From 321310ced2d6cc0175c76fa512fa8a829ee35223 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 4 May 2013 10:47:57 -0700 Subject: [PATCH] ipc: move sem_obtain_lock() rcu locking into the only caller sem_obtain_lock() was another of those functions that returned with the RCU lock held for reading in the success case. Move the RCU locking to the caller (semtimedop()), making it more obvious. We already did RCU locking elsewhere in that function. Side note: why does semtimedop() re-do the semphore lookup after the sleep, rather than just getting a reference to the semaphore it already looked up originally? Acked-by: Davidlohr Bueso Cc: Rik van Riel Cc: Al Viro Signed-off-by: Linus Torvalds --- ipc/sem.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/ipc/sem.c b/ipc/sem.c index 1f8f01a542de..8486a5bb6d29 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -269,6 +269,8 @@ static inline void sem_unlock(struct sem_array *sma, int locknum) /* * sem_lock_(check_) routines are called in the paths where the rw_mutex * is not held. + * + * The caller holds the RCU read lock. */ static inline struct sem_array *sem_obtain_lock(struct ipc_namespace *ns, int id, struct sembuf *sops, int nsops, int *locknum) @@ -276,12 +278,9 @@ static inline struct sem_array *sem_obtain_lock(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp; struct sem_array *sma; - rcu_read_lock(); ipcp = ipc_obtain_object(&sem_ids(ns), id); - if (IS_ERR(ipcp)) { - sma = ERR_CAST(ipcp); - goto err; - } + if (IS_ERR(ipcp)) + return ERR_CAST(ipcp); sma = container_of(ipcp, struct sem_array, sem_perm); *locknum = sem_lock(sma, sops, nsops); @@ -293,10 +292,7 @@ static inline struct sem_array *sem_obtain_lock(struct ipc_namespace *ns, return container_of(ipcp, struct sem_array, sem_perm); sem_unlock(sma, *locknum); - sma = ERR_PTR(-EINVAL); -err: - rcu_read_unlock(); - return sma; + return ERR_PTR(-EINVAL); } static inline struct sem_array *sem_obtain_object(struct ipc_namespace *ns, int id) @@ -1680,6 +1676,7 @@ sleep_again: goto out_free; } + rcu_read_lock(); sma = sem_obtain_lock(ns, semid, sops, nsops, &locknum); /* @@ -1691,6 +1688,7 @@ sleep_again: * Array removed? If yes, leave without sem_unlock(). */ if (IS_ERR(sma)) { + rcu_read_unlock(); goto out_free; }