diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-06-01 18:48:18 +0200 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-06-01 18:48:18 +0200 |
commit | 6b1ec7b9eb28291b3d858fb573f4af926c8a70d7 (patch) | |
tree | 006e1651d56eb73e7e55c910413819b87e4b238d /debian/patches/0007-libdiskfs-lock-less-reference-counting-of-nodes.patch | |
parent | 69797274af1fac1e1b97451d1ca603e3db2ca30b (diff) |
drop old patch series
Diffstat (limited to 'debian/patches/0007-libdiskfs-lock-less-reference-counting-of-nodes.patch')
-rw-r--r-- | debian/patches/0007-libdiskfs-lock-less-reference-counting-of-nodes.patch | 579 |
1 files changed, 0 insertions, 579 deletions
diff --git a/debian/patches/0007-libdiskfs-lock-less-reference-counting-of-nodes.patch b/debian/patches/0007-libdiskfs-lock-less-reference-counting-of-nodes.patch deleted file mode 100644 index 81e8a9d5..00000000 --- a/debian/patches/0007-libdiskfs-lock-less-reference-counting-of-nodes.patch +++ /dev/null @@ -1,579 +0,0 @@ -From 53a8c7ae70afc269a53ad0c474cba7abfaa5388c Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Wed, 14 May 2014 11:19:35 +0200 -Subject: [PATCH 7/9] libdiskfs: lock-less reference counting of nodes - -* libdiskfs/diskfs.h (struct node): Use refcounts_t for reference counting. -(diskfs_node_refcnt_lock): Remove. -(diskfs_node_norefs,diskfs_drop_node): Change comments accordingly. -* libdiskfs/init-init.c: Likewise. -* libdiskfs/node-drop.c: Likewise. -* libdiskfs/node-make.c: Likewise. -* libdiskfs/node-nput.c: Likewise. -* libdiskfs/node-nputl.c: Likewise. -* libdiskfs/node-nref.c: Likewise. -* libdiskfs/node-nrefl.c: Likewise. -* libdiskfs/node-nrele.c: Likewise. -* libdiskfs/node-nrelel.c: Likewise. -* ext2fs/inode.c: Likewise. -* fatfs/inode.c: Likewise. -* isofs/inode.c: Likewise. -* tmpfs/node.c: Likewise. -* doc/hurd.texi: Likewise. ---- - doc/hurd.texi | 11 ++-------- - ext2fs/inode.c | 14 +++++-------- - fatfs/inode.c | 26 ++++++++---------------- - isofs/inode.c | 12 ++++------- - libdiskfs/diskfs.h | 15 ++++++-------- - libdiskfs/init-init.c | 2 -- - libdiskfs/node-drop.c | 9 +++------ - libdiskfs/node-make.c | 3 +-- - libdiskfs/node-nput.c | 54 +++++++++++++++++++------------------------------ - libdiskfs/node-nputl.c | 12 ++++------- - libdiskfs/node-nref.c | 10 ++++----- - libdiskfs/node-nrefl.c | 6 +++--- - libdiskfs/node-nrele.c | 48 +++++++++++++++++++++---------------------- - libdiskfs/node-nrelel.c | 9 +++------ - tmpfs/node.c | 14 +++++-------- - 15 files changed, 92 insertions(+), 153 deletions(-) - -diff --git a/doc/hurd.texi b/doc/hurd.texi -index 07ddfb4..6cafdb9 100644 ---- a/doc/hurd.texi -+++ b/doc/hurd.texi -@@ -3780,10 +3780,6 @@ new thread and (eventually) get rid of the old one; the old thread won't - do any more syncs, regardless. - @end deftypefun - --@deftypevar spin_lock_t diskfs_node_refcnt_lock --Pager reference count lock. --@end deftypevar -- - @deftypevar int diskfs_readonly - Set to zero if the filesystem is currently writable. - @end deftypevar -@@ -3818,9 +3814,7 @@ Every file or directory is a diskfs @dfn{node}. The following functions - help your diskfs callbacks manage nodes and their references: - - @deftypefun void diskfs_drop_node (@w{struct node *@var{np}}) --Node @var{np} now has no more references; clean all state. The --@var{diskfs_node_refcnt_lock} must be held, and will be released upon --return. @var{np} must be locked. -+Node @var{np} now has no more references; clean all state. - @end deftypefun - - @deftypefun void diskfs_node_update (@w{struct node *@var{np}}, @w{int @var{wait}}) -@@ -4236,14 +4230,13 @@ without real users. - @deftypefun void diskfs_try_dropping_softrefs (@w{struct node *@var{np}}) - Node @var{np} has some light references, but has just lost its last hard - references. Take steps so that if any light references can be freed, --they are. Both @var{diskfs_node_refcnt_lock} and @var{np} are locked. -+they are. @var{np} is locked. - This function will be called after @code{diskfs_lost_hardrefs}. - @end deftypefun - - @deftypefun void diskfs_node_norefs (@w{struct node *@var{np}}) - Node @var{np} has no more references; free local state, including - @code{*@var{np}} if it shouldn't be retained. --@var{diskfs_node_refcnt_lock} is held. - @end deftypefun - - @deftypefun error_t diskfs_set_hypermetadata (@w{int @var{wait}}, @w{int @var{clean}}) -diff --git a/ext2fs/inode.c b/ext2fs/inode.c -index 835c8c7..fa940d9 100644 ---- a/ext2fs/inode.c -+++ b/ext2fs/inode.c -@@ -188,14 +188,10 @@ diskfs_try_dropping_softrefs (struct node *np) - { - /* Check if someone reacquired a reference through the - nodehash. */ -- unsigned int references; -- pthread_spin_lock (&diskfs_node_refcnt_lock); -- references = np->references; -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -- -- /* An additional reference is acquired by libdiskfs across calls -- to diskfs_try_dropping_softrefs. */ -- if (references > 1) -+ struct references result; -+ refcounts_references (&np->refcounts, &result); -+ -+ if (result.hard > 0) - { - /* A reference was reacquired through a hash table lookup. - It's fine, we didn't touch anything yet. */ -@@ -616,7 +612,7 @@ diskfs_node_iterate (error_t (*fun)(struct node *)) - /* We acquire a hard reference for node, but without using - diskfs_nref. We do this so that diskfs_new_hardrefs will not - get called. */ -- node->references++; -+ refcounts_ref (&node->refcounts, NULL); - } - - pthread_rwlock_unlock (&nodecache_lock); -diff --git a/fatfs/inode.c b/fatfs/inode.c -index 352c7a3..ccb895f 100644 ---- a/fatfs/inode.c -+++ b/fatfs/inode.c -@@ -235,14 +235,8 @@ diskfs_node_norefs (struct node *np) - if (np->dn->translator) - free (np->dn->translator); - -- /* It is safe to unlock diskfs_node_refcnt_lock here for a while because -- all references to the node have been deleted. */ - if (np->dn->dirnode) -- { -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -- diskfs_nrele (np->dn->dirnode); -- pthread_spin_lock (&diskfs_node_refcnt_lock); -- } -+ diskfs_nrele (np->dn->dirnode); - - assert (!np->dn->pager); - -@@ -260,14 +254,10 @@ diskfs_try_dropping_softrefs (struct node *np) - { - /* Check if someone reacquired a reference through the - nodehash. */ -- unsigned int references; -- pthread_spin_lock (&diskfs_node_refcnt_lock); -- references = np->references; -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -- -- /* An additional reference is acquired by libdiskfs across calls -- to diskfs_try_dropping_softrefs. */ -- if (references > 1) -+ struct references result; -+ refcounts_references (&np->refcounts, &result); -+ -+ if (result.hard > 0) - { - /* A reference was reacquired through a hash table lookup. - It's fine, we didn't touch anything yet. */ -@@ -372,7 +362,7 @@ read_node (struct node *np, vm_address_t buf) - /* Files in fatfs depend on the directory that hold the file. */ - np->dn->dirnode = dp; - if (dp) -- dp->references++; -+ refcounts_ref (&dp->refcounts, NULL); - - pthread_rwlock_rdlock (&np->dn->dirent_lock); - -@@ -607,7 +597,7 @@ diskfs_node_iterate (error_t (*fun)(struct node *)) - /* We acquire a hard reference for node, but without using - diskfs_nref. We do this so that diskfs_new_hardrefs will not - get called. */ -- node->references++; -+ refcounts_ref (&node->refcounts, NULL); - } - - pthread_rwlock_unlock (&nodecache_lock); -@@ -818,7 +808,7 @@ diskfs_alloc_node (struct node *dir, mode_t mode, struct node **node) - - /* FIXME: We know that readnode couldn't put this in. */ - np->dn->dirnode = dir; -- dir->references++; -+ refcounts_ref (&dir->refcounts, NULL); - - *node = np; - return 0; -diff --git a/isofs/inode.c b/isofs/inode.c -index 010d724..ba8bc5b 100644 ---- a/isofs/inode.c -+++ b/isofs/inode.c -@@ -533,14 +533,10 @@ diskfs_try_dropping_softrefs (struct node *np) - - /* Check if someone reacquired a reference through the - node_cache. */ -- unsigned int references; -- pthread_spin_lock (&diskfs_node_refcnt_lock); -- references = np->references; -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -- -- /* An additional reference is acquired by libdiskfs across calls -- to diskfs_try_dropping_softrefs. */ -- if (references > 1) -+ struct references result; -+ refcounts_references (&np->refcounts, &result); -+ -+ if (result.hard > 0) - { - /* A reference was reacquired through a hash table lookup. - It's fine, we didn't touch anything yet. */ -diff --git a/libdiskfs/diskfs.h b/libdiskfs/diskfs.h -index 2c68aa3..38234a3 100644 ---- a/libdiskfs/diskfs.h -+++ b/libdiskfs/diskfs.h -@@ -96,8 +96,7 @@ struct node - - pthread_mutex_t lock; - -- int references; /* hard references */ -- int light_references; /* light references */ -+ refcounts_t refcounts; - - mach_port_t sockaddr; /* address for S_IFSOCK shortcut */ - -@@ -198,8 +197,6 @@ extern volatile struct mapped_time_value *diskfs_mtime; - be done by format independent code. */ - extern int diskfs_synchronous; - --extern pthread_spinlock_t diskfs_node_refcnt_lock; -- - extern int pager_port_type; - - /* Whether the filesystem is currently writable or not. */ -@@ -448,14 +445,15 @@ error_t diskfs_alloc_node (struct node *dp, mode_t mode, struct node **np); - void diskfs_free_node (struct node *np, mode_t mode); - - /* Node NP has no more references; free local state, including *NP -- if it isn't to be retained. diskfs_node_refcnt_lock is held. */ -+ if it isn't to be retained. */ - void diskfs_node_norefs (struct node *np); - - /* The user must define this function. Node NP has some light - references, but has just lost its last hard references. Take steps - so that if any light references can be freed, they are. NP is locked - as is the pager refcount lock. This function will be called after -- diskfs_lost_hardrefs. */ -+ diskfs_lost_hardrefs. An additional light reference is acquired by -+ libdiskfs across calls to this function. */ - void diskfs_try_dropping_softrefs (struct node *np); - - /* The user must define this funcction. Node NP has some light -@@ -611,9 +609,8 @@ void diskfs_spawn_first_thread (ports_demuxer_type demuxer); - diskfs_init_completed once it has a valid proc and auth port. */ - void diskfs_start_bootstrap (); - --/* Node NP now has no more references; clean all state. The -- _diskfs_node_refcnt_lock must be held, and will be released -- upon return. NP must be locked. */ -+/* Node NP now has no more references; clean all state. NP must be -+ locked. */ - void diskfs_drop_node (struct node *np); - - /* Set on disk fields from NP->dn_stat; update ctime, atime, and mtime -diff --git a/libdiskfs/init-init.c b/libdiskfs/init-init.c -index 7a7f248..6c94faa 100644 ---- a/libdiskfs/init-init.c -+++ b/libdiskfs/init-init.c -@@ -41,8 +41,6 @@ int _diskfs_noatime; - - struct hurd_port _diskfs_exec_portcell; - --pthread_spinlock_t diskfs_node_refcnt_lock = PTHREAD_SPINLOCK_INITIALIZER; -- - pthread_spinlock_t _diskfs_control_lock = PTHREAD_SPINLOCK_INITIALIZER; - int _diskfs_ncontrol_ports; - -diff --git a/libdiskfs/node-drop.c b/libdiskfs/node-drop.c -index 83eb590..fab3cfa 100644 ---- a/libdiskfs/node-drop.c -+++ b/libdiskfs/node-drop.c -@@ -31,9 +31,8 @@ free_modreqs (struct modreq *mr) - } - - --/* Node NP now has no more references; clean all state. The -- diskfs_node_refcnt_lock must be held, and will be released -- upon return. NP must be locked. */ -+/* Node NP now has no more references; clean all state. NP must be -+ locked. */ - void - diskfs_drop_node (struct node *np) - { -@@ -60,8 +59,7 @@ diskfs_drop_node (struct node *np) - and an nput. The next time through, this routine - will notice that the size is zero, and not have to - do anything. */ -- np->references++; -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ refcounts_ref (&np->refcounts, NULL); - diskfs_truncate (np, 0); - - /* Force allocsize to zero; if truncate consistently fails this -@@ -94,5 +92,4 @@ diskfs_drop_node (struct node *np) - assert (!np->sockaddr); - - diskfs_node_norefs (np); -- pthread_spin_unlock (&diskfs_node_refcnt_lock); - } -diff --git a/libdiskfs/node-make.c b/libdiskfs/node-make.c -index ff0cc0d..c7ca3b0 100644 ---- a/libdiskfs/node-make.c -+++ b/libdiskfs/node-make.c -@@ -29,8 +29,7 @@ init_node (struct node *np, struct disknode *dn) - np->dn_stat_dirty = 0; - - pthread_mutex_init (&np->lock, NULL); -- np->references = 1; -- np->light_references = 0; -+ refcounts_init (&np->refcounts, 1, 0); - np->owner = 0; - np->sockaddr = MACH_PORT_NULL; - -diff --git a/libdiskfs/node-nput.c b/libdiskfs/node-nput.c -index 5043ad1..2935ae2 100644 ---- a/libdiskfs/node-nput.c -+++ b/libdiskfs/node-nput.c -@@ -26,56 +26,44 @@ - void - diskfs_nput (struct node *np) - { -- int tried_drop_softrefs = 0; -+ struct references result; - -- loop: -- pthread_spin_lock (&diskfs_node_refcnt_lock); -- assert (np->references); -- np->references--; -- if (np->references + np->light_references == 0) -- diskfs_drop_node (np); -- else if (np->references == 0 && !tried_drop_softrefs) -- { -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ /* While we call the diskfs_try_dropping_softrefs, we need to hold -+ one reference. We use a weak reference for this purpose, which -+ we acquire by demoting our hard reference to a weak one. */ -+ refcounts_demote (&np->refcounts, &result); - -+ if (result.hard == 0) -+ { - /* This is our cue that something akin to "last process closes file" - in the POSIX.1 sense happened, so make sure any pending node time - updates now happen in a timely fashion. */ - diskfs_set_node_times (np); -- - diskfs_lost_hardrefs (np); - if (!np->dn_stat.st_nlink) - { -- /* There are no links. If there are soft references that -- can be dropped, we can't let them postpone deallocation. -- So attempt to drop them. But that's a user-supplied -- routine, which might result in further recursive calls to -- the ref-counting system. So we have to reacquire our -- reference around the call to forestall disaster. */ -- pthread_spin_lock (&diskfs_node_refcnt_lock); -- np->references++; -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -- - if (np->sockaddr != MACH_PORT_NULL) - { - mach_port_deallocate (mach_task_self (), np->sockaddr); - np->sockaddr = MACH_PORT_NULL; - } - -+ /* There are no links. If there are soft references that -+ can be dropped, we can't let them postpone deallocation. -+ So attempt to drop them. But that's a user-supplied -+ routine, which might result in further recursive calls to -+ the ref-counting system. This is not a problem, as we -+ hold a weak reference ourselves. */ - diskfs_try_dropping_softrefs (np); -- -- /* But there's no value in looping forever in this -- routine; only try to drop soft refs once. */ -- tried_drop_softrefs = 1; -- -- /* Now we can drop the reference back... */ -- goto loop; - } - pthread_mutex_unlock (&np->lock); - } -- else -- { -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -- pthread_mutex_unlock (&np->lock); -- } -+ -+ /* Finally get rid of our reference. */ -+ refcounts_deref_weak (&np->refcounts, &result); -+ -+ if (result.hard == 0 && result.weak == 0) -+ diskfs_drop_node (np); -+ -+ pthread_mutex_unlock (&np->lock); - } -diff --git a/libdiskfs/node-nputl.c b/libdiskfs/node-nputl.c -index 1959665..8dac16e 100644 ---- a/libdiskfs/node-nputl.c -+++ b/libdiskfs/node-nputl.c -@@ -25,14 +25,10 @@ - void - diskfs_nput_light (struct node *np) - { -- pthread_spin_lock (&diskfs_node_refcnt_lock); -- assert (np->light_references); -- np->light_references--; -- if (np->references + np->light_references == 0) -+ struct references result; -+ refcounts_deref_weak (&np->refcounts, &result); -+ if (result.hard == 0 && result.weak == 0) - diskfs_drop_node (np); - else -- { -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -- pthread_mutex_unlock (&np->lock); -- } -+ pthread_mutex_unlock (&np->lock); - } -diff --git a/libdiskfs/node-nref.c b/libdiskfs/node-nref.c -index 13cea05..89ffa4f 100644 ---- a/libdiskfs/node-nref.c -+++ b/libdiskfs/node-nref.c -@@ -26,12 +26,10 @@ - void - diskfs_nref (struct node *np) - { -- int new_hardref; -- pthread_spin_lock (&diskfs_node_refcnt_lock); -- np->references++; -- new_hardref = (np->references == 1); -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -- if (new_hardref) -+ struct references result; -+ refcounts_ref (&np->refcounts, &result); -+ assert (result.hard > 1 || result.weak > 0); -+ if (result.hard == 1) - { - pthread_mutex_lock (&np->lock); - diskfs_new_hardrefs (np); -diff --git a/libdiskfs/node-nrefl.c b/libdiskfs/node-nrefl.c -index 9692247..b7af409 100644 ---- a/libdiskfs/node-nrefl.c -+++ b/libdiskfs/node-nrefl.c -@@ -24,7 +24,7 @@ - void - diskfs_nref_light (struct node *np) - { -- pthread_spin_lock (&diskfs_node_refcnt_lock); -- np->light_references++; -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ struct references result; -+ refcounts_ref_weak (&np->refcounts, &result); -+ assert (result.hard > 0 || result.weak > 1); - } -diff --git a/libdiskfs/node-nrele.c b/libdiskfs/node-nrele.c -index cc68089..d962846 100644 ---- a/libdiskfs/node-nrele.c -+++ b/libdiskfs/node-nrele.c -@@ -28,38 +28,36 @@ - void - diskfs_nrele (struct node *np) - { -- int tried_drop_softrefs = 0; -+ struct references result; - -- loop: -- pthread_spin_lock (&diskfs_node_refcnt_lock); -- assert (np->references); -- np->references--; -- if (np->references + np->light_references == 0) -- { -- pthread_mutex_lock (&np->lock); -- diskfs_drop_node (np); -- } -- else if (np->references == 0) -+ /* While we call the diskfs_try_dropping_softrefs, we need to hold -+ one reference. We use a weak reference for this purpose, which -+ we acquire by demoting our hard reference to a weak one. */ -+ refcounts_demote (&np->refcounts, &result); -+ -+ if (result.hard == 0) - { - pthread_mutex_lock (&np->lock); -- pthread_spin_unlock (&diskfs_node_refcnt_lock); - diskfs_lost_hardrefs (np); -- if (!np->dn_stat.st_nlink && !tried_drop_softrefs) -+ if (!np->dn_stat.st_nlink) - { -- /* Same issue here as in nput; see that for explanation */ -- pthread_spin_lock (&diskfs_node_refcnt_lock); -- np->references++; -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -- -+ /* There are no links. If there are soft references that -+ can be dropped, we can't let them postpone deallocation. -+ So attempt to drop them. But that's a user-supplied -+ routine, which might result in further recursive calls to -+ the ref-counting system. This is not a problem, as we -+ hold a weak reference ourselves. */ - diskfs_try_dropping_softrefs (np); -- tried_drop_softrefs = 1; -- -- /* Now we can drop the reference back... */ -- pthread_mutex_unlock (&np->lock); -- goto loop; - } - pthread_mutex_unlock (&np->lock); - } -- else -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ -+ /* Finally get rid of our reference. */ -+ refcounts_deref_weak (&np->refcounts, &result); -+ -+ if (result.hard == 0 && result.weak == 0) -+ { -+ pthread_mutex_lock (&np->lock); -+ diskfs_drop_node (np); -+ } - } -diff --git a/libdiskfs/node-nrelel.c b/libdiskfs/node-nrelel.c -index ee53b22..dc4f920 100644 ---- a/libdiskfs/node-nrelel.c -+++ b/libdiskfs/node-nrelel.c -@@ -26,14 +26,11 @@ - void - diskfs_nrele_light (struct node *np) - { -- pthread_spin_lock (&diskfs_node_refcnt_lock); -- assert (np->light_references); -- np->light_references--; -- if (np->references + np->light_references == 0) -+ struct references result; -+ refcounts_deref_weak (&np->refcounts, &result); -+ if (result.hard == 0 && result.weak == 0) - { - pthread_mutex_lock (&np->lock); - diskfs_drop_node (np); - } -- else -- pthread_spin_unlock (&diskfs_node_refcnt_lock); - } -diff --git a/tmpfs/node.c b/tmpfs/node.c -index 03d4742..f4d84c5 100644 ---- a/tmpfs/node.c -+++ b/tmpfs/node.c -@@ -255,7 +255,7 @@ diskfs_node_iterate (error_t (*fun) (struct node *)) - /* We acquire a hard reference for node, but without using - diskfs_nref. We do this so that diskfs_new_hardrefs will not - get called. */ -- node->references++; -+ refcounts_ref (&node->refcounts, NULL); - } - - pthread_rwlock_unlock (&all_nodes_lock); -@@ -288,14 +288,10 @@ diskfs_try_dropping_softrefs (struct node *np) - if (np->cache_id != 0) - { - /* Check if someone reacquired a reference. */ -- unsigned int references; -- pthread_spin_lock (&diskfs_node_refcnt_lock); -- references = np->references; -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -- -- /* An additional reference is acquired by libdiskfs across calls -- to diskfs_try_dropping_softrefs. */ -- if (references > 1) -+ struct references result; -+ refcounts_references (&np->refcounts, &result); -+ -+ if (result.hard > 0) - { - /* A reference was reacquired. It's fine, we didn't touch - anything yet. */ --- -2.0.0.rc2 - |