Commit 8f17d3a5049d32392b79925c73a0cf99ce6d5af0

Authored by Ingo Molnar
Committed by Linus Torvalds
1 parent 8fdd6c6df7

[PATCH] lightweight robust futexes updates

- fix: initialize the robust list(s) to NULL in copy_process.

- doc update

- cleanup: rename _inuser to _inatomic

- __user cleanups and other small cleanups

Signed-off-by: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Arjan van de Ven <arjan@infradead.org>
Cc: Ulrich Drepper <drepper@redhat.com>
Cc: Andi Kleen <ak@muc.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 12 changed files with 24 additions and 26 deletions Side-by-side Diff

Documentation/robust-futex-ABI.txt
... ... @@ -142,8 +142,6 @@
142 142 of the 'lock word', to the linked list starting at 'head', and
143 143 4) clear the 'list_op_pending' word.
144 144  
145   - XXX I am particularly unsure of the following -pj XXX
146   -
147 145 On removal:
148 146 1) set the 'list_op_pending' word to the address of the 'lock word'
149 147 to be removed,
Documentation/robust-futexes.txt
... ... @@ -213,7 +213,7 @@
213 213 All other architectures should build just fine too - but they wont have
214 214 the new syscalls yet.
215 215  
216   -Architectures need to implement the new futex_atomic_cmpxchg_inuser()
  216 +Architectures need to implement the new futex_atomic_cmpxchg_inatomic()
217 217 inline function before writing up the syscalls (that function returns
218 218 -ENOSYS right now).
include/asm-frv/futex.h
... ... @@ -10,7 +10,7 @@
10 10 extern int futex_atomic_op_inuser(int encoded_op, int __user *uaddr);
11 11  
12 12 static inline int
13   -futex_atomic_cmpxchg_inuser(int __user *uaddr, int oldval, int newval)
  13 +futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
14 14 {
15 15 return -ENOSYS;
16 16 }
include/asm-generic/futex.h
... ... @@ -50,7 +50,7 @@
50 50 }
51 51  
52 52 static inline int
53   -futex_atomic_cmpxchg_inuser(int __user *uaddr, int oldval, int newval)
  53 +futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
54 54 {
55 55 return -ENOSYS;
56 56 }
include/asm-i386/futex.h
... ... @@ -105,7 +105,7 @@
105 105 }
106 106  
107 107 static inline int
108   -futex_atomic_cmpxchg_inuser(int __user *uaddr, int oldval, int newval)
  108 +futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
109 109 {
110 110 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
111 111 return -EFAULT;
include/asm-mips/futex.h
... ... @@ -100,7 +100,7 @@
100 100 }
101 101  
102 102 static inline int
103   -futex_atomic_cmpxchg_inuser(int __user *uaddr, int oldval, int newval)
  103 +futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
104 104 {
105 105 return -ENOSYS;
106 106 }
include/asm-powerpc/futex.h
... ... @@ -82,7 +82,7 @@
82 82 }
83 83  
84 84 static inline int
85   -futex_atomic_cmpxchg_inuser(int __user *uaddr, int oldval, int newval)
  85 +futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
86 86 {
87 87 return -ENOSYS;
88 88 }
include/asm-x86_64/futex.h
... ... @@ -95,7 +95,7 @@
95 95 }
96 96  
97 97 static inline int
98   -futex_atomic_cmpxchg_inuser(int __user *uaddr, int oldval, int newval)
  98 +futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
99 99 {
100 100 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
101 101 return -EFAULT;
include/linux/futex.h
... ... @@ -100,7 +100,7 @@
100 100 unsigned long timeout, unsigned long uaddr2, int val2,
101 101 int val3);
102 102  
103   -extern int handle_futex_death(unsigned int *uaddr, struct task_struct *curr);
  103 +extern int handle_futex_death(u32 __user *uaddr, struct task_struct *curr);
104 104  
105 105 #ifdef CONFIG_FUTEX
106 106 extern void exit_robust_list(struct task_struct *curr);
... ... @@ -1061,7 +1061,10 @@
1061 1061 * Clear TID on mm_release()?
1062 1062 */
1063 1063 p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? child_tidptr: NULL;
1064   -
  1064 + p->robust_list = NULL;
  1065 +#ifdef CONFIG_COMPAT
  1066 + p->compat_robust_list = NULL;
  1067 +#endif
1065 1068 /*
1066 1069 * sigaltstack should be cleared when sharing the same VM
1067 1070 */
... ... @@ -913,15 +913,15 @@
913 913 * Process a futex-list entry, check whether it's owned by the
914 914 * dying task, and do notification if so:
915 915 */
916   -int handle_futex_death(unsigned int *uaddr, struct task_struct *curr)
  916 +int handle_futex_death(u32 __user *uaddr, struct task_struct *curr)
917 917 {
918   - unsigned int futex_val;
  918 + u32 uval;
919 919  
920   -repeat:
921   - if (get_user(futex_val, uaddr))
  920 +retry:
  921 + if (get_user(uval, uaddr))
922 922 return -1;
923 923  
924   - if ((futex_val & FUTEX_TID_MASK) == curr->pid) {
  924 + if ((uval & FUTEX_TID_MASK) == curr->pid) {
925 925 /*
926 926 * Ok, this dying thread is truly holding a futex
927 927 * of interest. Set the OWNER_DIED bit atomically
928 928  
... ... @@ -932,12 +932,11 @@
932 932 * thread-death.) The rest of the cleanup is done in
933 933 * userspace.
934 934 */
935   - if (futex_atomic_cmpxchg_inuser(uaddr, futex_val,
936   - futex_val | FUTEX_OWNER_DIED) !=
937   - futex_val)
938   - goto repeat;
  935 + if (futex_atomic_cmpxchg_inatomic(uaddr, uval,
  936 + uval | FUTEX_OWNER_DIED) != uval)
  937 + goto retry;
939 938  
940   - if (futex_val & FUTEX_WAITERS)
  939 + if (uval & FUTEX_WAITERS)
941 940 futex_wake((unsigned long)uaddr, 1);
942 941 }
943 942 return 0;
... ... @@ -985,7 +984,6 @@
985 984 if (handle_futex_death((void *)entry + futex_offset,
986 985 curr))
987 986 return;
988   -
989 987 /*
990 988 * Fetch the next entry in the list:
991 989 */
kernel/futex_compat.c
... ... @@ -121,9 +121,9 @@
121 121 return ret;
122 122 }
123 123  
124   -asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, int val,
  124 +asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val,
125 125 struct compat_timespec __user *utime, u32 __user *uaddr2,
126   - int val3)
  126 + u32 val3)
127 127 {
128 128 struct timespec t;
129 129 unsigned long timeout = MAX_SCHEDULE_TIMEOUT;
... ... @@ -137,7 +137,6 @@
137 137 if (op >= FUTEX_REQUEUE)
138 138 val2 = (int) (unsigned long) utime;
139 139  
140   - return do_futex((unsigned long)uaddr, op, val, timeout,
141   - (unsigned long)uaddr2, val2, val3);
  140 + return do_futex(uaddr, op, val, timeout, uaddr2, val2, val3);
142 141 }