diff options
author | Alexander van Heukelum <heukelum@fastmail.fm> | 2008-10-22 06:00:12 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-22 08:00:25 -0400 |
commit | e4955cfd2f5c81eb708f55769aa60173f207fd63 (patch) | |
tree | 221da9ebb28c55e2b1705554692f982771564389 /arch/x86/kernel | |
parent | 10b14cb7eb7dd5bff8023f76a55c8ac20e586128 (diff) |
i386, dumpstack: use x86_64's method to account die_nest_count
oops_begin/oops_end should always be used in pairs. On x86_64
oops_begin increments die_nest_count, and oops_end decrements
die_nest_count. Doing this makes oops_begin and oops_end equal
to the x86_64 versions.
Signed-off-by: Alexander van Heukelum <heukelum@fastmail.fm>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/dumpstack_32.c | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c index a29b88ffa346..7c7d691b32be 100644 --- a/arch/x86/kernel/dumpstack_32.c +++ b/arch/x86/kernel/dumpstack_32.c | |||
@@ -289,21 +289,24 @@ static unsigned int die_nest_count; | |||
289 | 289 | ||
290 | unsigned __kprobes long oops_begin(void) | 290 | unsigned __kprobes long oops_begin(void) |
291 | { | 291 | { |
292 | int cpu; | ||
292 | unsigned long flags; | 293 | unsigned long flags; |
293 | 294 | ||
294 | oops_enter(); | 295 | oops_enter(); |
295 | 296 | ||
296 | if (die_owner != raw_smp_processor_id()) { | 297 | /* racy, but better than risking deadlock. */ |
297 | console_verbose(); | 298 | raw_local_irq_save(flags); |
298 | raw_local_irq_save(flags); | 299 | cpu = smp_processor_id(); |
299 | __raw_spin_lock(&die_lock); | 300 | if (!__raw_spin_trylock(&die_lock)) { |
300 | die_owner = smp_processor_id(); | 301 | if (cpu == die_owner) |
301 | die_nest_count = 0; | 302 | /* nested oops. should stop eventually */; |
302 | bust_spinlocks(1); | 303 | else |
303 | } else { | 304 | __raw_spin_lock(&die_lock); |
304 | raw_local_irq_save(flags); | ||
305 | } | 305 | } |
306 | die_nest_count++; | 306 | die_nest_count++; |
307 | die_owner = cpu; | ||
308 | console_verbose(); | ||
309 | bust_spinlocks(1); | ||
307 | return flags; | 310 | return flags; |
308 | } | 311 | } |
309 | 312 | ||
@@ -315,13 +318,15 @@ void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr) | |||
315 | bust_spinlocks(0); | 318 | bust_spinlocks(0); |
316 | die_owner = -1; | 319 | die_owner = -1; |
317 | add_taint(TAINT_DIE); | 320 | add_taint(TAINT_DIE); |
318 | __raw_spin_unlock(&die_lock); | 321 | die_nest_count--; |
322 | if (!die_nest_count) | ||
323 | /* Nest count reaches zero, release the lock. */ | ||
324 | __raw_spin_unlock(&die_lock); | ||
319 | raw_local_irq_restore(flags); | 325 | raw_local_irq_restore(flags); |
320 | |||
321 | oops_exit(); | 326 | oops_exit(); |
327 | |||
322 | if (!signr) | 328 | if (!signr) |
323 | return; | 329 | return; |
324 | |||
325 | if (in_interrupt()) | 330 | if (in_interrupt()) |
326 | panic("Fatal exception in interrupt"); | 331 | panic("Fatal exception in interrupt"); |
327 | if (panic_on_oops) | 332 | if (panic_on_oops) |