Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1189703 > unrolled thread
| Started by | Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com> |
|---|---|
| First post | 2015-07-22 09:40 +0200 |
| Last post | 2015-07-23 10:20 +0200 |
| Articles | 2 — 2 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
[PATCH 1/3] x86/panic: Fix re-entrance problem due to panic on NMI Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com> - 2015-07-22 09:40 +0200
Re: [PATCH 1/3] x86/panic: Fix re-entrance problem due to panic on NMI Peter Zijlstra <peterz@infradead.org> - 2015-07-23 10:20 +0200
| From | Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com> |
|---|---|
| Date | 2015-07-22 09:40 +0200 |
| Subject | [PATCH 1/3] x86/panic: Fix re-entrance problem due to panic on NMI |
| Message-ID | <pOWNc-d3-9@gated-at.bofh.it> |
If panic on NMI happens just after panic() on the same CPU, panic()
is recursively called. As the result, it stalls on panic_lock.
To avoid this problem, don't call panic() in NMI context if
we've already entered panic() (i.e. we hold panic_lock).
Signed-off-by: Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Peter Zijlstra <peterz@infradead.org>
---
arch/x86/kernel/nmi.c | 18 ++++++++++++------
include/linux/kernel.h | 4 ++++
kernel/panic.c | 33 +++++++++++++++++++++++++--------
3 files changed, 41 insertions(+), 14 deletions(-)
diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c
index d05bd2e..c14b23f 100644
--- a/arch/x86/kernel/nmi.c
+++ b/arch/x86/kernel/nmi.c
@@ -230,8 +230,8 @@ void unregister_nmi_handler(unsigned int type, const char *name)
}
#endif
- if (panic_on_unrecovered_nmi)
- panic("NMI: Not continuing");
+ if (panic_on_unrecovered_nmi && spin_trylock(&panic_lock))
+ __panic("NMI: Not continuing");
pr_emerg("Dazed and confused, but trying to continue\n");
@@ -255,8 +255,12 @@ void unregister_nmi_handler(unsigned int type, const char *name)
reason, smp_processor_id());
show_regs(regs);
- if (panic_on_io_nmi)
- panic("NMI IOCK error: Not continuing");
+ if (panic_on_io_nmi) {
+ if (spin_trylock(&panic_lock))
+ __panic("NMI IOCK error: Not continuing");
+ else
+ return; /* We don't want to wait and re-enable NMI */
+ }
/* Re-enable the IOCK line, wait for a few seconds */
reason = (reason & NMI_REASON_CLEAR_MASK) | NMI_REASON_CLEAR_IOCHK;
@@ -296,8 +300,10 @@ void unregister_nmi_handler(unsigned int type, const char *name)
reason, smp_processor_id());
pr_emerg("Do you have a strange power saving mode enabled?\n");
- if (unknown_nmi_panic || panic_on_unrecovered_nmi)
- panic("NMI: Not continuing");
+ if (unknown_nmi_panic || panic_on_unrecovered_nmi) {
+ if (spin_trylock(&panic_lock))
+ __panic("NMI: Not continuing");
+ }
pr_emerg("Dazed and confused, but trying to continue\n");
}
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 5582410..be430dc 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -250,11 +250,15 @@ static inline u32 reciprocal_scale(u32 val, u32 ep_ro)
static inline void might_fault(void) { }
#endif
+typedef struct spinlock spinlock_t;
+extern spinlock_t panic_lock;
extern struct atomic_notifier_head panic_notifier_list;
extern long (*panic_blink)(int state);
__printf(1, 2)
void panic(const char *fmt, ...)
__noreturn __cold;
+void __panic(char *msg)
+ __noreturn __cold;
extern void oops_enter(void);
extern void oops_exit(void);
void print_oops_end_marker(void);
diff --git a/kernel/panic.c b/kernel/panic.c
index 04e91ff..3c8338b 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -60,6 +60,8 @@ void __weak panic_smp_self_stop(void)
cpu_relax();
}
+DEFINE_SPINLOCK(panic_lock);
+
/**
* panic - halt the system
* @fmt: The text string to print
@@ -70,11 +72,8 @@ void __weak panic_smp_self_stop(void)
*/
void panic(const char *fmt, ...)
{
- static DEFINE_SPINLOCK(panic_lock);
static char buf[1024];
va_list args;
- long i, i_next = 0;
- int state = 0;
/*
* Disable local interrupts. This will prevent panic_smp_self_stop
@@ -97,12 +96,30 @@ void panic(const char *fmt, ...)
if (!spin_trylock(&panic_lock))
panic_smp_self_stop();
- console_verbose();
- bust_spinlocks(1);
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
- pr_emerg("Kernel panic - not syncing: %s\n", buf);
+
+ __panic(buf);
+}
+
+/**
+ * __panic - no lock version of panic
+ * @msg: The text string to print
+ *
+ * Normally, please use panic(). This function can be used
+ * only if panic_lock has already been held.
+ *
+ * This function never returns.
+ */
+void __panic(char *msg)
+{
+ long i, i_next = 0;
+ int state = 0;
+
+ console_verbose();
+ bust_spinlocks(1);
+ pr_emerg("Kernel panic - not syncing: %s\n", msg);
#ifdef CONFIG_DEBUG_BUGVERBOSE
/*
* Avoid nested stack-dumping if a panic occurs during oops processing
@@ -131,7 +148,7 @@ void panic(const char *fmt, ...)
* Run any panic handlers, including those that might need to
* add information to the kmsg dump output.
*/
- atomic_notifier_call_chain(&panic_notifier_list, 0, buf);
+ atomic_notifier_call_chain(&panic_notifier_list, 0, msg);
kmsg_dump(KMSG_DUMP_PANIC);
@@ -190,7 +207,7 @@ void panic(const char *fmt, ...)
disabled_wait(caller);
}
#endif
- pr_emerg("---[ end Kernel panic - not syncing: %s\n", buf);
+ pr_emerg("---[ end Kernel panic - not syncing: %s\n", msg);
local_irq_enable();
for (i = 0; ; i += PANIC_TIMER_STEP) {
touch_softlockup_watchdog();
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2015-07-23 10:20 +0200 |
| Subject | Re: [PATCH 1/3] x86/panic: Fix re-entrance problem due to panic on NMI |
| Message-ID | <pPjTr-11y-11@gated-at.bofh.it> |
| In reply to | #1189703 |
On Wed, Jul 22, 2015 at 11:14:21AM +0900, Hidehiro Kawai wrote: > +DEFINE_SPINLOCK(panic_lock); At the very least this should be a raw spinlock, but wth aren't you using a simple atomic_xchg() ? -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web