From 8c050fb080c6e1981dc8e5a97a2313cd24e9b4b4 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Tue, 13 May 2014 15:35:42 +0200 Subject: tmpfs: use a seperate lock to protect all_nodes Previously, tmpfs used diskfs_node_refcnt_lock to serialize access to the all_nodes and some other related global state related to memory consumption. Use a separate lock to protect all_nodes, and atomic operations to access the state related to memory consumption. Adjust the reference counting accordingly. Every node in the all_nodes carries a light reference. When we are asked to give up that light reference, we reacquire our lock momentarily to check whether someone else reacquired a reference through the all_nodes. * tmpfs/tmpfs.h (num_files, tmpfs_space_used): Use atomic operations for these variables. (adjust_used): Use atomic operations. (get_used): New convenience function to atomically retrieve tmpfs_space_used. * tmpfs/node.c (all_nodes_lock): New lock. (diskfs_alloc_node): Use a separate lock to protect all_nodes. Adjust the reference counting accordingly. (diskfs_free_node): Likewise. (diskfs_cached_lookup):Likewise. (diskfs_node_iterate): Likewise. (diskfs_node_norefs): Do not remove the node from all_nodes. This actually looks like a mistake, I do not know why they did that here as well as in diskfs_free_node. (diskfs_try_dropping_softrefs): Check whether someone reacquired a reference, and if so hold on to our light reference. (diskfs_grow): Use atomic operations. * tmpfs/tmpfs.c (diskfs_set_statfs): Likewise. --- tmpfs/tmpfs.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'tmpfs/tmpfs.c') diff --git a/tmpfs/tmpfs.c b/tmpfs/tmpfs.c index 1b5b3746..fd1c9aaf 100644 --- a/tmpfs/tmpfs.c +++ b/tmpfs/tmpfs.c @@ -67,10 +67,8 @@ diskfs_set_statfs (struct statfs *st) st->f_bsize = vm_page_size; st->f_blocks = tmpfs_page_limit; - pthread_spin_lock (&diskfs_node_refcnt_lock); - st->f_files = num_files; - pages = round_page (tmpfs_space_used) / vm_page_size; - pthread_spin_unlock (&diskfs_node_refcnt_lock); + st->f_files = __atomic_load_n (&num_files, __ATOMIC_RELAXED); + pages = round_page (get_used ()) / vm_page_size; st->f_bfree = pages < tmpfs_page_limit ? tmpfs_page_limit - pages : 0; st->f_bavail = st->f_bfree; -- cgit v1.2.3