diff options
author | George Anzinger <george@mvista.com> | 2005-09-03 18:56:48 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@evo.osdl.org> | 2005-09-05 03:06:13 -0400 |
commit | 748f2edb52712aa3d926470a888608dc500d17e8 (patch) | |
tree | 9fb37795934642e11bad0d747d1271df393a993d | |
parent | f2f30ebca6c0c95e987cb9a1fd1495770a75432e (diff) |
[PATCH] x86 NMI: better support for debuggers
This patch adds a notify to the die_nmi notify that the system is about to
be taken down. If the notify is handled with a NOTIFY_STOP return, the
system is given a new lease on life.
We also change the nmi watchdog to carry on if die_nmi returns.
This give debug code a chance to a) catch watchdog timeouts and b) possibly
allow the system to continue, realizing that the time out may be due to
debugger activities such as single stepping which is usually done with
"other" cpus held.
Signed-off-by: George Anzinger<george@mvista.com>
Cc: Keith Owens <kaos@ocs.com.au>
Signed-off-by: George Anzinger <george@mvista.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | arch/i386/kernel/nmi.c | 5 | ||||
-rw-r--r-- | arch/i386/kernel/traps.c | 4 | ||||
-rw-r--r-- | include/asm-i386/kdebug.h | 11 |
3 files changed, 17 insertions, 3 deletions
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index 8c242bb1ef45..8bbdbda07a2d 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c | |||
@@ -501,8 +501,11 @@ void nmi_watchdog_tick (struct pt_regs * regs) | |||
501 | */ | 501 | */ |
502 | alert_counter[cpu]++; | 502 | alert_counter[cpu]++; |
503 | if (alert_counter[cpu] == 5*nmi_hz) | 503 | if (alert_counter[cpu] == 5*nmi_hz) |
504 | /* | ||
505 | * die_nmi will return ONLY if NOTIFY_STOP happens.. | ||
506 | */ | ||
504 | die_nmi(regs, "NMI Watchdog detected LOCKUP"); | 507 | die_nmi(regs, "NMI Watchdog detected LOCKUP"); |
505 | } else { | 508 | |
506 | last_irq_sums[cpu] = sum; | 509 | last_irq_sums[cpu] = sum; |
507 | alert_counter[cpu] = 0; | 510 | alert_counter[cpu] = 0; |
508 | } | 511 | } |
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index b2b4bb890bb7..54629bb5893a 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c | |||
@@ -565,6 +565,10 @@ static DEFINE_SPINLOCK(nmi_print_lock); | |||
565 | 565 | ||
566 | void die_nmi (struct pt_regs *regs, const char *msg) | 566 | void die_nmi (struct pt_regs *regs, const char *msg) |
567 | { | 567 | { |
568 | if (notify_die(DIE_NMIWATCHDOG, msg, regs, 0, 0, SIGINT) == | ||
569 | NOTIFY_STOP) | ||
570 | return; | ||
571 | |||
568 | spin_lock(&nmi_print_lock); | 572 | spin_lock(&nmi_print_lock); |
569 | /* | 573 | /* |
570 | * We are in trouble anyway, lets at least try | 574 | * We are in trouble anyway, lets at least try |
diff --git a/include/asm-i386/kdebug.h b/include/asm-i386/kdebug.h index b3f8d5f59d5d..316138e89910 100644 --- a/include/asm-i386/kdebug.h +++ b/include/asm-i386/kdebug.h | |||
@@ -41,9 +41,16 @@ enum die_val { | |||
41 | DIE_PAGE_FAULT, | 41 | DIE_PAGE_FAULT, |
42 | }; | 42 | }; |
43 | 43 | ||
44 | static inline int notify_die(enum die_val val,char *str,struct pt_regs *regs,long err,int trap, int sig) | 44 | static inline int notify_die(enum die_val val, const char *str, |
45 | struct pt_regs *regs, long err, int trap, int sig) | ||
45 | { | 46 | { |
46 | struct die_args args = { .regs=regs, .str=str, .err=err, .trapnr=trap,.signr=sig }; | 47 | struct die_args args = { |
48 | .regs = regs, | ||
49 | .str = str, | ||
50 | .err = err, | ||
51 | .trapnr = trap, | ||
52 | .signr = sig | ||
53 | }; | ||
47 | return notifier_call_chain(&i386die_chain, val, &args); | 54 | return notifier_call_chain(&i386die_chain, val, &args); |
48 | } | 55 | } |
49 | 56 | ||