Skip to content

Commit

Permalink
ipc,shm: shorten critical region in shmctl_down
Browse files Browse the repository at this point in the history
Instead of holding the ipc lock for the entire function, use the
ipcctl_pre_down_nolock and only acquire the lock for specific commands:
RMID and SET.

Signed-off-by: Davidlohr Bueso <[email protected]>
Tested-by: Sedat Dilek <[email protected]>
Cc: Rik van Riel <[email protected]>
Cc: Manfred Spraul <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Davidlohr Bueso authored and torvalds committed Sep 11, 2013
1 parent 8b8d52a commit 79ccf0f
Showing 1 changed file with 6 additions and 4 deletions.
10 changes: 6 additions & 4 deletions ipc/shm.c
Original file line number Diff line number Diff line change
Expand Up @@ -780,33 +780,35 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd,
down_write(&shm_ids(ns).rw_mutex);
rcu_read_lock();

ipcp = ipcctl_pre_down(ns, &shm_ids(ns), shmid, cmd,
&shmid64.shm_perm, 0);
ipcp = ipcctl_pre_down_nolock(ns, &shm_ids(ns), shmid, cmd,
&shmid64.shm_perm, 0);
if (IS_ERR(ipcp)) {
err = PTR_ERR(ipcp);
/* the ipc lock is not held upon failure */
goto out_unlock1;
}

shp = container_of(ipcp, struct shmid_kernel, shm_perm);

err = security_shm_shmctl(shp, cmd);
if (err)
goto out_unlock0;
goto out_unlock1;

switch (cmd) {
case IPC_RMID:
ipc_lock_object(&shp->shm_perm);
/* do_shm_rmid unlocks the ipc object and rcu */
do_shm_rmid(ns, ipcp);
goto out_up;
case IPC_SET:
ipc_lock_object(&shp->shm_perm);
err = ipc_update_perm(&shmid64.shm_perm, ipcp);
if (err)
goto out_unlock0;
shp->shm_ctim = get_seconds();
break;
default:
err = -EINVAL;
goto out_unlock1;
}

out_unlock0:
Expand Down

0 comments on commit 79ccf0f

Please sign in to comment.