diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-12-18 09:34:43 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-12-18 09:53:41 -0500 |
commit | 797245f5da543074ee7db0e0516da744c89aa17f (patch) | |
tree | 429a08d54bb870c720139a3f04ad27ded7f93a8f /arch/arm/kernel/process.c | |
parent | 2395d66d09ce10c25b6756575c4aeb219760d1fc (diff) |
ARM: Convert VFP/Crunch/XscaleCP thread_release() to exit_thread()
This avoids races in the VFP code where the dead thread may have
state on another CPU. By moving this code to exit_thread(), we
will be running as the thread, and therefore be running on the
current CPU.
This means that we can ensure that the only local state is accessed
in the thread notifiers.
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/process.c')
-rw-r--r-- | arch/arm/kernel/process.c | 12 |
1 files changed, 5 insertions, 7 deletions
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 0d96d0171c05..67304138a2ca 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c | |||
@@ -274,17 +274,18 @@ void show_regs(struct pt_regs * regs) | |||
274 | __backtrace(); | 274 | __backtrace(); |
275 | } | 275 | } |
276 | 276 | ||
277 | ATOMIC_NOTIFIER_HEAD(thread_notify_head); | ||
278 | |||
279 | EXPORT_SYMBOL_GPL(thread_notify_head); | ||
280 | |||
277 | /* | 281 | /* |
278 | * Free current thread data structures etc.. | 282 | * Free current thread data structures etc.. |
279 | */ | 283 | */ |
280 | void exit_thread(void) | 284 | void exit_thread(void) |
281 | { | 285 | { |
286 | thread_notify(THREAD_NOTIFY_EXIT, current_thread_info()); | ||
282 | } | 287 | } |
283 | 288 | ||
284 | ATOMIC_NOTIFIER_HEAD(thread_notify_head); | ||
285 | |||
286 | EXPORT_SYMBOL_GPL(thread_notify_head); | ||
287 | |||
288 | void flush_thread(void) | 289 | void flush_thread(void) |
289 | { | 290 | { |
290 | struct thread_info *thread = current_thread_info(); | 291 | struct thread_info *thread = current_thread_info(); |
@@ -299,9 +300,6 @@ void flush_thread(void) | |||
299 | 300 | ||
300 | void release_thread(struct task_struct *dead_task) | 301 | void release_thread(struct task_struct *dead_task) |
301 | { | 302 | { |
302 | struct thread_info *thread = task_thread_info(dead_task); | ||
303 | |||
304 | thread_notify(THREAD_NOTIFY_RELEASE, thread); | ||
305 | } | 303 | } |
306 | 304 | ||
307 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); | 305 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); |