aboutsummaryrefslogtreecommitdiffstats
path: root/ipc/sem.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-04 13:47:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-04 20:20:14 -0400
commit321310ced2d6cc0175c76fa512fa8a829ee35223 (patch)
tree0722d86daa8778a69207965cc6bc005d0def9f08 /ipc/sem.c
parentfbfd1d2862a8316c7191bc551c6a842e6918abb0 (diff)
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 <davidlohr.bueso@hp.com> Cc: Rik van Riel <riel@redhat.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'ipc/sem.c')
-rw-r--r--ipc/sem.c16
1 files 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)
269/* 269/*
270 * sem_lock_(check_) routines are called in the paths where the rw_mutex 270 * sem_lock_(check_) routines are called in the paths where the rw_mutex
271 * is not held. 271 * is not held.
272 *
273 * The caller holds the RCU read lock.
272 */ 274 */
273static inline struct sem_array *sem_obtain_lock(struct ipc_namespace *ns, 275static inline struct sem_array *sem_obtain_lock(struct ipc_namespace *ns,
274 int id, struct sembuf *sops, int nsops, int *locknum) 276 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,
276 struct kern_ipc_perm *ipcp; 278 struct kern_ipc_perm *ipcp;
277 struct sem_array *sma; 279 struct sem_array *sma;
278 280
279 rcu_read_lock();
280 ipcp = ipc_obtain_object(&sem_ids(ns), id); 281 ipcp = ipc_obtain_object(&sem_ids(ns), id);
281 if (IS_ERR(ipcp)) { 282 if (IS_ERR(ipcp))
282 sma = ERR_CAST(ipcp); 283 return ERR_CAST(ipcp);
283 goto err;
284 }
285 284
286 sma = container_of(ipcp, struct sem_array, sem_perm); 285 sma = container_of(ipcp, struct sem_array, sem_perm);
287 *locknum = sem_lock(sma, sops, nsops); 286 *locknum = sem_lock(sma, sops, nsops);
@@ -293,10 +292,7 @@ static inline struct sem_array *sem_obtain_lock(struct ipc_namespace *ns,
293 return container_of(ipcp, struct sem_array, sem_perm); 292 return container_of(ipcp, struct sem_array, sem_perm);
294 293
295 sem_unlock(sma, *locknum); 294 sem_unlock(sma, *locknum);
296 sma = ERR_PTR(-EINVAL); 295 return ERR_PTR(-EINVAL);
297err:
298 rcu_read_unlock();
299 return sma;
300} 296}
301 297
302static inline struct sem_array *sem_obtain_object(struct ipc_namespace *ns, int id) 298static inline struct sem_array *sem_obtain_object(struct ipc_namespace *ns, int id)
@@ -1680,6 +1676,7 @@ sleep_again:
1680 goto out_free; 1676 goto out_free;
1681 } 1677 }
1682 1678
1679 rcu_read_lock();
1683 sma = sem_obtain_lock(ns, semid, sops, nsops, &locknum); 1680 sma = sem_obtain_lock(ns, semid, sops, nsops, &locknum);
1684 1681
1685 /* 1682 /*
@@ -1691,6 +1688,7 @@ sleep_again:
1691 * Array removed? If yes, leave without sem_unlock(). 1688 * Array removed? If yes, leave without sem_unlock().
1692 */ 1689 */
1693 if (IS_ERR(sma)) { 1690 if (IS_ERR(sma)) {
1691 rcu_read_unlock();
1694 goto out_free; 1692 goto out_free;
1695 } 1693 }
1696 1694