|
@@ -15,6 +15,8 @@
|
|
|
#include <linux/notifier.h>
|
|
|
#include <linux/module.h>
|
|
|
|
|
|
+#include <asm/irq_regs.h>
|
|
|
+
|
|
|
static DEFINE_SPINLOCK(print_lock);
|
|
|
|
|
|
static DEFINE_PER_CPU(unsigned long, touch_timestamp);
|
|
@@ -72,6 +74,7 @@ void softlockup_tick(void)
|
|
|
int this_cpu = smp_processor_id();
|
|
|
unsigned long touch_timestamp = per_cpu(touch_timestamp, this_cpu);
|
|
|
unsigned long print_timestamp;
|
|
|
+ struct pt_regs *regs = get_irq_regs();
|
|
|
unsigned long now;
|
|
|
|
|
|
if (touch_timestamp == 0) {
|
|
@@ -101,15 +104,18 @@ void softlockup_tick(void)
|
|
|
wake_up_process(per_cpu(watchdog_task, this_cpu));
|
|
|
|
|
|
/* Warn about unreasonable 10+ seconds delays: */
|
|
|
- if (now > (touch_timestamp + 10)) {
|
|
|
- per_cpu(print_timestamp, this_cpu) = touch_timestamp;
|
|
|
+ if (now <= (touch_timestamp + 10))
|
|
|
+ return;
|
|
|
|
|
|
- spin_lock(&print_lock);
|
|
|
- printk(KERN_ERR "BUG: soft lockup detected on CPU#%d!\n",
|
|
|
- this_cpu);
|
|
|
+ per_cpu(print_timestamp, this_cpu) = touch_timestamp;
|
|
|
+
|
|
|
+ spin_lock(&print_lock);
|
|
|
+ printk(KERN_ERR "BUG: soft lockup detected on CPU#%d!\n", this_cpu);
|
|
|
+ if (regs)
|
|
|
+ show_regs(regs);
|
|
|
+ else
|
|
|
dump_stack();
|
|
|
- spin_unlock(&print_lock);
|
|
|
- }
|
|
|
+ spin_unlock(&print_lock);
|
|
|
}
|
|
|
|
|
|
/*
|