diff options
author | Ingo Molnar <mingo@elte.hu> | 2006-03-27 04:16:27 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-27 11:44:49 -0500 |
commit | 8f17d3a5049d32392b79925c73a0cf99ce6d5af0 (patch) | |
tree | 3c2aa0cbe337684d353dd2cfb0c177b4ae15217c | |
parent | 8fdd6c6df7889dc89df3d9fe0f5bbe6733e39f48 (diff) |
[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>
-rw-r--r-- | Documentation/robust-futex-ABI.txt | 2 | ||||
-rw-r--r-- | Documentation/robust-futexes.txt | 2 | ||||
-rw-r--r-- | include/asm-frv/futex.h | 2 | ||||
-rw-r--r-- | include/asm-generic/futex.h | 2 | ||||
-rw-r--r-- | include/asm-i386/futex.h | 2 | ||||
-rw-r--r-- | include/asm-mips/futex.h | 2 | ||||
-rw-r--r-- | include/asm-powerpc/futex.h | 2 | ||||
-rw-r--r-- | include/asm-x86_64/futex.h | 2 | ||||
-rw-r--r-- | include/linux/futex.h | 2 | ||||
-rw-r--r-- | kernel/fork.c | 5 | ||||
-rw-r--r-- | kernel/futex.c | 20 | ||||
-rw-r--r-- | kernel/futex_compat.c | 7 |
12 files changed, 24 insertions, 26 deletions
diff --git a/Documentation/robust-futex-ABI.txt b/Documentation/robust-futex-ABI.txt index def5d8735286..8529a17ffaa1 100644 --- a/Documentation/robust-futex-ABI.txt +++ b/Documentation/robust-futex-ABI.txt | |||
@@ -142,8 +142,6 @@ On insertion: | |||
142 | of the 'lock word', to the linked list starting at 'head', and | 142 | of the 'lock word', to the linked list starting at 'head', and |
143 | 4) clear the 'list_op_pending' word. | 143 | 4) clear the 'list_op_pending' word. |
144 | 144 | ||
145 | XXX I am particularly unsure of the following -pj XXX | ||
146 | |||
147 | On removal: | 145 | On removal: |
148 | 1) set the 'list_op_pending' word to the address of the 'lock word' | 146 | 1) set the 'list_op_pending' word to the address of the 'lock word' |
149 | to be removed, | 147 | to be removed, |
diff --git a/Documentation/robust-futexes.txt b/Documentation/robust-futexes.txt index 7aecc67b1361..df82d75245a0 100644 --- a/Documentation/robust-futexes.txt +++ b/Documentation/robust-futexes.txt | |||
@@ -213,6 +213,6 @@ robust-mutex testcases. | |||
213 | All other architectures should build just fine too - but they wont have | 213 | All other architectures should build just fine too - but they wont have |
214 | the new syscalls yet. | 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 | inline function before writing up the syscalls (that function returns | 217 | inline function before writing up the syscalls (that function returns |
218 | -ENOSYS right now). | 218 | -ENOSYS right now). |
diff --git a/include/asm-frv/futex.h b/include/asm-frv/futex.h index 9a0e9026ba5e..08b3d1da3583 100644 --- a/include/asm-frv/futex.h +++ b/include/asm-frv/futex.h | |||
@@ -10,7 +10,7 @@ | |||
10 | extern int futex_atomic_op_inuser(int encoded_op, int __user *uaddr); | 10 | extern int futex_atomic_op_inuser(int encoded_op, int __user *uaddr); |
11 | 11 | ||
12 | static inline int | 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 | return -ENOSYS; | 15 | return -ENOSYS; |
16 | } | 16 | } |
diff --git a/include/asm-generic/futex.h b/include/asm-generic/futex.h index 514bd401cd7e..df893c160318 100644 --- a/include/asm-generic/futex.h +++ b/include/asm-generic/futex.h | |||
@@ -50,7 +50,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) | |||
50 | } | 50 | } |
51 | 51 | ||
52 | static inline int | 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 | return -ENOSYS; | 55 | return -ENOSYS; |
56 | } | 56 | } |
diff --git a/include/asm-i386/futex.h b/include/asm-i386/futex.h index 41184a31885c..7b8ceefd010f 100644 --- a/include/asm-i386/futex.h +++ b/include/asm-i386/futex.h | |||
@@ -105,7 +105,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) | |||
105 | } | 105 | } |
106 | 106 | ||
107 | static inline int | 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 | if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) | 110 | if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) |
111 | return -EFAULT; | 111 | return -EFAULT; |
diff --git a/include/asm-mips/futex.h b/include/asm-mips/futex.h index c5fb2d6d918a..a554089991f2 100644 --- a/include/asm-mips/futex.h +++ b/include/asm-mips/futex.h | |||
@@ -100,7 +100,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) | |||
100 | } | 100 | } |
101 | 101 | ||
102 | static inline int | 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 | return -ENOSYS; | 105 | return -ENOSYS; |
106 | } | 106 | } |
diff --git a/include/asm-powerpc/futex.h b/include/asm-powerpc/futex.h index 80ed9854e42b..f1b3c00bc1ce 100644 --- a/include/asm-powerpc/futex.h +++ b/include/asm-powerpc/futex.h | |||
@@ -82,7 +82,7 @@ static inline int futex_atomic_op_inuser (int encoded_op, int __user *uaddr) | |||
82 | } | 82 | } |
83 | 83 | ||
84 | static inline int | 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 | return -ENOSYS; | 87 | return -ENOSYS; |
88 | } | 88 | } |
diff --git a/include/asm-x86_64/futex.h b/include/asm-x86_64/futex.h index 7d9eb1a84546..9804bf07b092 100644 --- a/include/asm-x86_64/futex.h +++ b/include/asm-x86_64/futex.h | |||
@@ -95,7 +95,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) | |||
95 | } | 95 | } |
96 | 96 | ||
97 | static inline int | 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 | if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) | 100 | if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) |
101 | return -EFAULT; | 101 | return -EFAULT; |
diff --git a/include/linux/futex.h b/include/linux/futex.h index 20face6b798d..55fff96ae859 100644 --- a/include/linux/futex.h +++ b/include/linux/futex.h | |||
@@ -100,7 +100,7 @@ long do_futex(unsigned long uaddr, int op, int val, | |||
100 | unsigned long timeout, unsigned long uaddr2, int val2, | 100 | unsigned long timeout, unsigned long uaddr2, int val2, |
101 | int val3); | 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 | #ifdef CONFIG_FUTEX | 105 | #ifdef CONFIG_FUTEX |
106 | extern void exit_robust_list(struct task_struct *curr); | 106 | extern void exit_robust_list(struct task_struct *curr); |
diff --git a/kernel/fork.c b/kernel/fork.c index e0a2b449dea6..c49bd193b058 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -1061,7 +1061,10 @@ static task_t *copy_process(unsigned long clone_flags, | |||
1061 | * Clear TID on mm_release()? | 1061 | * Clear TID on mm_release()? |
1062 | */ | 1062 | */ |
1063 | p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? child_tidptr: NULL; | 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 | * sigaltstack should be cleared when sharing the same VM | 1069 | * sigaltstack should be cleared when sharing the same VM |
1067 | */ | 1070 | */ |
diff --git a/kernel/futex.c b/kernel/futex.c index feb724b2554e..9c9b2b6b22dd 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -913,15 +913,15 @@ err_unlock: | |||
913 | * Process a futex-list entry, check whether it's owned by the | 913 | * Process a futex-list entry, check whether it's owned by the |
914 | * dying task, and do notification if so: | 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: | 920 | retry: |
921 | if (get_user(futex_val, uaddr)) | 921 | if (get_user(uval, uaddr)) |
922 | return -1; | 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 | * Ok, this dying thread is truly holding a futex | 926 | * Ok, this dying thread is truly holding a futex |
927 | * of interest. Set the OWNER_DIED bit atomically | 927 | * of interest. Set the OWNER_DIED bit atomically |
@@ -932,12 +932,11 @@ repeat: | |||
932 | * thread-death.) The rest of the cleanup is done in | 932 | * thread-death.) The rest of the cleanup is done in |
933 | * userspace. | 933 | * userspace. |
934 | */ | 934 | */ |
935 | if (futex_atomic_cmpxchg_inuser(uaddr, futex_val, | 935 | if (futex_atomic_cmpxchg_inatomic(uaddr, uval, |
936 | futex_val | FUTEX_OWNER_DIED) != | 936 | uval | FUTEX_OWNER_DIED) != uval) |
937 | futex_val) | 937 | goto retry; |
938 | goto repeat; | ||
939 | 938 | ||
940 | if (futex_val & FUTEX_WAITERS) | 939 | if (uval & FUTEX_WAITERS) |
941 | futex_wake((unsigned long)uaddr, 1); | 940 | futex_wake((unsigned long)uaddr, 1); |
942 | } | 941 | } |
943 | return 0; | 942 | return 0; |
@@ -985,7 +984,6 @@ void exit_robust_list(struct task_struct *curr) | |||
985 | if (handle_futex_death((void *)entry + futex_offset, | 984 | if (handle_futex_death((void *)entry + futex_offset, |
986 | curr)) | 985 | curr)) |
987 | return; | 986 | return; |
988 | |||
989 | /* | 987 | /* |
990 | * Fetch the next entry in the list: | 988 | * Fetch the next entry in the list: |
991 | */ | 989 | */ |
diff --git a/kernel/futex_compat.c b/kernel/futex_compat.c index c153559ef289..9c077cf9aa84 100644 --- a/kernel/futex_compat.c +++ b/kernel/futex_compat.c | |||
@@ -121,9 +121,9 @@ err_unlock: | |||
121 | return ret; | 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 | struct compat_timespec __user *utime, u32 __user *uaddr2, | 125 | struct compat_timespec __user *utime, u32 __user *uaddr2, |
126 | int val3) | 126 | u32 val3) |
127 | { | 127 | { |
128 | struct timespec t; | 128 | struct timespec t; |
129 | unsigned long timeout = MAX_SCHEDULE_TIMEOUT; | 129 | unsigned long timeout = MAX_SCHEDULE_TIMEOUT; |
@@ -137,6 +137,5 @@ asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, int val, | |||
137 | if (op >= FUTEX_REQUEUE) | 137 | if (op >= FUTEX_REQUEUE) |
138 | val2 = (int) (unsigned long) utime; | 138 | val2 = (int) (unsigned long) utime; |
139 | 139 | ||
140 | return do_futex((unsigned long)uaddr, op, val, timeout, | 140 | return do_futex(uaddr, op, val, timeout, uaddr2, val2, val3); |
141 | (unsigned long)uaddr2, val2, val3); | ||
142 | } | 141 | } |