[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1261603190-5036-29-git-send-email-jason.wessel@windriver.com>
Date: Wed, 23 Dec 2009 15:19:41 -0600
From: Jason Wessel <jason.wessel@...driver.com>
To: linux-kernel@...r.kernel.org
Cc: kgdb-bugreport@...ts.sourceforge.net, kdb@....sgi.com,
mingo@...e.hu, Jason Wessel <jason.wessel@...driver.com>,
Andrew Morton <akpm@...ux-foundation.org>
Subject: [PATCH 28/37] kdb,panic,debug_core: Allow the debug core to receive a panic before smp_send_stop()
It is highly desirable to trap into kdb on panic, and in order
to do so the notifier must be called before smp_send_stop(),
else the debug_core will not be able to correctly trap
all the CPUs.
CC: Ingo Molnar <mingo@...e.hu>
CC: Andrew Morton <akpm@...ux-foundation.org>
Signed-off-by: Jason Wessel <jason.wessel@...driver.com>
---
include/linux/kdb.h | 1 +
kernel/debug/debug_core.c | 19 +++++++++++++++++++
kernel/panic.c | 7 ++++---
3 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/include/linux/kdb.h b/include/linux/kdb.h
index 387a916..3504c1c 100644
--- a/include/linux/kdb.h
+++ b/include/linux/kdb.h
@@ -114,5 +114,6 @@ extern void kdb_si_swapinfo(struct sysinfo *);
#else /* ! CONFIG_KGDB_KDB */
#define KDB_IS_RUNNING() (0)
+#define kdb_printf(...)
#endif /* CONFIG_KGDB_KDB */
#endif /* !_KDB_H */
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c
index e6c6f8a..b28a0a4 100644
--- a/kernel/debug/debug_core.c
+++ b/kernel/debug/debug_core.c
@@ -46,6 +46,7 @@
#include <linux/pid.h>
#include <linux/smp.h>
#include <linux/mm.h>
+#include <linux/kdb.h>
#include <asm/cacheflush.h>
#include <asm/byteorder.h>
@@ -750,11 +751,27 @@ static struct sysrq_key_op sysrq_dbg_op = {
};
#endif
+static int kgdb_panic_event(struct notifier_block *self,
+ unsigned long val,
+ void *data)
+{
+ if (dbg_kdb_mode)
+ kdb_printf("PANIC: %s\n", (char *)data);
+ kgdb_breakpoint();
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block kgdb_panic_event_nb = {
+ .notifier_call = kgdb_panic_event,
+};
+
static void kgdb_register_callbacks(void)
{
if (!kgdb_io_module_registered) {
kgdb_io_module_registered = 1;
kgdb_arch_init();
+ atomic_notifier_chain_register(&panic_notifier_list,
+ &kgdb_panic_event_nb);
#ifdef CONFIG_MAGIC_SYSRQ
register_sysrq_key('g', &sysrq_dbg_op);
#endif
@@ -774,6 +791,8 @@ static void kgdb_unregister_callbacks(void)
*/
if (kgdb_io_module_registered) {
kgdb_io_module_registered = 0;
+ atomic_notifier_chain_unregister(&panic_notifier_list,
+ &kgdb_panic_event_nb);
kgdb_arch_exit();
#ifdef CONFIG_MAGIC_SYSRQ
unregister_sysrq_key('g', &sysrq_dbg_op);
diff --git a/kernel/panic.c b/kernel/panic.c
index 5827f7b..1f4fb47 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -66,10 +66,13 @@ NORET_TYPE void panic(const char * fmt, ...)
*/
preempt_disable();
- bust_spinlocks(1);
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
+
+ atomic_notifier_call_chain(&panic_notifier_list, 0, buf);
+
+ bust_spinlocks(1);
printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf);
#ifdef CONFIG_DEBUG_BUGVERBOSE
dump_stack();
@@ -90,8 +93,6 @@ NORET_TYPE void panic(const char * fmt, ...)
*/
smp_send_stop();
- atomic_notifier_call_chain(&panic_notifier_list, 0, buf);
-
bust_spinlocks(0);
if (!panic_blink)
--
1.6.4.rc1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists