From: Keith Owens <kaos@sgi.com>
To: linux-arch@vger.kernel.org
Cc: Keith Owens <kaos@sgi.com>
Subject: [patch 2.6.19-rc5 11/12] crash_stop: demonstration code
Date: Thu, 09 Nov 2006 15:05:20 +1100 [thread overview]
Message-ID: <20061109040520.17391.74072.sendpatchset@chook.melbourne.sgi.com> (raw)
In-Reply-To: <20061109040418.17391.16362.sendpatchset@chook.melbourne.sgi.com>
A quick and dirty crash_stop() demo program.
Notice that this demo is almost completely architecture independent.
It has no code to do per architecture IPI/NMI, nor does it need to save
any per cpu state - all of that is handled by the common code. IOW, a
debug style tool can concentrate on its own requirements, leaving all
the complicated code to the crash_stop API.
The base patch does not export any crash_stop() symbols. They can be
added later if any debug style code can be installed in a module.
Since the demo is best used as a module, this patch temporarilly
exports some symbols.
No signed-off-by, this code is not going into the kernel.
---
kernel/Makefile | 1
kernel/crash_stop.c | 6 +-
kernel/crash_stop_demo.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++
lib/Kconfig.debug | 11 +++
4 files changed, 151 insertions(+), 1 deletion(-)
Index: linux/kernel/Makefile
===================================================================
--- linux.orig/kernel/Makefile
+++ linux/kernel/Makefile
@@ -52,6 +52,7 @@ obj-$(CONFIG_UTS_NS) += utsname.o
obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o
obj-$(CONFIG_CRASH_STOP_SUPPORTED) += crash_stop.o
+obj-$(CONFIG_CRASH_STOP_DEMO) += crash_stop_demo.o
ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
# According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
Index: linux/kernel/crash_stop.c
===================================================================
--- linux.orig/kernel/crash_stop.c
+++ linux/kernel/crash_stop.c
@@ -197,6 +197,7 @@
#include <linux/crash_stop.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
+#include <linux/module.h> /* used by crash_stop_demo */
#include <linux/ptrace.h>
#include <linux/nmi.h>
#include <linux/spinlock.h>
@@ -335,7 +336,7 @@ retry:
set_mb(cs_notify_chain_owner, cpu);
set_mb(cs_lock_owner, -1);
spin_unlock(&cs_lock);
- crash_stop(cs_notify_callback, NULL, NULL, regs, __FUNCTION__);
+ crash_stop(cs_notify_callback, NULL, printk, regs, __FUNCTION__);
}
/* Called by the arch specific crash_stop code, when they reach the end of a
@@ -463,6 +464,7 @@ crash_stop_sent_nmi(void)
{
return cpu_isset(smp_processor_id(), cs_sent_nmi);
}
+EXPORT_SYMBOL(crash_stop_sent_nmi); /* used by crash_stop_demo */
#endif /* CONFIG_SMP */
/* Should only be called by the arch specific crash_stop code, after they have
@@ -752,6 +754,7 @@ retry:
set_mb(cs_leaving, 0);
return 0;
}
+EXPORT_SYMBOL(crash_stop); /* used by crash_stop_demo */
/**
* crash_stop_recovered: - Release any slaves in crash_stop state.
@@ -841,3 +844,4 @@ crash_stop_slaves(void)
else
return 0;
}
+EXPORT_SYMBOL(crash_stop_slaves); /* used by crash_stop_demo */
Index: linux/kernel/crash_stop_demo.c
===================================================================
--- /dev/null
+++ linux/kernel/crash_stop_demo.c
@@ -0,0 +1,134 @@
+/*
+ * linux/kernel/crash_stop_demo.c
+ *
+ * Copyright (C) 2006 Keith Owens <kaos@sgi.com>
+ *
+ * Demonstrate the use of crash_stop() by debug style code.
+ */
+
+#include <linux/crash_stop.h>
+#include <linux/module.h>
+#include <linux/nmi.h>
+#include <asm/kdebug.h>
+
+MODULE_LICENSE("GPL");
+
+/* The callback function passed to crash_stop() is invoked on each cpu that is
+ * in crash_stop state. The main crash_stop() code will ensure that slaves are
+ * entered first, followed by the monarch after a short delay. The debug
+ * specific callback then does its own work.
+ */
+
+static int cs_demo_monarch_entered, cs_demo_monarch_exited;
+atomic_t slave_count;
+
+static void
+cs_demo_callback_monarch(void *data) {
+ printk("%s: entering monarch cpu %d\n",
+ __FUNCTION__, smp_processor_id());
+ if (cs_demo_monarch_entered) {
+ printk("%s: recursive call detected\n", __FUNCTION__);
+ return;
+ }
+ set_mb(cs_demo_monarch_entered, 1);
+ /* wait for all the slaves to enter */
+ while (atomic_read(&slave_count) != crash_stop_slaves()) {
+ touch_nmi_watchdog();
+ cpu_relax();
+ }
+
+ /* Monarch callback processing using data and struct
+ * crash_stop_running_process goes here.
+ */
+
+ set_mb(cs_demo_monarch_exited, 1);
+ /* wait for all the slaves to leave */
+ while (atomic_read(&slave_count)) {
+ touch_nmi_watchdog();
+ cpu_relax();
+ }
+ /* reset state for next entry */
+ set_mb(cs_demo_monarch_entered, 0);
+ set_mb(cs_demo_monarch_exited, 0);
+}
+
+static void
+cs_demo_callback_slave(void *data) {
+ printk("%s: entering slave cpu %d via %s\n",
+ __FUNCTION__, smp_processor_id(),
+ crash_stop_sent_nmi() ? "NMI" : "IPI");
+ atomic_inc(&slave_count);
+ while (!cs_demo_monarch_entered) {
+ touch_nmi_watchdog();
+ cpu_relax();
+ }
+ /* Slave callback processing using data goes here. In most cases the
+ * slaves will just spin until the monarch releases them. The main
+ * crash_stop() code saves the state for each slave cpu before entering
+ * the callback. The monarch can used that saved state without the
+ * callback on the slave cpu doing any more work.
+ */
+ while (!cs_demo_monarch_exited) {
+ touch_nmi_watchdog();
+ cpu_relax();
+ }
+ atomic_dec(&slave_count);
+}
+
+static void
+cs_demo_callback(int monarch, void *data)
+{
+ if (monarch)
+ cs_demo_callback_monarch(data);
+ else
+ cs_demo_callback_slave(data);
+ printk("%s: leaving cpu %d\n",
+ __FUNCTION__, smp_processor_id());
+}
+
+/* Handle various kernel error conditions. */
+static int
+cs_demo_notify(struct notifier_block *self,
+ unsigned long val, void *data)
+{
+ struct die_args *args = data;
+ switch(val) {
+#ifdef CONFIG_X86
+ case DIE_NMIWATCHDOG:
+#endif
+#ifdef CONFIG_IA64
+ case DIE_MCA_MONARCH_LEAVE:
+ case DIE_INIT_MONARCH_LEAVE:
+#endif
+ case DIE_OOPS:
+ crash_stop(cs_demo_callback, NULL, printk, args->regs, __FUNCTION__);
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block cs_demo_nb = {
+ .notifier_call = cs_demo_notify,
+ .priority = 100,
+};
+
+static int __init
+cs_demo_init(void)
+{
+ int err;
+ if ((err = register_die_notifier(&cs_demo_nb))) {
+ printk(KERN_ERR "%s: failed to register cs_demo_nb\n",
+ __FUNCTION__);
+ return err;
+ }
+ return 0;
+}
+
+static void __exit
+cs_demo_exit(void)
+{
+ unregister_die_notifier(&cs_demo_nb);
+}
+
+module_init(cs_demo_init)
+module_exit(cs_demo_exit)
Index: linux/lib/Kconfig.debug
===================================================================
--- linux.orig/lib/Kconfig.debug
+++ linux/lib/Kconfig.debug
@@ -419,3 +419,14 @@ config CRASH_STOP
config CRASH_STOP_SUPPORTED
bool
+
+config CRASH_STOP_DEMO
+ tristate "Demonstrate the use of crash_stop"
+ default m
+ select CRASH_STOP
+ help
+ Code to demonstrate the use of crash_stop. Build it as a
+ module and load it. It will make one cpu spin disabled then
+ call crash_stop. All slave cpus bar one will get a normal
+ IPI, the spinning cpu will get NMI. You need at least 3 cpus
+ to run crash_stop_demo.
next prev parent reply other threads:[~2006-11-09 4:05 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-11-09 4:04 [patch 2.6.19-rc5 0/12] crash_stop: Summary Keith Owens
2006-11-09 4:04 ` [patch 2.6.19-rc5 1/12] crash_stop: common header Keith Owens
2006-11-09 4:04 ` [patch 2.6.19-rc5 2/12] crash_stop: common code Keith Owens
2006-11-09 4:04 ` [patch 2.6.19-rc5 3/12] crash_stop: i386 interrupt handlers Keith Owens
2006-11-09 4:04 ` [patch 2.6.19-rc5 4/12] crash_stop: i386 specific code Keith Owens
2006-11-09 4:04 ` [patch 2.6.19-rc5 5/12] crash_stop: add DIE_NMIWATCHDOG to x86_64 Keith Owens
2006-11-09 4:04 ` [patch 2.6.19-rc5 6/12] crash_stop: x86_64 interrupt handlers Keith Owens
2006-11-09 4:04 ` [patch 2.6.19-rc5 7/12] crash_stop: x86_64 specific code Keith Owens
2006-11-09 4:05 ` [patch 2.6.19-rc5 8/12] crash_stop: ia64 interrupt handlers Keith Owens
2006-11-09 4:05 ` [patch 2.6.19-rc5 9/12] crash_stop: ia64 specific code Keith Owens
2006-11-09 4:05 ` [patch 2.6.19-rc5 10/12] crash_stop: add to config system Keith Owens
2006-11-09 4:05 ` Keith Owens [this message]
2006-11-09 4:05 ` [patch 2.6.19-rc5 12/12] crash_stop: test code Keith Owens
2006-11-11 1:45 ` [patch 2.6.19-rc5 0/12] crash_stop: Summary Vivek Goyal
2006-11-13 2:08 ` Keith Owens
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20061109040520.17391.74072.sendpatchset@chook.melbourne.sgi.com \
--to=kaos@sgi.com \
--cc=linux-arch@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.