diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-05-13 20:08:19 +0200 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-05-13 20:08:19 +0200 |
commit | 2ab6147feee29f561592bcf07bb54c6688eccef7 (patch) | |
tree | 45ccb3ad2877d05d7f28bef9a31827dd2b11d78f | |
parent | 81392d0937737682bbbbfa462a185dcb2dc8dd62 (diff) |
drop huge patch series
13 files changed, 0 insertions, 2113 deletions
diff --git a/debian/patches/0001-libports-use-a-single-hash-table.patch b/debian/patches/0001-libports-use-a-single-hash-table.patch deleted file mode 100644 index ec0af1b9..00000000 --- a/debian/patches/0001-libports-use-a-single-hash-table.patch +++ /dev/null @@ -1,619 +0,0 @@ -From ad5c0b3331c73bae11c0c9da422ffd190a0dccfc Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Sat, 3 May 2014 03:53:41 +0200 -Subject: [PATCH 01/11] libports: use a single hash table - -Previously, libports used a hash table per port bucket. This makes -looking up a port difficult if one does not know the port bucket, as -one has to iterate over all buckets and do a hash table lookup each. - -Having to iterate over the buckets makes it necessary to keep a list -of all buckets, which has to be updated and protected by a lock as -well. - -Also, the current code in _ports_bucket_class_iterate iterates over -the hash table associated with the bucket given. When -ports_class_iterate calls this common function, it obtains a reference -to the bucket from one of the ports in the given class. This will not -work if a class contains ports in different port buckets. This -limitation is not documented as far as I can see. Again, having to -maintain this list has its cost and requires serialization. - -Use a single hash table instead. Furthermore, serialize access to it -using a separate lock. Remove the linked lists of all buckets and all -ports in a class. - -* libports/bucket-iterate.c (ports_bucket_iterate): Acquire -_ports_htable_lock. Also, generalize ports_bucket_iterate to treat -the bucket argument the same way as the class argument. -* libports/class-iterate.c (ports_class_iterate): Just call the -generalized _ports_bucket_class_iterate with NULL as class. -* libports/ports.h (struct port_info): Remove the port class links. -(struct port_bucket): Remove the hash table, and the all buckets link. -(_ports_all_buckets): Remove declaration. -(_ports_htable): New global hash table. -(_ports_htable_lock): Protected by this lock. -* libports/claim-right.c: Adjust accordingly. -* libports/complete-deallocate.c: Likewise. -* libports/create-bucket.c: Likewise. -* libports/create-class.c: Likewise. -* libports/create-internal.c: Likewise. -* libports/destroy-right.c: Likewise. -* libports/import-port.c: Likewise. -* libports/lookup-port.c: Likewise. -* libports/reallocate-from-external.c: Likewise. -* libports/reallocate-port.c: Likewise. -* libports/transfer-right.c: Likewise. -* libports/inhibit-all-rpcs.c: Iterate over the hash table. -* libports/inhibit-bucket-rpcs.c: Likewise, but filter using bucket. -* libports/inhibit-class-rpcs.c: Likewise, but filter using class. -* libports/init.c (_ports_htable): Initialize. -(_ports_htable_lock): Likewise. ---- - libports/bucket-iterate.c | 21 +++++++++++++++------ - libports/claim-right.c | 6 ++++-- - libports/class-iterate.c | 10 +--------- - libports/complete-deallocate.c | 8 +++----- - libports/create-bucket.c | 7 ------- - libports/create-class.c | 1 - - libports/create-internal.c | 9 +++------ - libports/destroy-right.c | 6 +++--- - libports/import-port.c | 9 +++------ - libports/inhibit-all-rpcs.c | 27 +++++++++++++-------------- - libports/inhibit-bucket-rpcs.c | 7 +++++-- - libports/inhibit-class-rpcs.c | 27 ++++++++++++++++++--------- - libports/init.c | 7 ++++++- - libports/lookup-port.c | 21 ++++++++------------- - libports/ports.h | 11 ++++++----- - libports/reallocate-from-external.c | 16 ++++++++++------ - libports/reallocate-port.c | 10 +++++++--- - libports/transfer-right.c | 20 +++++++++++++------- - 18 files changed, 118 insertions(+), 105 deletions(-) - -diff --git a/libports/bucket-iterate.c b/libports/bucket-iterate.c -index babc204..d5f590e 100644 ---- a/libports/bucket-iterate.c -+++ b/libports/bucket-iterate.c -@@ -36,35 +36,44 @@ _ports_bucket_class_iterate (struct port_bucket *bucket, - error_t err; - - pthread_mutex_lock (&_ports_lock); -+ pthread_mutex_lock (&_ports_htable_lock); - -- if (bucket->htable.nr_items == 0) -+ if (_ports_htable.nr_items == 0) - { -- pthread_mutex_unlock (&_ports_lock); -+ pthread_mutex_unlock (&_ports_htable_lock); - return 0; - } - -- nr_items = bucket->htable.nr_items; -+ nr_items = _ports_htable.nr_items; - p = malloc (nr_items * sizeof *p); - if (p == NULL) - { -- pthread_mutex_unlock (&_ports_lock); -+ pthread_mutex_unlock (&_ports_htable_lock); - return ENOMEM; - } - - n = 0; -- HURD_IHASH_ITERATE (&bucket->htable, arg) -+ HURD_IHASH_ITERATE (&_ports_htable, arg) - { - struct port_info *const pi = arg; - -- if (class == 0 || pi->class == class) -+ if ((bucket == NULL || pi->bucket == bucket) -+ && (class == NULL || pi->class == class)) - { - pi->refcnt++; - p[n] = pi; - n++; - } - } -+ pthread_mutex_unlock (&_ports_htable_lock); - pthread_mutex_unlock (&_ports_lock); - -+ if (n == 0) -+ { -+ free (p); -+ return 0; -+ } -+ - if (n != nr_items) - { - /* We allocated too much. Release unused memory. */ -diff --git a/libports/claim-right.c b/libports/claim-right.c -index 4851ea3..f453a82 100644 ---- a/libports/claim-right.c -+++ b/libports/claim-right.c -@@ -34,10 +34,12 @@ ports_claim_right (void *portstruct) - if (ret == MACH_PORT_NULL) - return ret; - -- pthread_mutex_lock (&_ports_lock); -- hurd_ihash_locp_remove (&pi->bucket->htable, pi->hentry); -+ pthread_mutex_lock (&_ports_htable_lock); -+ hurd_ihash_locp_remove (&_ports_htable, pi->hentry); -+ pthread_mutex_unlock (&_ports_htable_lock); - err = mach_port_move_member (mach_task_self (), ret, MACH_PORT_NULL); - assert_perror (err); -+ pthread_mutex_lock (&_ports_lock); - pi->port_right = MACH_PORT_NULL; - if (pi->flags & PORT_HAS_SENDRIGHTS) - { -diff --git a/libports/class-iterate.c b/libports/class-iterate.c -index 1f8878a..5cfcfc8 100644 ---- a/libports/class-iterate.c -+++ b/libports/class-iterate.c -@@ -23,13 +23,5 @@ error_t - ports_class_iterate (struct port_class *class, - error_t (*fun)(void *)) - { -- pthread_mutex_lock (&_ports_lock); -- if (class->ports != 0) -- { -- struct port_bucket *bucket = class->ports->bucket; -- pthread_mutex_unlock (&_ports_lock); -- return _ports_bucket_class_iterate (bucket, class, fun); -- } -- pthread_mutex_unlock (&_ports_lock); -- return 0; -+ return _ports_bucket_class_iterate (NULL, class, fun); - } -diff --git a/libports/complete-deallocate.c b/libports/complete-deallocate.c -index 8ce095b..1371d92 100644 ---- a/libports/complete-deallocate.c -+++ b/libports/complete-deallocate.c -@@ -29,16 +29,14 @@ _ports_complete_deallocate (struct port_info *pi) - - if (pi->port_right) - { -- hurd_ihash_locp_remove (&pi->bucket->htable, pi->hentry); -+ pthread_mutex_lock (&_ports_htable_lock); -+ hurd_ihash_locp_remove (&_ports_htable, pi->hentry); -+ pthread_mutex_unlock (&_ports_htable_lock); - mach_port_mod_refs (mach_task_self (), pi->port_right, - MACH_PORT_RIGHT_RECEIVE, -1); - pi->port_right = MACH_PORT_NULL; - } - -- *pi->prevp = pi->next; -- if (pi->next) -- pi->next->prevp = pi->prevp; -- - pi->bucket->count--; - pi->class->count--; - -diff --git a/libports/create-bucket.c b/libports/create-bucket.c -index 52d50c3..9f6821d 100644 ---- a/libports/create-bucket.c -+++ b/libports/create-bucket.c -@@ -46,13 +46,6 @@ ports_create_bucket () - return NULL; - } - -- hurd_ihash_init (&ret->htable, offsetof (struct port_info, hentry)); - ret->rpcs = ret->flags = ret->count = 0; -- -- pthread_mutex_lock (&_ports_lock); -- ret->next = _ports_all_buckets; -- _ports_all_buckets = ret; -- pthread_mutex_unlock (&_ports_lock); -- - return ret; - } -diff --git a/libports/create-class.c b/libports/create-class.c -index 12c8add..782f52b 100644 ---- a/libports/create-class.c -+++ b/libports/create-class.c -@@ -39,7 +39,6 @@ ports_create_class (void (*clean_routine)(void *), - cl->dropweak_routine = dropweak_routine; - cl->flags = 0; - cl->rpcs = 0; -- cl->ports = NULL; - cl->count = 0; - cl->uninhibitable_rpcs = ports_default_uninhibitable_rpcs; - -diff --git a/libports/create-internal.c b/libports/create-internal.c -index 8551297..e773dd6 100644 ---- a/libports/create-internal.c -+++ b/libports/create-internal.c -@@ -81,15 +81,12 @@ _ports_create_port_internal (struct port_class *class, - goto loop; - } - -- err = hurd_ihash_add (&bucket->htable, port, pi); -+ pthread_mutex_lock (&_ports_htable_lock); -+ err = hurd_ihash_add (&_ports_htable, port, pi); -+ pthread_mutex_unlock (&_ports_htable_lock); - if (err) - goto lose; - -- pi->next = class->ports; -- pi->prevp = &class->ports; -- if (class->ports) -- class->ports->prevp = &pi->next; -- class->ports = pi; - bucket->count++; - class->count++; - pthread_mutex_unlock (&_ports_lock); -diff --git a/libports/destroy-right.c b/libports/destroy-right.c -index 65e19c7..6ba7302 100644 ---- a/libports/destroy-right.c -+++ b/libports/destroy-right.c -@@ -30,12 +30,12 @@ ports_destroy_right (void *portstruct) - - if (pi->port_right != MACH_PORT_NULL) - { -- pthread_mutex_lock (&_ports_lock); -- hurd_ihash_locp_remove (&pi->bucket->htable, pi->hentry); -+ pthread_mutex_lock (&_ports_htable_lock); -+ hurd_ihash_locp_remove (&_ports_htable, pi->hentry); -+ pthread_mutex_unlock (&_ports_htable_lock); - err = mach_port_mod_refs (mach_task_self (), pi->port_right, - MACH_PORT_RIGHT_RECEIVE, -1); - assert_perror (err); -- pthread_mutex_unlock (&_ports_lock); - - pi->port_right = MACH_PORT_NULL; - -diff --git a/libports/import-port.c b/libports/import-port.c -index 226f47e..d0b2ea4 100644 ---- a/libports/import-port.c -+++ b/libports/import-port.c -@@ -75,15 +75,12 @@ ports_import_port (struct port_class *class, struct port_bucket *bucket, - goto loop; - } - -- err = hurd_ihash_add (&bucket->htable, port, pi); -+ pthread_mutex_lock (&_ports_htable_lock); -+ err = hurd_ihash_add (&_ports_htable, port, pi); -+ pthread_mutex_unlock (&_ports_htable_lock); - if (err) - goto lose; - -- pi->next = class->ports; -- pi->prevp = &class->ports; -- if (class->ports) -- class->ports->prevp = &pi->next; -- class->ports = pi; - bucket->count++; - class->count++; - pthread_mutex_unlock (&_ports_lock); -diff --git a/libports/inhibit-all-rpcs.c b/libports/inhibit-all-rpcs.c -index d4a54ba..83c291f 100644 ---- a/libports/inhibit-all-rpcs.c -+++ b/libports/inhibit-all-rpcs.c -@@ -36,24 +36,23 @@ ports_inhibit_all_rpcs () - struct port_bucket *bucket; - int this_one = 0; - -- for (bucket = _ports_all_buckets; bucket; bucket = bucket->next) -+ pthread_mutex_lock (&_ports_htable_lock); -+ HURD_IHASH_ITERATE (&_ports_htable, portstruct) - { -- HURD_IHASH_ITERATE (&bucket->htable, portstruct) -+ struct rpc_info *rpc; -+ struct port_info *pi = portstruct; -+ -+ for (rpc = pi->current_rpcs; rpc; rpc = rpc->next) - { -- struct rpc_info *rpc; -- struct port_info *pi = portstruct; -- -- for (rpc = pi->current_rpcs; rpc; rpc = rpc->next) -- { -- /* Avoid cancelling the calling thread if it's currently -- handling a RPC. */ -- if (rpc->thread == hurd_thread_self ()) -- this_one = 1; -- else -- hurd_thread_cancel (rpc->thread); -- } -+ /* Avoid cancelling the calling thread if it's currently -+ handling a RPC. */ -+ if (rpc->thread == hurd_thread_self ()) -+ this_one = 1; -+ else -+ hurd_thread_cancel (rpc->thread); - } - } -+ pthread_mutex_unlock (&_ports_htable_lock); - - while (_ports_total_rpcs > this_one) - { -diff --git a/libports/inhibit-bucket-rpcs.c b/libports/inhibit-bucket-rpcs.c -index 965aa03..ed3e29d 100644 ---- a/libports/inhibit-bucket-rpcs.c -+++ b/libports/inhibit-bucket-rpcs.c -@@ -35,10 +35,13 @@ ports_inhibit_bucket_rpcs (struct port_bucket *bucket) - { - int this_one = 0; - -- HURD_IHASH_ITERATE (&bucket->htable, portstruct) -+ pthread_mutex_lock (&_ports_htable_lock); -+ HURD_IHASH_ITERATE (&_ports_htable, portstruct) - { - struct rpc_info *rpc; - struct port_info *pi = portstruct; -+ if (pi->bucket != bucket) -+ continue; - - for (rpc = pi->current_rpcs; rpc; rpc = rpc->next) - { -@@ -49,7 +52,7 @@ ports_inhibit_bucket_rpcs (struct port_bucket *bucket) - hurd_thread_cancel (rpc->thread); - } - } -- -+ pthread_mutex_unlock (&_ports_htable_lock); - - while (bucket->rpcs > this_one) - { -diff --git a/libports/inhibit-class-rpcs.c b/libports/inhibit-class-rpcs.c -index 7ee8653..1580bdb 100644 ---- a/libports/inhibit-class-rpcs.c -+++ b/libports/inhibit-class-rpcs.c -@@ -36,15 +36,24 @@ ports_inhibit_class_rpcs (struct port_class *class) - struct rpc_info *rpc; - int this_one = 0; - -- for (pi = class->ports; pi; pi = pi->next) -- for (rpc = pi->current_rpcs; rpc; rpc = rpc->next) -- { -- /* Avoid cancelling the calling thread. */ -- if (rpc->thread == hurd_thread_self ()) -- this_one = 1; -- else -- hurd_thread_cancel (rpc->thread); -- } -+ pthread_mutex_lock (&_ports_htable_lock); -+ HURD_IHASH_ITERATE (&_ports_htable, portstruct) -+ { -+ struct rpc_info *rpc; -+ struct port_info *pi = portstruct; -+ if (pi->class != class) -+ continue; -+ -+ for (rpc = pi->current_rpcs; rpc; rpc = rpc->next) -+ { -+ /* Avoid cancelling the calling thread. */ -+ if (rpc->thread == hurd_thread_self ()) -+ this_one = 1; -+ else -+ hurd_thread_cancel (rpc->thread); -+ } -+ } -+ pthread_mutex_unlock (&_ports_htable_lock); - - while (class->rpcs > this_one) - { -diff --git a/libports/init.c b/libports/init.c -index 3ef5388..8fbc7e8 100644 ---- a/libports/init.c -+++ b/libports/init.c -@@ -19,9 +19,14 @@ - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - #include "ports.h" -+#include <stddef.h> - - pthread_mutex_t _ports_lock = PTHREAD_MUTEX_INITIALIZER; - pthread_cond_t _ports_block = PTHREAD_COND_INITIALIZER; --struct port_bucket *_ports_all_buckets; -+ -+struct hurd_ihash _ports_htable = -+ HURD_IHASH_INITIALIZER (offsetof (struct port_info, hentry)); -+pthread_mutex_t _ports_htable_lock = PTHREAD_MUTEX_INITIALIZER; -+ - int _ports_total_rpcs; - int _ports_flags; -diff --git a/libports/lookup-port.c b/libports/lookup-port.c -index f79f6f0..fbb13ef 100644 ---- a/libports/lookup-port.c -+++ b/libports/lookup-port.c -@@ -26,26 +26,21 @@ ports_lookup_port (struct port_bucket *bucket, - mach_port_t port, - struct port_class *class) - { -- struct port_info *pi = 0; -- -+ struct port_info *pi; -+ - pthread_mutex_lock (&_ports_lock); -+ pthread_mutex_lock (&_ports_htable_lock); - -- if (bucket) -- pi = hurd_ihash_find (&bucket->htable, port); -- else -- for (bucket = _ports_all_buckets; bucket; bucket = bucket->next) -- { -- pi = hurd_ihash_find (&bucket->htable, port); -- if (pi) -- break; -- } -- -- if (pi && class && pi->class != class) -+ pi = hurd_ihash_find (&_ports_htable, port); -+ if (pi -+ && ((class && pi->class != class) -+ || (bucket && pi->bucket != bucket))) - pi = 0; - - if (pi) - pi->refcnt++; - -+ pthread_mutex_unlock (&_ports_htable_lock); - pthread_mutex_unlock (&_ports_lock); - - return pi; -diff --git a/libports/ports.h b/libports/ports.h -index 7f13124..9c5f14d 100644 ---- a/libports/ports.h -+++ b/libports/ports.h -@@ -48,7 +48,6 @@ struct port_info - struct rpc_info *current_rpcs; - struct port_bucket *bucket; - hurd_ihash_locp_t hentry; -- struct port_info *next, **prevp; /* links on port_class list */ - }; - typedef struct port_info *port_info_t; - -@@ -61,11 +60,9 @@ typedef struct port_info *port_info_t; - struct port_bucket - { - mach_port_t portset; -- struct hurd_ihash htable; - int rpcs; - int flags; - int count; -- struct port_bucket *next; - }; - /* FLAGS above are the following: */ - #define PORT_BUCKET_INHIBITED PORTS_INHIBITED -@@ -78,7 +75,6 @@ struct port_class - { - int flags; - int rpcs; -- struct port_info *ports; - int count; - void (*clean_routine) (void *); - void (*dropweak_routine) (void *); -@@ -402,7 +398,12 @@ extern kern_return_t - /* Private data */ - extern pthread_mutex_t _ports_lock; - extern pthread_cond_t _ports_block; --extern struct port_bucket *_ports_all_buckets; -+ -+/* A hash table mapping port names to port_info objects. */ -+extern struct hurd_ihash _ports_htable; -+/* Access to the hash table is protected by this lock. */ -+extern pthread_mutex_t _ports_htable_lock; -+ - extern int _ports_total_rpcs; - extern int _ports_flags; - #define _PORTS_INHIBITED PORTS_INHIBITED -diff --git a/libports/reallocate-from-external.c b/libports/reallocate-from-external.c -index 8cccb2a..bbcf9ba 100644 ---- a/libports/reallocate-from-external.c -+++ b/libports/reallocate-from-external.c -@@ -43,8 +43,10 @@ ports_reallocate_from_external (void *portstruct, mach_port_t receive) - MACH_PORT_RIGHT_RECEIVE, -1); - assert_perror (err); - -- hurd_ihash_locp_remove (&pi->bucket->htable, pi->hentry); -- -+ pthread_mutex_lock (&_ports_htable_lock); -+ hurd_ihash_locp_remove (&_ports_htable, pi->hentry); -+ pthread_mutex_unlock (&_ports_htable_lock); -+ - if ((pi->flags & PORT_HAS_SENDRIGHTS) && !stat.mps_srights) - { - dropref = 1; -@@ -59,11 +61,13 @@ ports_reallocate_from_external (void *portstruct, mach_port_t receive) - pi->port_right = receive; - pi->cancel_threshold = 0; - pi->mscount = stat.mps_mscount; -- -- err = hurd_ihash_add (&pi->bucket->htable, receive, pi); -- assert_perror (err); -+ -+ pthread_mutex_lock (&_ports_htable_lock); -+ err = hurd_ihash_add (&_ports_htable, receive, pi); -+ pthread_mutex_unlock (&_ports_htable_lock); - pthread_mutex_unlock (&_ports_lock); -- -+ assert_perror (err); -+ - mach_port_move_member (mach_task_self (), receive, pi->bucket->portset); - - if (stat.mps_srights) -diff --git a/libports/reallocate-port.c b/libports/reallocate-port.c -index d2adaeb..99c4041 100644 ---- a/libports/reallocate-port.c -+++ b/libports/reallocate-port.c -@@ -36,7 +36,9 @@ ports_reallocate_port (void *portstruct) - MACH_PORT_RIGHT_RECEIVE, -1); - assert_perror (err); - -- hurd_ihash_locp_remove (&pi->bucket->htable, pi->hentry); -+ pthread_mutex_lock (&_ports_htable_lock); -+ hurd_ihash_locp_remove (&_ports_htable, pi->hentry); -+ pthread_mutex_unlock (&_ports_htable_lock); - - err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, - &pi->port_right); -@@ -48,9 +50,11 @@ ports_reallocate_port (void *portstruct) - } - pi->cancel_threshold = 0; - pi->mscount = 0; -- err = hurd_ihash_add (&pi->bucket->htable, pi->port_right, pi); -- assert_perror (err); -+ pthread_mutex_lock (&_ports_htable_lock); -+ err = hurd_ihash_add (&_ports_htable, pi->port_right, pi); -+ pthread_mutex_unlock (&_ports_htable_lock); - pthread_mutex_unlock (&_ports_lock); -+ assert_perror (err); - - err = mach_port_move_member (mach_task_self (), pi->port_right, - pi->bucket->portset); -diff --git a/libports/transfer-right.c b/libports/transfer-right.c -index 72488a9..5a7653d 100644 ---- a/libports/transfer-right.c -+++ b/libports/transfer-right.c -@@ -41,7 +41,9 @@ ports_transfer_right (void *tostruct, - port = frompi->port_right; - if (port != MACH_PORT_NULL) - { -- hurd_ihash_locp_remove (&frompi->bucket->htable, frompi->hentry); -+ pthread_mutex_lock (&_ports_htable_lock); -+ hurd_ihash_locp_remove (&_ports_htable, frompi->hentry); -+ pthread_mutex_unlock (&_ports_htable_lock); - frompi->port_right = MACH_PORT_NULL; - if (frompi->flags & PORT_HAS_SENDRIGHTS) - { -@@ -54,7 +56,9 @@ ports_transfer_right (void *tostruct, - /* Destroy the existing right in TOPI. */ - if (topi->port_right != MACH_PORT_NULL) - { -- hurd_ihash_locp_remove (&topi->bucket->htable, topi->hentry); -+ pthread_mutex_lock (&_ports_htable_lock); -+ hurd_ihash_locp_remove (&_ports_htable, topi->hentry); -+ pthread_mutex_unlock (&_ports_htable_lock); - err = mach_port_mod_refs (mach_task_self (), topi->port_right, - MACH_PORT_RIGHT_RECEIVE, -1); - assert_perror (err); -@@ -74,10 +78,14 @@ ports_transfer_right (void *tostruct, - topi->port_right = port; - topi->cancel_threshold = frompi->cancel_threshold; - topi->mscount = frompi->mscount; -- -+ -+ pthread_mutex_unlock (&_ports_lock); -+ - if (port) - { -- err = hurd_ihash_add (&topi->bucket->htable, port, topi); -+ pthread_mutex_lock (&_ports_htable_lock); -+ err = hurd_ihash_add (&_ports_htable, port, topi); -+ pthread_mutex_unlock (&_ports_htable_lock); - assert_perror (err); - if (topi->bucket != frompi->bucket) - { -@@ -86,9 +94,7 @@ ports_transfer_right (void *tostruct, - assert_perror (err); - } - } -- -- pthread_mutex_unlock (&_ports_lock); -- -+ - /* Take care of any lowered reference counts. */ - if (dereffrompi) - ports_port_deref (frompi); --- -2.0.0.rc0 - diff --git a/debian/patches/0002-include-add-lock-less-reference-counting-primitives.patch b/debian/patches/0002-include-add-lock-less-reference-counting-primitives.patch deleted file mode 100644 index 6718ab31..00000000 --- a/debian/patches/0002-include-add-lock-less-reference-counting-primitives.patch +++ /dev/null @@ -1,194 +0,0 @@ -From 55ddd1b28a57492c5df4afcdf167910fb7bbc3a1 Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Tue, 6 May 2014 19:52:04 +0200 -Subject: [PATCH 02/11] include: add lock-less reference counting primitives - -* include/refcount.h: New file. ---- - include/refcount.h | 174 +++++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 174 insertions(+) - create mode 100644 include/refcount.h - -diff --git a/include/refcount.h b/include/refcount.h -new file mode 100644 -index 0000000..0a9ed8e ---- /dev/null -+++ b/include/refcount.h -@@ -0,0 +1,174 @@ -+/* Lock-less reference counting primitives -+ -+ Copyright (C) 2014 Free Software Foundation, Inc. -+ -+ Written by Justus Winter <4winter@informatik.uni-hamburg.de> -+ -+ This file is part of the GNU Hurd. -+ -+ The GNU Hurd is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public License as -+ published by the Free Software Foundation; either version 2, or (at -+ your option) any later version. -+ -+ The GNU Hurd is distributed in the hope that it will be useful, but -+ WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */ -+ -+#ifndef _HURD_REFCOUNT_H_ -+#define _HURD_REFCOUNT_H_ -+ -+#include <stdint.h> -+ -+/* Simple reference counting. */ -+ -+/* An opaque type. You must not access these values directly. */ -+typedef unsigned int refcount_t; -+ -+/* Initialize REF with REFERENCES. */ -+static inline void -+refcount_init (refcount_t *ref, unsigned int references) -+{ -+ *ref = references; -+} -+ -+/* Increment REF. Return the result of the operation. This function -+ uses atomic operations. It is not required to serialize calls to -+ this function. */ -+static inline unsigned int -+refcount_ref (refcount_t *ref) -+{ -+ return __atomic_add_fetch (ref, 1, __ATOMIC_RELAXED); -+} -+ -+/* Decrement REF. Return the result of the operation. This function -+ uses atomic operations. It is not required to serialize calls to -+ this function. */ -+static inline unsigned int -+refcount_deref (refcount_t *ref) -+{ -+ return __atomic_sub_fetch (ref, 1, __ATOMIC_RELAXED); -+} -+ -+/* Return REF. This function uses atomic operations. It is not -+ required to serialize calls to this function. */ -+static inline unsigned int -+refcount_references (refcount_t *ref) -+{ -+ return __atomic_load_n (ref, __ATOMIC_RELAXED); -+} -+ -+/* Reference counting with weak references. */ -+ -+/* An opaque type. You must not access these values directly. */ -+typedef uint64_t refcounts_t; -+ -+/* Instead, the functions manipulating refcounts_t values write the -+ results into this kind of objects. */ -+struct references { -+ uint32_t hard; -+ uint32_t weak; -+}; -+ -+union _references { -+ struct references refs; -+ refcounts_t rc; -+}; -+ -+/* Initialize REF with HARD and WEAK references. */ -+static inline void -+refcounts_init (refcounts_t *ref, uint32_t hard, uint32_t weak) -+{ -+ ((union _references *) ref)->refs = -+ (struct references) { .hard = hard, .weak = weak }; -+} -+ -+/* Increment the hard reference count of REF. If RESULT is not NULL, -+ the result of the operation is written there. This function uses -+ atomic operations. It is not required to serialize calls to this -+ function. */ -+static inline void -+refcounts_ref (refcounts_t *ref, struct references *result) -+{ -+ const union _references op = { .refs = { .hard = 1 } }; -+ refcounts_t r = __atomic_add_fetch (ref, op.rc, __ATOMIC_RELAXED); -+ if (result) -+ ((union _references *) result)->rc = r; -+} -+ -+/* Decrement the hard reference count of REF. If RESULT is not NULL, -+ the result of the operation is written there. This function uses -+ atomic operations. It is not required to serialize calls to this -+ function. */ -+static inline void -+refcounts_deref (refcounts_t *ref, struct references *result) -+{ -+ const union _references op = { .refs = { .hard = 1 } }; -+ refcounts_t r = __atomic_sub_fetch (ref, op.rc, __ATOMIC_RELAXED); -+ if (result) -+ ((union _references *) result)->rc = r; -+} -+ -+/* Increment the weak reference count of REF. If RESULT is not NULL, -+ the result of the operation is written there. This function uses -+ atomic operations. It is not required to serialize calls to this -+ function. */ -+static inline void -+refcounts_ref_weak (refcounts_t *ref, struct references *result) -+{ -+ const union _references op = { .refs = { .weak = 1 } }; -+ refcounts_t r = __atomic_add_fetch (ref, op.rc, __ATOMIC_RELAXED); -+ if (result) -+ ((union _references *) result)->rc = r; -+} -+ -+/* Decrement the weak reference count of REF. If RESULT is not NULL, -+ the result of the operation is written there. This function uses -+ atomic operations. It is not required to serialize calls to this -+ function. */ -+static inline void -+refcounts_deref_weak (refcounts_t *ref, struct references *result) -+{ -+ const union _references op = { .refs = { .weak = 1 } }; -+ refcounts_t r = __atomic_sub_fetch (ref, op.rc, __ATOMIC_RELAXED); -+ if (result) -+ ((union _references *) result)->rc = r; -+} -+ -+/* Store the current reference counts of REF in RESULT. This function -+ uses atomic operations. It is not required to serialize calls to -+ this function. */ -+static inline void -+refcounts_references (refcounts_t *ref, struct references *result) -+{ -+ ((union _references *) result)->rc = -+ __atomic_load_n (ref, __ATOMIC_RELAXED); -+} -+ -+/* Return the hard reference count of REF. This function uses atomic -+ operations. It is not required to serialize calls to this -+ function. */ -+static inline uint32_t -+refcounts_hard_references (refcounts_t *ref) -+{ -+ struct references result; -+ refcounts_references (ref, &result); -+ return result.hard; -+} -+ -+/* Return the weak reference count of REF. This function uses atomic -+ operations. It is not required to serialize calls to this -+ function. */ -+static inline uint32_t -+refcounts_weak_references (refcounts_t *ref) -+{ -+ struct references result; -+ refcounts_references (ref, &result); -+ return result.weak; -+} -+ -+#endif /* _HURD_REFCOUNT_H_ */ --- -2.0.0.rc0 - diff --git a/debian/patches/0003-libports-lock-less-reference-counting-for-port_info-.patch b/debian/patches/0003-libports-lock-less-reference-counting-for-port_info-.patch deleted file mode 100644 index e03a61f7..00000000 --- a/debian/patches/0003-libports-lock-less-reference-counting-for-port_info-.patch +++ /dev/null @@ -1,345 +0,0 @@ -From c860c73eb7baf5d3846da968969d3b2ef7a541ac Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Sat, 3 May 2014 01:02:35 +0200 -Subject: [PATCH 03/11] libports: lock-less reference counting for port_info - objects - -* libports/ports.h (struct port_info): Use the new type. -* libports/lookup-port.c: No need to lock _ports_lock anymore. -* libports/bucket-iterate.c: Likewise. -* libports/complete-deallocate.c: Check if someone reacquired a -reference through a hash table lookup. -* libports/create-internal.c: Use the new reference counting primitives. -* libports/get-right.c: Likewise. -* libports/import-port.c: Likewise. -* libports/port-deref-weak.c: Likewise. -* libports/port-deref.c: Likewise. -* libports/port-ref-weak.c: Likewise. -* libports/port-ref.c: Likewise. -* libports/reallocate-from-external.c: Likewise. -* libports/transfer-right.c: Likewise. -* utils/rpctrace.c: Likewise. ---- - libports/bucket-iterate.c | 4 +--- - libports/complete-deallocate.c | 15 +++++++++++++++ - libports/create-internal.c | 3 +-- - libports/get-right.c | 2 +- - libports/import-port.c | 3 +-- - libports/lookup-port.c | 6 ++---- - libports/port-deref-weak.c | 10 +++------- - libports/port-deref.c | 34 ++++++++++++++++------------------ - libports/port-ref-weak.c | 8 +++----- - libports/port-ref.c | 8 +++----- - libports/ports.h | 4 ++-- - libports/reallocate-from-external.c | 2 +- - libports/transfer-right.c | 2 +- - utils/rpctrace.c | 10 ++++++++-- - 14 files changed, 58 insertions(+), 53 deletions(-) - -diff --git a/libports/bucket-iterate.c b/libports/bucket-iterate.c -index d5f590e..2a2b2b6 100644 ---- a/libports/bucket-iterate.c -+++ b/libports/bucket-iterate.c -@@ -35,7 +35,6 @@ _ports_bucket_class_iterate (struct port_bucket *bucket, - size_t i, n, nr_items; - error_t err; - -- pthread_mutex_lock (&_ports_lock); - pthread_mutex_lock (&_ports_htable_lock); - - if (_ports_htable.nr_items == 0) -@@ -60,13 +59,12 @@ _ports_bucket_class_iterate (struct port_bucket *bucket, - if ((bucket == NULL || pi->bucket == bucket) - && (class == NULL || pi->class == class)) - { -- pi->refcnt++; -+ refcounts_ref (&pi->refcounts, NULL); - p[n] = pi; - n++; - } - } - pthread_mutex_unlock (&_ports_htable_lock); -- pthread_mutex_unlock (&_ports_lock); - - if (n == 0) - { -diff --git a/libports/complete-deallocate.c b/libports/complete-deallocate.c -index 1371d92..6c9074a 100644 ---- a/libports/complete-deallocate.c -+++ b/libports/complete-deallocate.c -@@ -29,14 +29,29 @@ _ports_complete_deallocate (struct port_info *pi) - - if (pi->port_right) - { -+ struct references result; -+ - pthread_mutex_lock (&_ports_htable_lock); -+ -+ refcounts_references (&pi->refcounts, &result); -+ if (result.hard > 0 || result.weak > 0) -+ { -+ /* A reference was reacquired through a hash table lookup. -+ It's fine, we didn't touch anything yet. */ -+ pthread_mutex_unlock (&_ports_htable_lock); -+ return; -+ } -+ - hurd_ihash_locp_remove (&_ports_htable, pi->hentry); - pthread_mutex_unlock (&_ports_htable_lock); -+ - mach_port_mod_refs (mach_task_self (), pi->port_right, - MACH_PORT_RIGHT_RECEIVE, -1); - pi->port_right = MACH_PORT_NULL; - } - -+ pthread_mutex_lock (&_ports_lock); -+ - pi->bucket->count--; - pi->class->count--; - -diff --git a/libports/create-internal.c b/libports/create-internal.c -index e773dd6..9e3824d 100644 ---- a/libports/create-internal.c -+++ b/libports/create-internal.c -@@ -54,8 +54,7 @@ _ports_create_port_internal (struct port_class *class, - } - - pi->class = class; -- pi->refcnt = 1; -- pi->weakrefcnt = 0; -+ refcounts_init (&pi->refcounts, 1, 0); - pi->cancel_threshold = 0; - pi->mscount = 0; - pi->flags = 0; -diff --git a/libports/get-right.c b/libports/get-right.c -index 89050c6..8681f46 100644 ---- a/libports/get-right.c -+++ b/libports/get-right.c -@@ -41,7 +41,7 @@ ports_get_right (void *port) - if ((pi->flags & PORT_HAS_SENDRIGHTS) == 0) - { - pi->flags |= PORT_HAS_SENDRIGHTS; -- pi->refcnt++; -+ refcounts_ref (&pi->refcounts, NULL); - err = mach_port_request_notification (mach_task_self (), - pi->port_right, - MACH_NOTIFY_NO_SENDERS, -diff --git a/libports/import-port.c b/libports/import-port.c -index d0b2ea4..e250b0e 100644 ---- a/libports/import-port.c -+++ b/libports/import-port.c -@@ -48,8 +48,7 @@ ports_import_port (struct port_class *class, struct port_bucket *bucket, - return ENOMEM; - - pi->class = class; -- pi->refcnt = 1 + !!stat.mps_srights; -- pi->weakrefcnt = 0; -+ refcounts_init (&pi->refcounts, 1 + !!stat.mps_srights, 0); - pi->cancel_threshold = 0; - pi->mscount = stat.mps_mscount; - pi->flags = stat.mps_srights ? PORT_HAS_SENDRIGHTS : 0; -diff --git a/libports/lookup-port.c b/libports/lookup-port.c -index fbb13ef..1bf012f 100644 ---- a/libports/lookup-port.c -+++ b/libports/lookup-port.c -@@ -28,7 +28,6 @@ ports_lookup_port (struct port_bucket *bucket, - { - struct port_info *pi; - -- pthread_mutex_lock (&_ports_lock); - pthread_mutex_lock (&_ports_htable_lock); - - pi = hurd_ihash_find (&_ports_htable, port); -@@ -38,10 +37,9 @@ ports_lookup_port (struct port_bucket *bucket, - pi = 0; - - if (pi) -- pi->refcnt++; -+ ports_port_ref (pi); - - pthread_mutex_unlock (&_ports_htable_lock); -- pthread_mutex_unlock (&_ports_lock); -- -+ - return pi; - } -diff --git a/libports/port-deref-weak.c b/libports/port-deref-weak.c -index beb4842..8432660 100644 ---- a/libports/port-deref-weak.c -+++ b/libports/port-deref-weak.c -@@ -25,12 +25,8 @@ void - ports_port_deref_weak (void *portstruct) - { - struct port_info *pi = portstruct; -- -- pthread_mutex_lock (&_ports_lock); -- assert (pi->weakrefcnt); -- pi->weakrefcnt--; -- if (pi->refcnt == 0 && pi->weakrefcnt == 0) -+ struct references result; -+ refcounts_deref_weak (&pi->refcounts, &result); -+ if (result.hard == 0 && result.weak == 0) - _ports_complete_deallocate (pi); -- else -- pthread_mutex_unlock (&_ports_lock); - } -diff --git a/libports/port-deref.c b/libports/port-deref.c -index cf9b238..dd38f55 100644 ---- a/libports/port-deref.c -+++ b/libports/port-deref.c -@@ -25,26 +25,24 @@ void - ports_port_deref (void *portstruct) - { - struct port_info *pi = portstruct; -- int trieddroppingweakrefs = 0; -- -- retry: -- -- pthread_mutex_lock (&_ports_lock); -- -- if (pi->refcnt == 1 && pi->weakrefcnt -- && pi->class->dropweak_routine && !trieddroppingweakrefs) -+ struct references result; -+ -+ /* If we need to call the dropweak routine, we need to hold one -+ reference while doing so. We use a weak reference for this -+ purpose, which we acquire before we release our hard reference. -+ The order is important here to prevent a race. */ -+ if (pi->class->dropweak_routine) -+ refcounts_ref_weak (&pi->refcounts, NULL); -+ -+ refcounts_deref (&pi->refcounts, &result); -+ -+ if (pi->class->dropweak_routine) - { -- pthread_mutex_unlock (&_ports_lock); -- (*pi->class->dropweak_routine) (pi); -- trieddroppingweakrefs = 1; -- goto retry; -+ if (result.hard == 0 && result.weak > 1) -+ (*pi->class->dropweak_routine) (pi); -+ refcounts_deref_weak (&pi->refcounts, &result); - } -- -- assert (pi->refcnt); - -- pi->refcnt--; -- if (pi->refcnt == 0 && pi->weakrefcnt == 0) -+ if (result.hard == 0 && result.weak == 0) - _ports_complete_deallocate (pi); -- else -- pthread_mutex_unlock (&_ports_lock); - } -diff --git a/libports/port-ref-weak.c b/libports/port-ref-weak.c -index c7d3c69..e4b7fc8 100644 ---- a/libports/port-ref-weak.c -+++ b/libports/port-ref-weak.c -@@ -25,9 +25,7 @@ void - ports_port_ref_weak (void *portstruct) - { - struct port_info *pi = portstruct; -- -- pthread_mutex_lock (&_ports_lock); -- assert (pi->refcnt || pi->weakrefcnt); -- pi->weakrefcnt++; -- pthread_mutex_unlock (&_ports_lock); -+ struct references result; -+ refcounts_ref_weak (&pi->refcounts, &result); -+ assert (result.hard > 0 || result.weak > 1); - } -diff --git a/libports/port-ref.c b/libports/port-ref.c -index 92b7118..761c50f 100644 ---- a/libports/port-ref.c -+++ b/libports/port-ref.c -@@ -25,9 +25,7 @@ void - ports_port_ref (void *portstruct) - { - struct port_info *pi = portstruct; -- -- pthread_mutex_lock (&_ports_lock); -- assert (pi->refcnt || pi->weakrefcnt); -- pi->refcnt++; -- pthread_mutex_unlock (&_ports_lock); -+ struct references result; -+ refcounts_ref (&pi->refcounts, &result); -+ assert (result.hard > 1 || result.weak > 0); - } -diff --git a/libports/ports.h b/libports/ports.h -index 9c5f14d..116e920 100644 ---- a/libports/ports.h -+++ b/libports/ports.h -@@ -27,6 +27,7 @@ - #include <hurd/ihash.h> - #include <mach/notify.h> - #include <pthread.h> -+#include <refcount.h> - - /* These are global values for common flags used in the various structures. - Not all of these are meaningful in all flag fields. */ -@@ -39,8 +40,7 @@ - struct port_info - { - struct port_class *class; -- int refcnt; -- int weakrefcnt; -+ refcounts_t refcounts; - mach_port_mscount_t mscount; - mach_msg_seqno_t cancel_threshold; - int flags; -diff --git a/libports/reallocate-from-external.c b/libports/reallocate-from-external.c -index bbcf9ba..5ee579d 100644 ---- a/libports/reallocate-from-external.c -+++ b/libports/reallocate-from-external.c -@@ -55,7 +55,7 @@ ports_reallocate_from_external (void *portstruct, mach_port_t receive) - else if (((pi->flags & PORT_HAS_SENDRIGHTS) == 0) && stat.mps_srights) - { - pi->flags |= PORT_HAS_SENDRIGHTS; -- pi->refcnt++; -+ refcounts_ref (&pi->refcounts, NULL); - } - - pi->port_right = receive; -diff --git a/libports/transfer-right.c b/libports/transfer-right.c -index 5a7653d..d3ff0f4 100644 ---- a/libports/transfer-right.c -+++ b/libports/transfer-right.c -@@ -70,7 +70,7 @@ ports_transfer_right (void *tostruct, - else if (((topi->flags & PORT_HAS_SENDRIGHTS) == 0) && hassendrights) - { - topi->flags |= PORT_HAS_SENDRIGHTS; -- topi->refcnt++; -+ refcounts_ref (&topi->refcounts, NULL); - } - } - -diff --git a/utils/rpctrace.c b/utils/rpctrace.c -index fc913e3..b11fea4 100644 ---- a/utils/rpctrace.c -+++ b/utils/rpctrace.c -@@ -431,7 +431,9 @@ destroy_receiver_info (struct receiver_info *info) - while (send_wrapper) - { - struct sender_info *next = send_wrapper->next; -- assert (TRACED_INFO (send_wrapper)->pi.refcnt == 1); -+ assert ( -+ refcounts_hard_references (&TRACED_INFO (send_wrapper)->pi.refcounts) -+ == 1); - /* Reset the receive_right of the send wrapper in advance to avoid - * destroy_receiver_info is called when the port info is destroyed. */ - send_wrapper->receive_right = NULL; -@@ -848,7 +850,11 @@ rewrite_right (mach_port_t *right, mach_msg_type_name_t *type, - hurd_ihash_locp_remove (&traced_names, receiver_info->locp); - - send_wrapper2 = get_send_wrapper (receiver_info, dest, &rr); -- assert (TRACED_INFO (send_wrapper2)->pi.refcnt == 1); -+ assert ( -+ refcounts_hard_references ( -+ &TRACED_INFO (send_wrapper2)->pi.refcounts) -+ == 1); -+ - name = TRACED_INFO (send_wrapper2)->name; - TRACED_INFO (send_wrapper2)->name = NULL; - /* send_wrapper2 isn't destroyed normally, so we need to unlink --- -2.0.0.rc0 - diff --git a/debian/patches/0004-libdiskfs-lock-less-reference-counting-for-peropen-o.patch b/debian/patches/0004-libdiskfs-lock-less-reference-counting-for-peropen-o.patch deleted file mode 100644 index d90ccf45..00000000 --- a/debian/patches/0004-libdiskfs-lock-less-reference-counting-for-peropen-o.patch +++ /dev/null @@ -1,143 +0,0 @@ -From e2a2dd50028147ab23a108f21432c47689c0ffd3 Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Tue, 6 May 2014 18:58:10 +0200 -Subject: [PATCH 04/11] libdiskfs: lock-less reference counting for peropen - objects - -* libdiskfs/diskfs.h (struct peropen): Use refcount_t for field refcnt. -* libdiskfs/peropen-make.c (diskfs_make_peropen): Initialize refcnt. -* libdiskfs/peropen-rele.c (diskfs_release_peropen): Adjust accordingly. -* libdiskfs/protid-make.c (diskfs_start_protid): Likewise. Also, the -node must no longer be locked, adjust comment accordingly. -(diskfs_create_protid): Likewise. ---- - libdiskfs/diskfs.h | 7 ++++--- - libdiskfs/peropen-make.c | 2 +- - libdiskfs/peropen-rele.c | 21 ++++++++++----------- - libdiskfs/protid-make.c | 8 ++++---- - 4 files changed, 19 insertions(+), 19 deletions(-) - -diff --git a/libdiskfs/diskfs.h b/libdiskfs/diskfs.h -index 8151ddc..ae1a150 100644 ---- a/libdiskfs/diskfs.h -+++ b/libdiskfs/diskfs.h -@@ -28,6 +28,7 @@ - #include <hurd/iohelp.h> - #include <idvec.h> - #include <features.h> -+#include <refcount.h> - - #ifdef DISKFS_DEFINE_EXTERN_INLINE - #define DISKFS_EXTERN_INLINE -@@ -57,7 +58,7 @@ struct peropen - { - int filepointer; - int lock_status; -- int refcnt; -+ refcount_t refcnt; - int openstat; - - struct node *np; -@@ -792,12 +793,12 @@ diskfs_create_node (struct node *dir, const char *name, mode_t mode, - struct dirstat *ds); - - /* Create and return a protid for an existing peropen PO in CRED, -- referring to user USER. The node PO->np must be locked. */ -+ referring to user USER. */ - error_t diskfs_create_protid (struct peropen *po, struct iouser *user, - struct protid **cred); - - /* Build and return in CRED a protid which has no user identification, for -- peropen PO. The node PO->np must be locked. */ -+ peropen PO. */ - error_t diskfs_start_protid (struct peropen *po, struct protid **cred); - - /* Finish building protid CRED started with diskfs_start_protid; -diff --git a/libdiskfs/peropen-make.c b/libdiskfs/peropen-make.c -index eba037f..6d5ca01 100644 ---- a/libdiskfs/peropen-make.c -+++ b/libdiskfs/peropen-make.c -@@ -31,7 +31,7 @@ diskfs_make_peropen (struct node *np, int flags, struct peropen *context, - - po->filepointer = 0; - po->lock_status = LOCK_UN; -- po->refcnt = 0; -+ refcount_init (&po->refcnt, 0); - po->openstat = flags; - po->np = np; - po->path = NULL; -diff --git a/libdiskfs/peropen-rele.c b/libdiskfs/peropen-rele.c -index d3f7492..877137b 100644 ---- a/libdiskfs/peropen-rele.c -+++ b/libdiskfs/peropen-rele.c -@@ -22,13 +22,8 @@ - void - diskfs_release_peropen (struct peropen *po) - { -- pthread_mutex_lock (&po->np->lock); -- -- if (--po->refcnt) -- { -- pthread_mutex_unlock (&po->np->lock); -- return; -- } -+ if (refcount_deref (&po->refcnt) > 0) -+ return; - - if (po->root_parent) - mach_port_deallocate (mach_task_self (), po->root_parent); -@@ -40,10 +35,14 @@ diskfs_release_peropen (struct peropen *po) - mach_port_deallocate (mach_task_self (), po->shadow_root_parent); - - if (po->lock_status != LOCK_UN) -- fshelp_acquire_lock (&po->np->userlock, &po->lock_status, -- &po->np->lock, LOCK_UN); -- -- diskfs_nput (po->np); -+ { -+ pthread_mutex_lock (&po->np->lock); -+ fshelp_acquire_lock (&po->np->userlock, &po->lock_status, -+ &po->np->lock, LOCK_UN); -+ diskfs_nput (po->np); -+ } -+ else -+ diskfs_nrele (po->np); - - free (po->path); - free (po); -diff --git a/libdiskfs/protid-make.c b/libdiskfs/protid-make.c -index b39b92a..22aaa2e 100644 ---- a/libdiskfs/protid-make.c -+++ b/libdiskfs/protid-make.c -@@ -20,7 +20,7 @@ - #include <assert.h> - - /* Build and return in CRED a protid which has no user identification, for -- peropen PO. The node PO->np must be locked. */ -+ peropen PO. */ - error_t - diskfs_start_protid (struct peropen *po, struct protid **cred) - { -@@ -29,7 +29,7 @@ diskfs_start_protid (struct peropen *po, struct protid **cred) - sizeof (struct protid), cred); - if (! err) - { -- po->refcnt++; -+ refcount_ref (&po->refcnt); - (*cred)->po = po; - (*cred)->shared_object = MACH_PORT_NULL; - (*cred)->mapped = 0; -@@ -55,8 +55,8 @@ diskfs_finish_protid (struct protid *cred, struct iouser *user) - assert_perror (err); - } - --/* Create and return a protid for an existing peropen PO in CRED for USER. -- The node PO->np must be locked. */ -+/* Create and return a protid for an existing peropen PO in CRED for -+ USER. */ - error_t - diskfs_create_protid (struct peropen *po, struct iouser *user, - struct protid **cred) --- -2.0.0.rc0 - diff --git a/debian/patches/0005-libtrivfs-lock-less-reference-counting-for-trivfs_pr.patch b/debian/patches/0005-libtrivfs-lock-less-reference-counting-for-trivfs_pr.patch deleted file mode 100644 index f269ee2b..00000000 --- a/debian/patches/0005-libtrivfs-lock-less-reference-counting-for-trivfs_pr.patch +++ /dev/null @@ -1,172 +0,0 @@ -From 06c8ddf64b015b150a41a6af8ba8a6cf9d20fef0 Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Tue, 6 May 2014 19:07:13 +0200 -Subject: [PATCH 05/11] libtrivfs: lock-less reference counting for - trivfs_peropen objects - -* libtrivfs/trivfs.h (struct trivfs_peropen): Use refcount_t for field -refcnt. -(struct trivfs_control): Remove unused field lock. -* libtrivfs/cntl-create.c (trivfs_create_control): Drop the mutex -initialization. -* libtrivfs/io-reauthenticate.c (trivfs_S_io_reauthenticate): Adjust -accordingly. -* libtrivfs/io-restrict-auth.c (trivfs_S_io_restrict_auth): Likewise. -* libtrivfs/open.c (trivfs_open): Initialize refcnt. -* libtrivfs/protid-clean.c (trivfs_clean_protid): Likewise. -* libtrivfs/protid-dup.c (trivfs_protid_dup): Likewise. ---- - libtrivfs/cntl-create.c | 1 - - libtrivfs/io-reauthenticate.c | 5 +---- - libtrivfs/io-restrict-auth.c | 4 +--- - libtrivfs/open.c | 2 +- - libtrivfs/protid-clean.c | 26 +++++++++++++++----------- - libtrivfs/protid-dup.c | 5 +---- - libtrivfs/trivfs.h | 4 ++-- - 7 files changed, 21 insertions(+), 26 deletions(-) - -diff --git a/libtrivfs/cntl-create.c b/libtrivfs/cntl-create.c -index 910daf3..eb9a834 100644 ---- a/libtrivfs/cntl-create.c -+++ b/libtrivfs/cntl-create.c -@@ -85,7 +85,6 @@ trivfs_create_control (mach_port_t underlying, - } - - (*control)->hook = 0; -- pthread_mutex_init (&(*control)->lock, NULL); - } - - out: -diff --git a/libtrivfs/io-reauthenticate.c b/libtrivfs/io-reauthenticate.c -index 7677697..df0ed2e 100644 ---- a/libtrivfs/io-reauthenticate.c -+++ b/libtrivfs/io-reauthenticate.c -@@ -62,11 +62,8 @@ trivfs_S_io_reauthenticate (struct trivfs_protid *cred, - newcred->isroot = 1; - - newcred->hook = cred->hook; -- -- pthread_mutex_lock (&cred->po->cntl->lock); - newcred->po = cred->po; -- newcred->po->refcnt++; -- pthread_mutex_unlock (&cred->po->cntl->lock); -+ refcount_ref (&newcred->po->refcnt); - - do - err = io_restrict_auth (newcred->po->cntl->underlying, &newcred->realnode, -diff --git a/libtrivfs/io-restrict-auth.c b/libtrivfs/io-restrict-auth.c -index 65b4fd6..39670fe 100644 ---- a/libtrivfs/io-restrict-auth.c -+++ b/libtrivfs/io-restrict-auth.c -@@ -110,10 +110,8 @@ trivfs_S_io_restrict_auth (struct trivfs_protid *cred, - } - - newcred->isroot = 0; -- pthread_mutex_lock (&cred->po->cntl->lock); - newcred->po = cred->po; -- newcred->po->refcnt++; -- pthread_mutex_unlock (&cred->po->cntl->lock); -+ refcount_ref (&newcred->po->refcnt); - if (cred->isroot && idvec_contains (user->uids, 0)) - newcred->isroot = 1; - newcred->user = user; -diff --git a/libtrivfs/open.c b/libtrivfs/open.c -index f64d2ff..97e70a1 100644 ---- a/libtrivfs/open.c -+++ b/libtrivfs/open.c -@@ -40,7 +40,7 @@ trivfs_open (struct trivfs_control *cntl, - - ports_port_ref (cntl); - -- po->refcnt = 1; -+ refcount_init (&po->refcnt, 1); - po->cntl = cntl; - po->openmodes = flags; - po->hook = 0; -diff --git a/libtrivfs/protid-clean.c b/libtrivfs/protid-clean.c -index f98da6a..cce736d 100644 ---- a/libtrivfs/protid-clean.c -+++ b/libtrivfs/protid-clean.c -@@ -31,19 +31,23 @@ trivfs_clean_protid (void *arg) - (*trivfs_protid_destroy_hook) (cred); - - /* If we hold the only reference to the peropen, try to get rid of it. */ -- pthread_mutex_lock (&cntl->lock); -- if (cred->po->refcnt == 1 && trivfs_peropen_destroy_hook) -+ if (refcount_deref (&cred->po->refcnt) == 0) - { -- pthread_mutex_unlock (&cntl->lock); -- (*trivfs_peropen_destroy_hook) (cred->po); -- pthread_mutex_lock (&cntl->lock); -+ if (trivfs_peropen_destroy_hook) -+ { -+ /* Reaquire a reference while we call the hook. */ -+ refcount_ref (&cred->po->refcnt); -+ (*trivfs_peropen_destroy_hook) (cred->po); -+ if (refcount_deref (&cred->po->refcnt) == 0) -+ goto free_po; -+ } -+ else -+ { -+ free_po: -+ ports_port_deref (cntl); -+ free (cred->po); -+ } - } -- if (--cred->po->refcnt == 0) -- { -- ports_port_deref (cntl); -- free (cred->po); -- } -- pthread_mutex_unlock (&cntl->lock); - - iohelp_free_iouser (cred->user); - -diff --git a/libtrivfs/protid-dup.c b/libtrivfs/protid-dup.c -index 6169603..75f3ca8 100644 ---- a/libtrivfs/protid-dup.c -+++ b/libtrivfs/protid-dup.c -@@ -35,11 +35,8 @@ trivfs_protid_dup (struct trivfs_protid *cred, struct trivfs_protid **dup) - - if (! err) - { -- pthread_mutex_lock (&cred->po->cntl->lock); - new->po = cred->po; -- new->po->refcnt++; -- pthread_mutex_unlock (&cred->po->cntl->lock); -- -+ refcount_ref (&new->po->refcnt); - new->isroot = cred->isroot; - - err = iohelp_dup_iouser (&new->user, cred->user); -diff --git a/libtrivfs/trivfs.h b/libtrivfs/trivfs.h -index bb456ff..8902338 100644 ---- a/libtrivfs/trivfs.h -+++ b/libtrivfs/trivfs.h -@@ -24,6 +24,7 @@ - #include <mach/mach.h> - #include <hurd/ports.h> - #include <hurd/iohelp.h> -+#include <refcount.h> - - struct trivfs_protid - { -@@ -41,14 +42,13 @@ struct trivfs_peropen - { - void *hook; /* for user use */ - int openmodes; -- int refcnt; -+ refcount_t refcnt; - struct trivfs_control *cntl; - }; - - struct trivfs_control - { - struct port_info pi; -- pthread_mutex_t lock; - struct port_class *protid_class; - struct port_bucket *protid_bucket; - mach_port_t filesys_id; --- -2.0.0.rc0 - diff --git a/debian/patches/0006-libihash-use-an-integer-hash-function-on-the-keys.patch b/debian/patches/0006-libihash-use-an-integer-hash-function-on-the-keys.patch deleted file mode 100644 index 89aae003..00000000 --- a/debian/patches/0006-libihash-use-an-integer-hash-function-on-the-keys.patch +++ /dev/null @@ -1,66 +0,0 @@ -From cf90fe8f338d8a3538b7b88e8c64cd0cbf8fda77 Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Thu, 8 May 2014 15:45:00 +0200 -Subject: [PATCH 06/11] libihash: use an integer hash function on the keys - -Use an integer hash function to derive the index from the key. This -should reduce the number of collisions. - -* libihash/ihash.c (hash_int32): New function. -(find_index): Use hash_int32 on the key to derive the index. -(add_one): Likewise. ---- - libihash/ihash.c | 23 +++++++++++++++++++++-- - 1 file changed, 21 insertions(+), 2 deletions(-) - -diff --git a/libihash/ihash.c b/libihash/ihash.c -index d670fee..1de4c35 100644 ---- a/libihash/ihash.c -+++ b/libihash/ihash.c -@@ -81,6 +81,25 @@ static const unsigned int ihash_nsizes = (sizeof ihash_sizes - / sizeof ihash_sizes[0]); - - -+/* Integer hashing follows Thomas Wang's paper about his 32/64-bits -+ mix functions : -+ - http://www.concentric.net/~Ttwang/tech/inthash.htm */ -+static inline uint32_t -+hash_int32(uint32_t n, unsigned int bits) -+{ -+ uint32_t hash; -+ -+ hash = n; -+ hash = ~hash + (hash << 15); -+ hash ^= (hash >> 12); -+ hash += (hash << 2); -+ hash ^= (hash >> 4); -+ hash += (hash << 3) + (hash << 11); -+ hash ^= (hash >> 16); -+ -+ return hash >> (32 - bits); -+} -+ - /* Return 1 if the slot with the index IDX in the hash table HT is - empty, and 0 otherwise. */ - static inline int -@@ -111,7 +130,7 @@ find_index (hurd_ihash_t ht, hurd_ihash_key_t key) - unsigned int up_idx; - unsigned int down_idx; - -- idx = key % ht->size; -+ idx = hash_int32 (key, 32) % ht->size; - - if (ht->items[idx].value == _HURD_IHASH_EMPTY || ht->items[idx].key == key) - return idx; -@@ -264,7 +283,7 @@ add_one (hurd_ihash_t ht, hurd_ihash_key_t key, hurd_ihash_value_t value) - unsigned int idx; - unsigned int first_free; - -- idx = key % ht->size; -+ idx = hash_int32 (key, 32) % ht->size; - first_free = idx; - - if (ht->items[idx].value != _HURD_IHASH_EMPTY && ht->items[idx].key != key) --- -2.0.0.rc0 - diff --git a/debian/patches/0007-libihash-reduce-the-default-maximum-load-factor-to-7.patch b/debian/patches/0007-libihash-reduce-the-default-maximum-load-factor-to-7.patch deleted file mode 100644 index d4110817..00000000 --- a/debian/patches/0007-libihash-reduce-the-default-maximum-load-factor-to-7.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0f30bbc488fcf38528c447b15c1d53c49f2b6cfb Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Thu, 8 May 2014 16:43:11 +0200 -Subject: [PATCH 07/11] libihash: reduce the default maximum load factor to 75% - -* libihash/ihash.h (HURD_IHASH_MAX_LOAD_DEFAULT): Set to 75. ---- - libihash/ihash.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libihash/ihash.h b/libihash/ihash.h -index 3ca5ec3..6bdc925 100644 ---- a/libihash/ihash.h -+++ b/libihash/ihash.h -@@ -94,7 +94,7 @@ typedef struct hurd_ihash *hurd_ihash_t; - /* Construction and destruction of hash tables. */ - - /* The default value for the maximum load factor in percent. */ --#define HURD_IHASH_MAX_LOAD_DEFAULT 80 -+#define HURD_IHASH_MAX_LOAD_DEFAULT 75 - - /* The LOCP_OFFS to use if no location pointer is available. */ - #define HURD_IHASH_NO_LOCP INTPTR_MIN --- -2.0.0.rc0 - diff --git a/debian/patches/0008-libihash-use-linear-probing-and-fast-modulo-operatio.patch b/debian/patches/0008-libihash-use-linear-probing-and-fast-modulo-operatio.patch deleted file mode 100644 index 1c4a394c..00000000 --- a/debian/patches/0008-libihash-use-linear-probing-and-fast-modulo-operatio.patch +++ /dev/null @@ -1,229 +0,0 @@ -From b18240df917ef17a7877164e098092728c139bb6 Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Thu, 8 May 2014 18:33:57 +0200 -Subject: [PATCH 08/11] libihash: use linear probing and fast modulo operation - -libihash uses open addressing. Previously, quadratic probing in both -directions was used to resolve collisions. Quadratic probing might -result in a less efficient use of caches. - -Also, prime numbers of the form 4 * i + 3 were used as array sizes. -This was used in combination with the integer modulo operation for -hashing. It has been known for some time that libihash suffers from -collisions, so a integer hash function is now applied to the keys to -derive the index. - -Use linear probing instead. Also, use powers of two for the array -sizes, so a bit mask can be used for the modulo operation. - -* libihash/ihash.c (ihash_sizes, ihash_nsizes): Remove. -(find_index): Use linear probing and fast modulo operation. -(add_one): Likewise. -* libihash/ihash.h (HURD_IHASH_MIN_SIZE): New macro. ---- - libihash/ihash.c | 121 ++++++------------------------------------------------- - libihash/ihash.h | 4 ++ - 2 files changed, 17 insertions(+), 108 deletions(-) - -diff --git a/libihash/ihash.c b/libihash/ihash.c -index 1de4c35..e74a2c5 100644 ---- a/libihash/ihash.c -+++ b/libihash/ihash.c -@@ -31,55 +31,6 @@ - #include <assert.h> - - #include "ihash.h" -- -- --/* The prime numbers of the form 4 * i + 3 for some i, all greater -- than twice the previous one and smaller than 2^40 (for now). */ --static const uint64_t ihash_sizes[] = --{ -- 3, -- 7, -- 19, -- 43, -- 103, -- 211, -- 431, -- 863, -- 1747, -- 3499, -- 7019, -- 14051, -- 28111, -- 56239, -- 112507, -- 225023, -- 450067, -- 900139, -- 1800311, -- 3600659, -- 7201351, -- 14402743, -- 28805519, -- 57611039, -- 115222091, -- 230444239, -- 460888499, -- 921777067, -- 1843554151, -- UINT64_C (3687108307), -- UINT64_C (7374216631), -- UINT64_C (14748433279), -- UINT64_C (29496866579), -- UINT64_C (58993733159), -- UINT64_C (117987466379), -- UINT64_C (235974932759), -- UINT64_C (471949865531), -- UINT64_C (943899731087) --}; -- --static const unsigned int ihash_nsizes = (sizeof ihash_sizes -- / sizeof ihash_sizes[0]); -- - - /* Integer hashing follows Thomas Wang's paper about his 32/64-bits - mix functions : -@@ -126,40 +77,24 @@ static inline int - find_index (hurd_ihash_t ht, hurd_ihash_key_t key) - { - unsigned int idx; -- unsigned int i; - unsigned int up_idx; -- unsigned int down_idx; -+ unsigned int mask = ht->size - 1; - -- idx = hash_int32 (key, 32) % ht->size; -+ idx = hash_int32 (key, 32) & mask; - - if (ht->items[idx].value == _HURD_IHASH_EMPTY || ht->items[idx].key == key) - return idx; - -- /* Instead of calculating idx + 1, idx + 4, idx + 9, ..., idx + i^2, -- we add 1, 3, 5, 7, etc to the previous index. We do this in both -- directions separately. */ -- i = 1; - up_idx = idx; -- down_idx = idx; - - do - { -- up_idx = (up_idx + i) % ht->size; -+ up_idx = (up_idx + 1) & mask; - if (ht->items[up_idx].value == _HURD_IHASH_EMPTY - || ht->items[up_idx].key == key) - return up_idx; -- -- if (down_idx < i) -- down_idx += ht->size; -- down_idx = (down_idx - i) % ht->size; -- if (ht->items[down_idx].value == _HURD_IHASH_EMPTY -- || ht->items[down_idx].key == key) -- return down_idx; -- -- /* After (ht->size - 1) / 2 iterations, this will be 0. */ -- i = (i + 2) % ht->size; - } -- while (i); -+ while (up_idx != idx); - - /* If we end up here, the item could not be found. Return any - invalid index. */ -@@ -282,53 +217,26 @@ add_one (hurd_ihash_t ht, hurd_ihash_key_t key, hurd_ihash_value_t value) - { - unsigned int idx; - unsigned int first_free; -+ unsigned int mask = ht->size - 1; - -- idx = hash_int32 (key, 32) % ht->size; -+ idx = hash_int32 (key, 32) & mask; - first_free = idx; - - if (ht->items[idx].value != _HURD_IHASH_EMPTY && ht->items[idx].key != key) - { -- /* Instead of calculating idx + 1, idx + 4, idx + 9, ..., idx + -- i^2, we add 1, 3, 5, 7, ... 2 * i - 1 to the previous index. -- We do this in both directions separately. */ -- unsigned int i = 1; - unsigned int up_idx = idx; -- unsigned int down_idx = idx; - - do - { -- up_idx = (up_idx + i) % ht->size; -+ up_idx = (up_idx + 1) & mask; - if (ht->items[up_idx].value == _HURD_IHASH_EMPTY - || ht->items[up_idx].key == key) - { - idx = up_idx; - break; - } -- if (first_free == idx -- && ht->items[up_idx].value == _HURD_IHASH_DELETED) -- first_free = up_idx; -- -- if (down_idx < i) -- down_idx += ht->size; -- down_idx = (down_idx - i) % ht->size; -- if (down_idx < 0) -- down_idx += ht->size; -- else -- down_idx %= ht->size; -- if (ht->items[down_idx].value == _HURD_IHASH_EMPTY -- || ht->items[down_idx].key == key) -- { -- idx = down_idx; -- break; -- } -- if (first_free == idx -- && ht->items[down_idx].value == _HURD_IHASH_DELETED) -- first_free = down_idx; -- -- /* After (ht->size - 1) / 2 iterations, this will be 0. */ -- i = (i + 2) % ht->size; - } -- while (i); -+ while (up_idx != idx); - } - - /* Remove the old entry for this key if necessary. */ -@@ -377,15 +285,12 @@ hurd_ihash_add (hurd_ihash_t ht, hurd_ihash_key_t key, hurd_ihash_value_t item) - } - - /* The hash table is too small, and we have to increase it. */ -- for (i = 0; i < ihash_nsizes; i++) -- if (ihash_sizes[i] > old_ht.size) -- break; -- if (i == ihash_nsizes -- || ihash_sizes[i] > SIZE_MAX / sizeof (struct _hurd_ihash_item)) -- return ENOMEM; /* Surely will be true momentarily. */ -- - ht->nr_items = 0; -- ht->size = ihash_sizes[i]; -+ if (ht->size == 0) -+ ht->size = HURD_IHASH_MIN_SIZE; -+ else -+ ht->size <<= 1; -+ - /* calloc() will initialize all values to _HURD_IHASH_EMPTY implicitely. */ - ht->items = calloc (ht->size, sizeof (struct _hurd_ihash_item)); - -diff --git a/libihash/ihash.h b/libihash/ihash.h -index 6bdc925..057babc 100644 ---- a/libihash/ihash.h -+++ b/libihash/ihash.h -@@ -93,6 +93,10 @@ typedef struct hurd_ihash *hurd_ihash_t; - - /* Construction and destruction of hash tables. */ - -+/* The size of the initial allocation in number of items. This must -+ be a power of two. */ -+#define HURD_IHASH_MIN_SIZE 32 -+ - /* The default value for the maximum load factor in percent. */ - #define HURD_IHASH_MAX_LOAD_DEFAULT 75 - --- -2.0.0.rc0 - diff --git a/debian/patches/0009-ext2fs-improve-enable-disable-_caching.patch b/debian/patches/0009-ext2fs-improve-enable-disable-_caching.patch deleted file mode 100644 index f7752a36..00000000 --- a/debian/patches/0009-ext2fs-improve-enable-disable-_caching.patch +++ /dev/null @@ -1,38 +0,0 @@ -From afa09fc5d380d0a6fd5f6ddd37eb32c9f359de26 Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Fri, 9 May 2014 10:07:28 +0200 -Subject: [PATCH 09/11] ext2fs: improve {enable,disable}_caching - -* ext2fs/pager.c (enable_caching, disable_caching): Iterate over the -pager class instead of over both pager buckets. ---- - ext2fs/pager.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/ext2fs/pager.c b/ext2fs/pager.c -index 017efcc..6328f3b 100644 ---- a/ext2fs/pager.c -+++ b/ext2fs/pager.c -@@ -1409,8 +1409,7 @@ disable_caching () - - /* Loop through the pagers and turn off caching one by one, - synchronously. That should cause termination of each pager. */ -- ports_bucket_iterate (disk_pager_bucket, block_cache); -- ports_bucket_iterate (file_pager_bucket, block_cache); -+ ports_class_iterate (_pager_class, block_cache); - } - - static void -@@ -1438,8 +1437,7 @@ enable_caching () - return 0; - } - -- ports_bucket_iterate (disk_pager_bucket, enable_cache); -- ports_bucket_iterate (file_pager_bucket, enable_cache); -+ ports_class_iterate (_pager_class, enable_cache); - } - - /* Tell diskfs if there are pagers exported, and if none, then --- -2.0.0.rc0 - diff --git a/debian/patches/0010-fatfs-improve-enable-disable-_caching.patch b/debian/patches/0010-fatfs-improve-enable-disable-_caching.patch deleted file mode 100644 index e39bdfd8..00000000 --- a/debian/patches/0010-fatfs-improve-enable-disable-_caching.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 8071bad9edfaf6990a17fcdd68f88afa01456566 Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Fri, 9 May 2014 10:11:45 +0200 -Subject: [PATCH 10/11] fatfs: improve {enable,disable}_caching - -* fatfs/pager.c (enable_caching, disable_caching): Iterate over the -pager class instead of over both pager buckets. ---- - fatfs/pager.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/fatfs/pager.c b/fatfs/pager.c -index f855ecf..7aa5c5e 100644 ---- a/fatfs/pager.c -+++ b/fatfs/pager.c -@@ -23,6 +23,9 @@ - #include <hurd/store.h> - #include "fatfs.h" - -+/* XXX */ -+#include "../libpager/priv.h" -+ - /* A ports bucket to hold disk pager ports. */ - struct port_bucket *disk_pager_bucket; - -@@ -963,8 +966,7 @@ disable_caching () - - /* Loop through the pagers and turn off caching one by one, - synchronously. That should cause termination of each pager. */ -- ports_bucket_iterate (disk_pager_bucket, block_cache); -- ports_bucket_iterate (file_pager_bucket, block_cache); -+ ports_class_iterate (_pager_class, block_cache); - } - - static void -@@ -992,8 +994,7 @@ enable_caching () - return 0; - } - -- ports_bucket_iterate (disk_pager_bucket, enable_cache); -- ports_bucket_iterate (file_pager_bucket, enable_cache); -+ ports_class_iterate (_pager_class, enable_cache); - } - - /* Tell diskfs if there are pagers exported, and if none, then --- -2.0.0.rc0 - diff --git a/debian/patches/ext2fs-cache-superblock.patch b/debian/patches/ext2fs-cache-superblock.patch deleted file mode 100644 index 27bf494e..00000000 --- a/debian/patches/ext2fs-cache-superblock.patch +++ /dev/null @@ -1,73 +0,0 @@ -commit a3ccff628fcd9d9866bac415758be8d55d6cf13f -Author: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Thu Apr 24 17:44:14 2014 +0200 - - ext2fs: cache the superblock - - Previously, the superblock was mmaped and a pointer stored in sblock - by map_hypermetadata. This memory is backed by our disk pager. - - This is rather unfortunate, as this means that whenever we read a - value from that location, we might generate a request our disk pager. - This amplifies the so-called thread-storm problem. - - Rather than relying on a mmaped region of memory, just use the data - loaded by get_hypermetadata. - - * ext2fs/hyper.c (get_hypermetadata): Do not free sblock. - (mapped_sblock): New variable. - (map_hypermetadata): Map the superblock to mapped_sblock instead. - (diskfs_set_hypermetadata): Copy superblock into mapped_superblock. - -diff --git a/ext2fs/hyper.c b/ext2fs/hyper.c -index 5bcc2ab..5f288bf 100644 ---- a/ext2fs/hyper.c -+++ b/ext2fs/hyper.c -@@ -61,7 +61,9 @@ get_hypermetadata (void) - error_t err; - size_t read = 0; - -- assert (! sblock); -+ if (sblock != NULL) -+ munmap (sblock, SBLOCK_SIZE); -+ - err = store_read (store, SBLOCK_OFFS >> store->log2_block_size, - SBLOCK_SIZE, (void **)&sblock, &read); - if (err || read != SBLOCK_SIZE) -@@ -161,19 +163,19 @@ get_hypermetadata (void) - zeroblock = (vm_address_t) mmap (0, block_size, PROT_READ, MAP_ANON, 0, 0); - assert (zeroblock != (vm_address_t) MAP_FAILED); - } -- -- munmap (sblock, SBLOCK_SIZE); -- sblock = NULL; - } - -+static struct ext2_super_block *mapped_sblock; -+ - void - map_hypermetadata (void) - { -- sblock = (struct ext2_super_block *) boffs_ptr (SBLOCK_OFFS); -+ mapped_sblock = (struct ext2_super_block *) boffs_ptr (SBLOCK_OFFS); - - /* Cache a convenient pointer to the block group descriptors for allocation. - These are stored in the filesystem blocks following the superblock. */ -- group_desc_image = (struct ext2_group_desc *) bptr (bptr_block (sblock) + 1); -+ group_desc_image = -+ (struct ext2_group_desc *) bptr (bptr_block (mapped_sblock) + 1); - } - - error_t -@@ -196,8 +198,9 @@ diskfs_set_hypermetadata (int wait, int clean) - if (sblock_dirty) - { - sblock_dirty = 0; -- disk_cache_block_ref_ptr (sblock); -- record_global_poke (sblock); -+ memcpy (mapped_sblock, sblock, SBLOCK_SIZE); -+ disk_cache_block_ref_ptr (mapped_sblock); -+ record_global_poke (mapped_sblock); - } - - sync_global (wait); diff --git a/debian/patches/ext2fs-nodehash-lock.patch b/debian/patches/ext2fs-nodehash-lock.patch deleted file mode 100644 index 2c63643c..00000000 --- a/debian/patches/ext2fs-nodehash-lock.patch +++ /dev/null @@ -1,147 +0,0 @@ -diff --git a/ext2fs/inode.c b/ext2fs/inode.c -index ed78265..2264034 100644 ---- a/ext2fs/inode.c -+++ b/ext2fs/inode.c -@@ -48,6 +48,7 @@ - - static struct node *nodehash[INOHSZ]; - static size_t nodehash_nr_items; -+static pthread_mutex_t nodehash_lock = PTHREAD_MUTEX_INITIALIZER; - - static error_t read_node (struct node *np); - -@@ -71,12 +72,12 @@ diskfs_cached_lookup (ino_t inum, struct node **npp) - struct node *np; - struct disknode *dn; - -- pthread_spin_lock (&diskfs_node_refcnt_lock); -+ pthread_mutex_lock (&nodehash_lock); - for (np = nodehash[INOHASH(inum)]; np; np = np->dn->hnext) - if (np->cache_id == inum) - { -- np->references++; -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ diskfs_nref (np); -+ pthread_mutex_unlock (&nodehash_lock); - pthread_mutex_lock (&np->lock); - *npp = np; - return 0; -@@ -86,7 +87,7 @@ diskfs_cached_lookup (ino_t inum, struct node **npp) - dn = malloc (sizeof (struct disknode)); - if (! dn) - { -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ pthread_mutex_unlock (&nodehash_lock); - return ENOMEM; - } - dn->dirents = 0; -@@ -107,9 +108,10 @@ diskfs_cached_lookup (ino_t inum, struct node **npp) - dn->hnext->dn->hprevp = &dn->hnext; - dn->hprevp = &nodehash[INOHASH(inum)]; - nodehash[INOHASH(inum)] = np; -+ diskfs_nref_light (np); - nodehash_nr_items += 1; - -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ pthread_mutex_unlock (&nodehash_lock); - - /* Get the contents of NP off disk. */ - err = read_node (np); -@@ -140,14 +142,13 @@ ifind (ino_t inum) - { - struct node *np; - -- pthread_spin_lock (&diskfs_node_refcnt_lock); -+ pthread_mutex_lock (&nodehash_lock); - for (np = nodehash[INOHASH(inum)]; np; np = np->dn->hnext) - { - if (np->cache_id != inum) - continue; - -- assert (np->references); -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ pthread_mutex_unlock (&nodehash_lock); - return np; - } - assert (0); -@@ -158,11 +159,6 @@ ifind (ino_t inum) - void - diskfs_node_norefs (struct node *np) - { -- *np->dn->hprevp = np->dn->hnext; -- if (np->dn->hnext) -- np->dn->hnext->dn->hprevp = np->dn->hprevp; -- nodehash_nr_items -= 1; -- - if (np->dn->dirents) - free (np->dn->dirents); - assert (!np->dn->pager); -@@ -180,6 +176,31 @@ diskfs_node_norefs (struct node *np) - void - diskfs_try_dropping_softrefs (struct node *np) - { -+ pthread_mutex_lock (&nodehash_lock); -+ if (np->dn->hnext != NULL) -+ { -+ /* 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); -+ -+ if (references > 0) -+ { -+ pthread_mutex_unlock (&nodehash_lock); -+ return; -+ } -+ -+ *np->dn->hprevp = np->dn->hnext; -+ if (np->dn->hnext) -+ np->dn->hnext->dn->hprevp = np->dn->hprevp; -+ np->dn->hnext = NULL; -+ nodehash_nr_items -= 1; -+ diskfs_nrele_light (np); -+ } -+ pthread_mutex_unlock (&nodehash_lock); -+ - drop_pager_softrefs (np); - } - -@@ -556,12 +577,12 @@ diskfs_node_iterate (error_t (*fun)(struct node *)) - size_t num_nodes; - struct node *node, **node_list, **p; - -- pthread_spin_lock (&diskfs_node_refcnt_lock); -+ pthread_mutex_lock (&nodehash_lock); - - /* We must copy everything from the hash table into another data structure - to avoid running into any problems with the hash-table being modified - during processing (normally we delegate access to hash-table with -- diskfs_node_refcnt_lock, but we can't hold this while locking the -+ nodehash_lock, but we can't hold this while locking the - individual node locks). */ - num_nodes = nodehash_nr_items; - -@@ -570,7 +591,7 @@ diskfs_node_iterate (error_t (*fun)(struct node *)) - node_list = malloc (num_nodes * sizeof (struct node *)); - if (node_list == NULL) - { -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ pthread_mutex_unlock (&nodehash_lock); - ext2_debug ("unable to allocate temporary node table"); - return ENOMEM; - } -@@ -580,10 +601,10 @@ diskfs_node_iterate (error_t (*fun)(struct node *)) - for (node = nodehash[n]; node; node = node->dn->hnext) - { - *p++ = node; -- node->references++; -+ diskfs_nref (node); - } - -- pthread_spin_unlock (&diskfs_node_refcnt_lock); -+ pthread_mutex_unlock (&nodehash_lock); - - p = node_list; - while (num_nodes-- > 0) diff --git a/debian/patches/series b/debian/patches/series index 7189b96c..c08b0f99 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -40,16 +40,3 @@ xkb-compat.patch mach-defpager-protected-payload.patch -ext2fs-cache-superblock.patch -0001-libports-use-a-single-hash-table.patch -0002-include-add-lock-less-reference-counting-primitives.patch -0003-libports-lock-less-reference-counting-for-port_info-.patch -0004-libdiskfs-lock-less-reference-counting-for-peropen-o.patch -0005-libtrivfs-lock-less-reference-counting-for-trivfs_pr.patch -0006-libihash-use-an-integer-hash-function-on-the-keys.patch -0007-libihash-reduce-the-default-maximum-load-factor-to-7.patch -0008-libihash-use-linear-probing-and-fast-modulo-operatio.patch -0009-ext2fs-improve-enable-disable-_caching.patch -0010-fatfs-improve-enable-disable-_caching.patch - -ext2fs-nodehash-lock.patch |