diff options
author | Andrew Morton <akpm@osdl.org> | 2006-12-06 20:14:02 -0500 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2006-12-06 20:14:02 -0500 |
commit | da68933e0a999fb13636653c710cca701b457ad2 (patch) | |
tree | 16808c3d5074dd249a0fe11b513ec4e53ecdec9d | |
parent | bb0d977ed42c79ed709c79dbab4ff2159941eb2a (diff) |
[PATCH] x86-64: dump_trace() atomicity fix
Fix
BUG: using smp_processor_id() in preemptible [00000001] code:
in backtracer on preemptible debug kernels.
Cc: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Andi Kleen <ak@suse.de>
-rw-r--r-- | arch/x86_64/kernel/traps.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index eedd4e759c3a..e37b4d77d5a8 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c | |||
@@ -254,7 +254,7 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, | |||
254 | unsigned long *stack, | 254 | unsigned long *stack, |
255 | struct stacktrace_ops *ops, void *data) | 255 | struct stacktrace_ops *ops, void *data) |
256 | { | 256 | { |
257 | const unsigned cpu = smp_processor_id(); | 257 | const unsigned cpu = get_cpu(); |
258 | unsigned long *irqstack_end = (unsigned long*)cpu_pda(cpu)->irqstackptr; | 258 | unsigned long *irqstack_end = (unsigned long*)cpu_pda(cpu)->irqstackptr; |
259 | unsigned used = 0; | 259 | unsigned used = 0; |
260 | struct thread_info *tinfo; | 260 | struct thread_info *tinfo; |
@@ -286,11 +286,11 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, | |||
286 | MSG("Leftover inexact backtrace:"); | 286 | MSG("Leftover inexact backtrace:"); |
287 | stack = (unsigned long *)UNW_SP(&info); | 287 | stack = (unsigned long *)UNW_SP(&info); |
288 | if (!stack) | 288 | if (!stack) |
289 | return; | 289 | goto out; |
290 | } else | 290 | } else |
291 | MSG("Full inexact backtrace again:"); | 291 | MSG("Full inexact backtrace again:"); |
292 | } else if (call_trace >= 1) | 292 | } else if (call_trace >= 1) |
293 | return; | 293 | goto out; |
294 | else | 294 | else |
295 | MSG("Full inexact backtrace again:"); | 295 | MSG("Full inexact backtrace again:"); |
296 | } else | 296 | } else |
@@ -385,6 +385,8 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, | |||
385 | tinfo = current_thread_info(); | 385 | tinfo = current_thread_info(); |
386 | HANDLE_STACK (valid_stack_ptr(tinfo, stack)); | 386 | HANDLE_STACK (valid_stack_ptr(tinfo, stack)); |
387 | #undef HANDLE_STACK | 387 | #undef HANDLE_STACK |
388 | out: | ||
389 | put_cpu(); | ||
388 | } | 390 | } |
389 | EXPORT_SYMBOL(dump_trace); | 391 | EXPORT_SYMBOL(dump_trace); |
390 | 392 | ||