Commit 1c7ee8a0cc8ba17b5f99133b004edfe64fb496fb

Authored by Davidlohr Bueso
Committed by Greg Kroah-Hartman
1 parent dafeda2a91

ipc,shm: make shmctl_nolock lockless

commit c97cb9ccab8c85428ec21eff690642ad2ce1fa8a upstream.

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>
Cc: Mike Galbraith <efault@gmx.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Showing 1 changed file with 12 additions and 7 deletions Side-by-side Diff

... ... @@ -889,27 +889,31 @@
889 889 struct shmid64_ds tbuf;
890 890 int result;
891 891  
  892 + rcu_read_lock();
892 893 if (cmd == SHM_STAT) {
893   - shp = shm_lock(ns, shmid);
  894 + shp = shm_obtain_object(ns, shmid);
894 895 if (IS_ERR(shp)) {
895 896 err = PTR_ERR(shp);
896   - goto out;
  897 + goto out_unlock;
897 898 }
898 899 result = shp->shm_perm.id;
899 900 } else {
900   - shp = shm_lock_check(ns, shmid);
  901 + shp = shm_obtain_object_check(ns, shmid);
901 902 if (IS_ERR(shp)) {
902 903 err = PTR_ERR(shp);
903   - goto out;
  904 + goto out_unlock;
904 905 }
905 906 result = 0;
906 907 }
  908 +
907 909 err = -EACCES;
908 910 if (ipcperms(ns, &shp->shm_perm, S_IRUGO))
909 911 goto out_unlock;
  912 +
910 913 err = security_shm_shmctl(shp, cmd);
911 914 if (err)
912 915 goto out_unlock;
  916 +
913 917 memset(&tbuf, 0, sizeof(tbuf));
914 918 kernel_to_ipc64_perm(&shp->shm_perm, &tbuf.shm_perm);
915 919 tbuf.shm_segsz = shp->shm_segsz;
... ... @@ -919,8 +923,9 @@
919 923 tbuf.shm_cpid = shp->shm_cprid;
920 924 tbuf.shm_lpid = shp->shm_lprid;
921 925 tbuf.shm_nattch = shp->shm_nattch;
922   - shm_unlock(shp);
923   - if(copy_shmid_to_user (buf, &tbuf, version))
  926 + rcu_read_unlock();
  927 +
  928 + if (copy_shmid_to_user(buf, &tbuf, version))
924 929 err = -EFAULT;
925 930 else
926 931 err = result;
... ... @@ -931,7 +936,7 @@
931 936 }
932 937  
933 938 out_unlock:
934   - shm_unlock(shp);
  939 + rcu_read_unlock();
935 940 out:
936 941 return err;
937 942 }