summaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/traps.c
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2006-12-07 02:14:02 +0100
committerAndi Kleen <andi@basil.nowhere.org>2006-12-07 02:14:02 +0100
commitda68933e0a999fb13636653c710cca701b457ad2 (patch)
tree16808c3d5074dd249a0fe11b513ec4e53ecdec9d /arch/x86_64/kernel/traps.c
parentbb0d977ed42c79ed709c79dbab4ff2159941eb2a (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>
Diffstat (limited to 'arch/x86_64/kernel/traps.c')
-rw-r--r--arch/x86_64/kernel/traps.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index eedd4e759c3..e37b4d77d5a 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,
unsigned long *stack,
struct stacktrace_ops *ops, void *data)
{
- const unsigned cpu = smp_processor_id();
+ const unsigned cpu = get_cpu();
unsigned long *irqstack_end = (unsigned long*)cpu_pda(cpu)->irqstackptr;
unsigned used = 0;
struct thread_info *tinfo;
@@ -286,11 +286,11 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
MSG("Leftover inexact backtrace:");
stack = (unsigned long *)UNW_SP(&info);
if (!stack)
- return;
+ goto out;
} else
MSG("Full inexact backtrace again:");
} else if (call_trace >= 1)
- return;
+ goto out;
else
MSG("Full inexact backtrace again:");
} else
@@ -385,6 +385,8 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
tinfo = current_thread_info();
HANDLE_STACK (valid_stack_ptr(tinfo, stack));
#undef HANDLE_STACK
+out:
+ put_cpu();
}
EXPORT_SYMBOL(dump_trace);