Commit 748f2edb52712aa3d926470a888608dc500d17e8

Authored by George Anzinger
Committed by Linus Torvalds
1 parent f2f30ebca6

[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>

Showing 3 changed files with 17 additions and 3 deletions Side-by-side Diff

arch/i386/kernel/nmi.c
... ... @@ -501,8 +501,11 @@
501 501 */
502 502 alert_counter[cpu]++;
503 503 if (alert_counter[cpu] == 5*nmi_hz)
  504 + /*
  505 + * die_nmi will return ONLY if NOTIFY_STOP happens..
  506 + */
504 507 die_nmi(regs, "NMI Watchdog detected LOCKUP");
505   - } else {
  508 +
506 509 last_irq_sums[cpu] = sum;
507 510 alert_counter[cpu] = 0;
508 511 }
arch/i386/kernel/traps.c
... ... @@ -565,6 +565,10 @@
565 565  
566 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 572 spin_lock(&nmi_print_lock);
569 573 /*
570 574 * We are in trouble anyway, lets at least try
include/asm-i386/kdebug.h
... ... @@ -41,9 +41,16 @@
41 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 54 return notifier_call_chain(&i386die_chain, val, &args);
48 55 }
49 56