Commit 8f17d3a5049d32392b79925c73a0cf99ce6d5af0
Committed by
Linus Torvalds
1 parent
8fdd6c6df7
Exists in
master
and in
20 other branches
[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
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
include/asm-powerpc/futex.h
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); |
kernel/fork.c
... | ... | @@ -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 | */ |
kernel/futex.c
... | ... | @@ -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 | } |