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 | } |