From 6062a8dc0517bce23e3c2f7d2fea5e22411269a3 Mon Sep 17 00:00:00 2001 From: Rik van Riel Date: Tue, 30 Apr 2013 19:15:44 -0700 Subject: ipc,sem: fine grained locking for semtimedop Introduce finer grained locking for semtimedop, to handle the common case of a program wanting to manipulate one semaphore from an array with multiple semaphores. If the call is a semop manipulating just one semaphore in an array with multiple semaphores, only take the lock for that semaphore itself. If the call needs to manipulate multiple semaphores, or another caller is in a transaction that manipulates multiple semaphores, the sem_array lock is taken, as well as all the locks for the individual semaphores. On a 24 CPU system, performance numbers with the semop-multi test with N threads and N semaphores, look like this: vanilla Davidlohr's Davidlohr's + Davidlohr's + threads patches rwlock patches v3 patches 10 610652 726325 1783589 2142206 20 341570 365699 1520453 1977878 30 288102 307037 1498167 2037995 40 290714 305955 1612665 2256484 50 288620 312890 1733453 2650292 60 289987 306043 1649360 2388008 70 291298 306347 1723167 2717486 80 290948 305662 1729545 2763582 90 290996 306680 1736021 2757524 100 292243 306700 1773700 3059159 [davidlohr.bueso@hp.com: do not call sem_lock when bogus sma] [davidlohr.bueso@hp.com: make refcounter atomic] Signed-off-by: Rik van Riel Suggested-by: Linus Torvalds Acked-by: Davidlohr Bueso Cc: Chegu Vinod Cc: Jason Low Reviewed-by: Michel Lespinasse Cc: Peter Hurley Cc: Stanislav Kinsbursky Tested-by: Emmanuel Benisty Tested-by: Sedat Dilek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- ipc/util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ipc/util.h') diff --git a/ipc/util.h b/ipc/util.h index c36b9977c957..2b0bdd5d92ce 100644 --- a/ipc/util.h +++ b/ipc/util.h @@ -119,7 +119,7 @@ void ipc_free(void* ptr, int size); * to 0 schedules the rcu destruction. Caller must guarantee locking. */ void* ipc_rcu_alloc(int size); -void ipc_rcu_getref(void *ptr); +int ipc_rcu_getref(void *ptr); void ipc_rcu_putref(void *ptr); struct kern_ipc_perm *ipc_lock(struct ipc_ids *, int); -- cgit v1.2.3-59-g8ed1b