diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-08-12 11:49:53 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-08-12 11:49:53 -0400 |
commit | 96348852cf8ff5597a39e866838679b3a9a38947 (patch) | |
tree | a46ec9749b85d15a8312e18c15cfdf33d28c813b /kernel | |
parent | 1c89ac55017f982355c7761e1c912c88c941483d (diff) | |
parent | c2fc11985db304572322f1dcdcb0f71337315006 (diff) |
Merge branch 'core-fixes-for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'core-fixes-for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
generic-ipi: fix stack and rcu interaction bug in smp_call_function_mask(), fix
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/smp.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/kernel/smp.c b/kernel/smp.c index e6084f6efb4d..782e2b93e465 100644 --- a/kernel/smp.c +++ b/kernel/smp.c | |||
@@ -135,7 +135,8 @@ void generic_smp_call_function_interrupt(void) | |||
135 | */ | 135 | */ |
136 | smp_wmb(); | 136 | smp_wmb(); |
137 | data->csd.flags &= ~CSD_FLAG_WAIT; | 137 | data->csd.flags &= ~CSD_FLAG_WAIT; |
138 | } else | 138 | } |
139 | if (data->csd.flags & CSD_FLAG_ALLOC) | ||
139 | call_rcu(&data->rcu_head, rcu_free_call_data); | 140 | call_rcu(&data->rcu_head, rcu_free_call_data); |
140 | } | 141 | } |
141 | rcu_read_unlock(); | 142 | rcu_read_unlock(); |
@@ -289,10 +290,11 @@ static void smp_call_function_mask_quiesce_stack(cpumask_t mask) | |||
289 | 290 | ||
290 | data.func = quiesce_dummy; | 291 | data.func = quiesce_dummy; |
291 | data.info = NULL; | 292 | data.info = NULL; |
292 | data.flags = CSD_FLAG_WAIT; | ||
293 | 293 | ||
294 | for_each_cpu_mask(cpu, mask) | 294 | for_each_cpu_mask(cpu, mask) { |
295 | data.flags = CSD_FLAG_WAIT; | ||
295 | generic_exec_single(cpu, &data); | 296 | generic_exec_single(cpu, &data); |
297 | } | ||
296 | } | 298 | } |
297 | 299 | ||
298 | /** | 300 | /** |
@@ -371,7 +373,7 @@ int smp_call_function_mask(cpumask_t mask, void (*func)(void *), void *info, | |||
371 | if (wait) { | 373 | if (wait) { |
372 | csd_flag_wait(&data->csd); | 374 | csd_flag_wait(&data->csd); |
373 | if (unlikely(slowpath)) | 375 | if (unlikely(slowpath)) |
374 | smp_call_function_mask_quiesce_stack(allbutself); | 376 | smp_call_function_mask_quiesce_stack(mask); |
375 | } | 377 | } |
376 | 378 | ||
377 | return 0; | 379 | return 0; |