From: Michael Sundius <msundius@cisco.com>
To: linux-kernel@vger.kernel.org, msundius@sundius.com, msundius@cisco.com
Subject: [patch] delay panic during startup of kernel
Date: Wed, 21 Oct 2009 16:38:32 -0700 [thread overview]
Message-ID: <4ADF9B78.4060807@cisco.com> (raw)
We've been, from time to time, running into various problems early on
the initialization of the kernel, encountering situations where we really
should panic, but we can't because its too early to do so.
(see * if you care to know why this is a problem for us). Anyhow, I've
created this patch to have a little better way of orderly finishing the
bring-up to the point where we can panic safely. Any comments?
*One reason this often happens to us is that we have added hooks
for our drivers to allocate contiguous blocks of memory very early and
our driver team doesn't always communicate when changes have been
made.
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index f4e3184..b2e7bac 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -163,6 +163,10 @@ extern struct atomic_notifier_head panic_notifier_list;
extern long (*panic_blink)(long time);
NORET_TYPE void panic(const char * fmt, ...)
__attribute__ ((NORET_AND format (printf, 1, 2))) __cold;
+extern void panic_later(const char * fmt, ...)
+ __attribute__ ((format (printf, 1, 2)));
+extern void panic_later_complete(void);
+extern bool panic_later_pending(void);
extern void oops_enter(void);
extern void oops_exit(void);
extern int oops_may_print(void);
diff --git a/init/main.c b/init/main.c
index 5988deb..2a9347a 100644
--- a/init/main.c
+++ b/init/main.c
@@ -185,7 +185,6 @@ __setup("reset_devices", set_reset_devices);
static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
-static const char *panic_later, *panic_param;
extern struct obs_kernel_param __setup_start[], __setup_end[];
@@ -281,7 +280,7 @@ static int __init unknown_bootoption(char *param,
char *val)
return 0;
}
- if (panic_later)
+ if (panic_later_pending())
return 0;
if (val) {
@@ -289,8 +288,7 @@ static int __init unknown_bootoption(char *param,
char *val)
unsigned int i;
for (i = 0; envp_init[i]; i++) {
if (i == MAX_INIT_ENVS) {
- panic_later = "Too many boot env vars at
`%s'";
- panic_param = param;
+ panic_later("Too many boot env vars at
`%s'", param);
}
if (!strncmp(param, envp_init[i], val - param))
break;
@@ -301,8 +299,7 @@ static int __init unknown_bootoption(char *param,
char *val)
unsigned int i;
for (i = 0; argv_init[i]; i++) {
if (i == MAX_INIT_ARGS) {
- panic_later = "Too many boot init vars
at `%s'";
- panic_param = param;
+ panic_later("Too many boot init vars at
`%s'", param);
}
}
argv_init[i] = param;
@@ -621,8 +618,7 @@ asmlinkage void __init start_kernel(void)
* this. But we do want output early, in case something goes wrong.
*/
console_init();
- if (panic_later)
- panic(panic_later, panic_param);
+ panic_later_complete();
lockdep_info();
diff --git a/kernel/panic.c b/kernel/panic.c
index 96b45d0..092bb46 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -23,6 +23,9 @@
#include <linux/nmi.h>
#include <linux/dmi.h>
+#define MAX_PANIC_LATER_LEN 1024
+static char panic_later_msg[MAX_PANIC_LATER_LEN];
+
int panic_on_oops;
static unsigned long tainted_mask;
static int pause_on_oops;
@@ -40,6 +43,28 @@ static long no_blink(long time)
return 0;
}
+void panic_later(const char *fmt, ...)
+{
+ va_list args;
+
+ if (!panic_later_pending()) {
+ va_start(args, fmt);
+ vsnprintf(panic_later_msg, sizeof(panic_later_msg), fmt,
args);
+ va_end(args);
+ }
+}
+
+bool panic_later_pending()
+{
+ return panic_later_msg[0] != 0;
+}
+
+void panic_later_complete()
+{
+ if (panic_later_pending())
+ panic("%s", panic_later_msg);
+}
+
/* Returns how long it waited in ms */
long (*panic_blink)(long time);
EXPORT_SYMBOL(panic_blink);
next reply other threads:[~2009-10-21 23:38 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-10-21 23:38 Michael Sundius [this message]
2009-10-26 8:41 ` [patch] delay panic during startup of kernel Andi Kleen
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=4ADF9B78.4060807@cisco.com \
--to=msundius@cisco.com \
--cc=linux-kernel@vger.kernel.org \
--cc=msundius@sundius.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox