Skip to content

Commit

Permalink
ipc,shm: make shmctl_nolock lockless
Browse files Browse the repository at this point in the history
While the INFO cmd doesn't take the ipc lock, the STAT commands do acquire
it unnecessarily.  We can do the permissions and security checks only
holding the rcu lock.

[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
Tested-by: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Manfred Spraul <manfred@colorfullife.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Davidlohr Bueso authored and Linus Torvalds committed Sep 11, 2013
1 parent 68eccc1 commit c97cb9c
Showing 1 changed file with 12 additions and 7 deletions.
19 changes: 12 additions & 7 deletions ipc/shm.c
Original file line number Diff line number Diff line change
Expand Up @@ -882,27 +882,31 @@ static int shmctl_nolock(struct ipc_namespace *ns, int shmid,
struct shmid64_ds tbuf;
int result;

rcu_read_lock();
if (cmd == SHM_STAT) {
shp = shm_lock(ns, shmid);
shp = shm_obtain_object(ns, shmid);
if (IS_ERR(shp)) {
err = PTR_ERR(shp);
goto out;
goto out_unlock;
}
result = shp->shm_perm.id;
} else {
shp = shm_lock_check(ns, shmid);
shp = shm_obtain_object_check(ns, shmid);
if (IS_ERR(shp)) {
err = PTR_ERR(shp);
goto out;
goto out_unlock;
}
result = 0;
}

err = -EACCES;
if (ipcperms(ns, &shp->shm_perm, S_IRUGO))
goto out_unlock;

err = security_shm_shmctl(shp, cmd);
if (err)
goto out_unlock;

memset(&tbuf, 0, sizeof(tbuf));
kernel_to_ipc64_perm(&shp->shm_perm, &tbuf.shm_perm);
tbuf.shm_segsz = shp->shm_segsz;
Expand All @@ -912,8 +916,9 @@ static int shmctl_nolock(struct ipc_namespace *ns, int shmid,
tbuf.shm_cpid = shp->shm_cprid;
tbuf.shm_lpid = shp->shm_lprid;
tbuf.shm_nattch = shp->shm_nattch;
shm_unlock(shp);
if(copy_shmid_to_user (buf, &tbuf, version))
rcu_read_unlock();

if (copy_shmid_to_user(buf, &tbuf, version))
err = -EFAULT;
else
err = result;
Expand All @@ -924,7 +929,7 @@ static int shmctl_nolock(struct ipc_namespace *ns, int shmid,
}

out_unlock:
shm_unlock(shp);
rcu_read_unlock();
out:
return err;
}
Expand Down

0 comments on commit c97cb9c

Please sign in to comment.