Commit 321310ce authored by Linus Torvalds's avatar Linus Torvalds

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: default avatarDavidlohr Bueso <davidlohr.bueso@hp.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent fbfd1d28
...@@ -269,6 +269,8 @@ static inline void sem_unlock(struct sem_array *sma, int locknum) ...@@ -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 * sem_lock_(check_) routines are called in the paths where the rw_mutex
* is not held. * is not held.
*
* The caller holds the RCU read lock.
*/ */
static inline struct sem_array *sem_obtain_lock(struct ipc_namespace *ns, static inline struct sem_array *sem_obtain_lock(struct ipc_namespace *ns,
int id, struct sembuf *sops, int nsops, int *locknum) 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,12 +278,9 @@ static inline struct sem_array *sem_obtain_lock(struct ipc_namespace *ns,
struct kern_ipc_perm *ipcp; struct kern_ipc_perm *ipcp;
struct sem_array *sma; struct sem_array *sma;
rcu_read_lock();
ipcp = ipc_obtain_object(&sem_ids(ns), id); ipcp = ipc_obtain_object(&sem_ids(ns), id);
if (IS_ERR(ipcp)) { if (IS_ERR(ipcp))
sma = ERR_CAST(ipcp); return ERR_CAST(ipcp);
goto err;
}
sma = container_of(ipcp, struct sem_array, sem_perm); sma = container_of(ipcp, struct sem_array, sem_perm);
*locknum = sem_lock(sma, sops, nsops); *locknum = sem_lock(sma, sops, nsops);
...@@ -293,10 +292,7 @@ static inline struct sem_array *sem_obtain_lock(struct ipc_namespace *ns, ...@@ -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); return container_of(ipcp, struct sem_array, sem_perm);
sem_unlock(sma, *locknum); sem_unlock(sma, *locknum);
sma = ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
err:
rcu_read_unlock();
return sma;
} }
static inline struct sem_array *sem_obtain_object(struct ipc_namespace *ns, int id) static inline struct sem_array *sem_obtain_object(struct ipc_namespace *ns, int id)
...@@ -1680,6 +1676,7 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, ...@@ -1680,6 +1676,7 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
goto out_free; goto out_free;
} }
rcu_read_lock();
sma = sem_obtain_lock(ns, semid, sops, nsops, &locknum); sma = sem_obtain_lock(ns, semid, sops, nsops, &locknum);
/* /*
...@@ -1691,6 +1688,7 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, ...@@ -1691,6 +1688,7 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
* Array removed? If yes, leave without sem_unlock(). * Array removed? If yes, leave without sem_unlock().
*/ */
if (IS_ERR(sma)) { if (IS_ERR(sma)) {
rcu_read_unlock();
goto out_free; goto out_free;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment