diff options
| -rw-r--r-- | arch/arm/include/asm/thread_notify.h | 2 | ||||
| -rw-r--r-- | arch/arm/kernel/crunch.c | 2 | ||||
| -rw-r--r-- | arch/arm/kernel/process.c | 12 | ||||
| -rw-r--r-- | arch/arm/kernel/xscale-cp0.c | 2 | ||||
| -rw-r--r-- | arch/arm/vfp/vfpmodule.c | 19 |
5 files changed, 19 insertions, 18 deletions
diff --git a/arch/arm/include/asm/thread_notify.h b/arch/arm/include/asm/thread_notify.h index f27379d7f72a..c4391ba20350 100644 --- a/arch/arm/include/asm/thread_notify.h +++ b/arch/arm/include/asm/thread_notify.h | |||
| @@ -41,7 +41,7 @@ static inline void thread_notify(unsigned long rc, struct thread_info *thread) | |||
| 41 | * These are the reason codes for the thread notifier. | 41 | * These are the reason codes for the thread notifier. |
| 42 | */ | 42 | */ |
| 43 | #define THREAD_NOTIFY_FLUSH 0 | 43 | #define THREAD_NOTIFY_FLUSH 0 |
| 44 | #define THREAD_NOTIFY_RELEASE 1 | 44 | #define THREAD_NOTIFY_EXIT 1 |
| 45 | #define THREAD_NOTIFY_SWITCH 2 | 45 | #define THREAD_NOTIFY_SWITCH 2 |
| 46 | 46 | ||
| 47 | #endif | 47 | #endif |
diff --git a/arch/arm/kernel/crunch.c b/arch/arm/kernel/crunch.c index 769abe15cf91..25ef223ba7f3 100644 --- a/arch/arm/kernel/crunch.c +++ b/arch/arm/kernel/crunch.c | |||
| @@ -51,7 +51,7 @@ static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t) | |||
| 51 | * initialised state information on the first fault. | 51 | * initialised state information on the first fault. |
| 52 | */ | 52 | */ |
| 53 | 53 | ||
| 54 | case THREAD_NOTIFY_RELEASE: | 54 | case THREAD_NOTIFY_EXIT: |
| 55 | crunch_task_release(thread); | 55 | crunch_task_release(thread); |
| 56 | break; | 56 | break; |
| 57 | 57 | ||
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"); |
diff --git a/arch/arm/kernel/xscale-cp0.c b/arch/arm/kernel/xscale-cp0.c index 17127db906fa..1796157e3dd5 100644 --- a/arch/arm/kernel/xscale-cp0.c +++ b/arch/arm/kernel/xscale-cp0.c | |||
| @@ -70,7 +70,7 @@ static int iwmmxt_do(struct notifier_block *self, unsigned long cmd, void *t) | |||
| 70 | * initialised state information on the first fault. | 70 | * initialised state information on the first fault. |
| 71 | */ | 71 | */ |
| 72 | 72 | ||
| 73 | case THREAD_NOTIFY_RELEASE: | 73 | case THREAD_NOTIFY_EXIT: |
| 74 | iwmmxt_task_release(thread); | 74 | iwmmxt_task_release(thread); |
| 75 | break; | 75 | break; |
| 76 | 76 | ||
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index aed05bc3c2ea..f60a5400a25b 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c | |||
| @@ -63,14 +63,15 @@ static void vfp_thread_flush(struct thread_info *thread) | |||
| 63 | put_cpu(); | 63 | put_cpu(); |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | static void vfp_thread_release(struct thread_info *thread) | 66 | static void vfp_thread_exit(struct thread_info *thread) |
| 67 | { | 67 | { |
| 68 | /* release case: Per-thread VFP cleanup. */ | 68 | /* release case: Per-thread VFP cleanup. */ |
| 69 | union vfp_state *vfp = &thread->vfpstate; | 69 | union vfp_state *vfp = &thread->vfpstate; |
| 70 | unsigned int cpu = thread->cpu; | 70 | unsigned int cpu = get_cpu(); |
| 71 | 71 | ||
| 72 | if (last_VFP_context[cpu] == vfp) | 72 | if (last_VFP_context[cpu] == vfp) |
| 73 | last_VFP_context[cpu] = NULL; | 73 | last_VFP_context[cpu] = NULL; |
| 74 | put_cpu(); | ||
| 74 | } | 75 | } |
| 75 | 76 | ||
| 76 | /* | 77 | /* |
| @@ -88,11 +89,13 @@ static void vfp_thread_release(struct thread_info *thread) | |||
| 88 | * but may change at any time. | 89 | * but may change at any time. |
| 89 | * - we could be preempted if tree preempt rcu is enabled, so | 90 | * - we could be preempted if tree preempt rcu is enabled, so |
| 90 | * it is unsafe to use thread->cpu. | 91 | * it is unsafe to use thread->cpu. |
| 91 | * THREAD_NOTIFY_RELEASE: | 92 | * THREAD_NOTIFY_EXIT |
| 92 | * - the thread (v) will not be running on any CPU; it is a dead thread. | 93 | * - the thread (v) will be running on the local CPU, so |
| 93 | * - thread->cpu will be the last CPU the thread ran on, which may not | 94 | * v === current_thread_info() |
| 94 | * be the current CPU. | 95 | * - thread->cpu is the local CPU number at the time it is accessed, |
| 95 | * - we could be preempted if tree preempt rcu is enabled. | 96 | * but may change at any time. |
| 97 | * - we could be preempted if tree preempt rcu is enabled, so | ||
| 98 | * it is unsafe to use thread->cpu. | ||
| 96 | */ | 99 | */ |
| 97 | static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v) | 100 | static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v) |
| 98 | { | 101 | { |
| @@ -133,7 +136,7 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v) | |||
| 133 | if (cmd == THREAD_NOTIFY_FLUSH) | 136 | if (cmd == THREAD_NOTIFY_FLUSH) |
| 134 | vfp_thread_flush(thread); | 137 | vfp_thread_flush(thread); |
| 135 | else | 138 | else |
| 136 | vfp_thread_release(thread); | 139 | vfp_thread_exit(thread); |
| 137 | 140 | ||
| 138 | return NOTIFY_DONE; | 141 | return NOTIFY_DONE; |
| 139 | } | 142 | } |
