Skip to content

Commit c97cb9c

Browse files
Davidlohr Buesotorvalds
authored andcommitted
ipc,shm: make shmctl_nolock lockless
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>
1 parent 68eccc1 commit c97cb9c

File tree

1 file changed

+12
-7
lines changed

1 file changed

+12
-7
lines changed

ipc/shm.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -882,27 +882,31 @@ static int shmctl_nolock(struct ipc_namespace *ns, int shmid,
882882
struct shmid64_ds tbuf;
883883
int result;
884884

885+
rcu_read_lock();
885886
if (cmd == SHM_STAT) {
886-
shp = shm_lock(ns, shmid);
887+
shp = shm_obtain_object(ns, shmid);
887888
if (IS_ERR(shp)) {
888889
err = PTR_ERR(shp);
889-
goto out;
890+
goto out_unlock;
890891
}
891892
result = shp->shm_perm.id;
892893
} else {
893-
shp = shm_lock_check(ns, shmid);
894+
shp = shm_obtain_object_check(ns, shmid);
894895
if (IS_ERR(shp)) {
895896
err = PTR_ERR(shp);
896-
goto out;
897+
goto out_unlock;
897898
}
898899
result = 0;
899900
}
901+
900902
err = -EACCES;
901903
if (ipcperms(ns, &shp->shm_perm, S_IRUGO))
902904
goto out_unlock;
905+
903906
err = security_shm_shmctl(shp, cmd);
904907
if (err)
905908
goto out_unlock;
909+
906910
memset(&tbuf, 0, sizeof(tbuf));
907911
kernel_to_ipc64_perm(&shp->shm_perm, &tbuf.shm_perm);
908912
tbuf.shm_segsz = shp->shm_segsz;
@@ -912,8 +916,9 @@ static int shmctl_nolock(struct ipc_namespace *ns, int shmid,
912916
tbuf.shm_cpid = shp->shm_cprid;
913917
tbuf.shm_lpid = shp->shm_lprid;
914918
tbuf.shm_nattch = shp->shm_nattch;
915-
shm_unlock(shp);
916-
if(copy_shmid_to_user (buf, &tbuf, version))
919+
rcu_read_unlock();
920+
921+
if (copy_shmid_to_user(buf, &tbuf, version))
917922
err = -EFAULT;
918923
else
919924
err = result;
@@ -924,7 +929,7 @@ static int shmctl_nolock(struct ipc_namespace *ns, int shmid,
924929
}
925930

926931
out_unlock:
927-
shm_unlock(shp);
932+
rcu_read_unlock();
928933
out:
929934
return err;
930935
}

0 commit comments

Comments
 (0)