X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=kernel%2Fpanic.c;h=3f93784a4207300283552b643f3b67bf19890757;hb=4b659086703c3cfdabfc916b517590ad55d1ddfa;hp=3c1581eb65bd24fdf2581e63f1f9469b707f2cef;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/kernel/panic.c b/kernel/panic.c index 3c1581eb6..3f93784a4 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -37,6 +36,15 @@ static int __init panic_setup(char *str) } __setup("panic=", panic_setup); +static long no_blink(long time) +{ + return 0; +} + +/* Returns how long it waited in ms */ +long (*panic_blink)(long time); +EXPORT_SYMBOL(panic_blink); + /** * panic - halt the system * @fmt: The text string to print @@ -49,6 +57,7 @@ __setup("panic=", panic_setup); NORET_TYPE void panic(const char * fmt, ...) { + long i; static char buf[1024]; va_list args; #if defined(CONFIG_ARCH_S390) @@ -59,32 +68,30 @@ NORET_TYPE void panic(const char * fmt, ...) va_start(args, fmt); vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); - printk(KERN_EMERG "Kernel panic: %s\n",buf); - if (in_interrupt()) - printk(KERN_EMERG "In interrupt handler - not syncing\n"); - else if (!current->pid) - printk(KERN_EMERG "In idle task - not syncing\n"); - else - sys_sync(); + printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf); bust_spinlocks(0); #ifdef CONFIG_SMP smp_send_stop(); #endif - notifier_call_chain(&panic_notifier_list, 0, buf); + notifier_call_chain(&panic_notifier_list, 0, buf); + + if (!panic_blink) + panic_blink = no_blink; if (panic_timeout > 0) { - int i; /* * Delay timeout seconds before rebooting the machine. * We can't use the "normal" timers since we just panicked.. */ printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout); - for (i = 0; i < panic_timeout; i++) { + for (i = 0; i < panic_timeout*1000; ) { touch_nmi_watchdog(); - mdelay(1000); + i += panic_blink(i); + mdelay(1); + i++; } /* * Should we run the reboot notifier. For the moment Im @@ -105,8 +112,11 @@ NORET_TYPE void panic(const char * fmt, ...) disabled_wait(caller); #endif local_irq_enable(); - for (;;) - ; + for (i = 0;;) { + i += panic_blink(i); + mdelay(1); + i++; + } } EXPORT_SYMBOL(panic); @@ -117,6 +127,9 @@ EXPORT_SYMBOL(panic); * 'P' - Proprietary module has been loaded. * 'F' - Module has been forcibly loaded. * 'S' - SMP with CPUs not designed for SMP. + * 'R' - User forced a module unload. + * 'M' - Machine had a machine check experience. + * 'B' - System has hit bad_page. * * The string is overwritten by the next call to print_taint(). */ @@ -125,12 +138,21 @@ const char *print_tainted(void) { static char buf[20]; if (tainted) { - snprintf(buf, sizeof(buf), "Tainted: %c%c%c", + snprintf(buf, sizeof(buf), "Tainted: %c%c%c%c%c%c", tainted & TAINT_PROPRIETARY_MODULE ? 'P' : 'G', tainted & TAINT_FORCED_MODULE ? 'F' : ' ', - tainted & TAINT_UNSAFE_SMP ? 'S' : ' '); + tainted & TAINT_UNSAFE_SMP ? 'S' : ' ', + tainted & TAINT_FORCED_RMMOD ? 'R' : ' ', + tainted & TAINT_MACHINE_CHECK ? 'M' : ' ', + tainted & TAINT_BAD_PAGE ? 'B' : ' '); } else snprintf(buf, sizeof(buf), "Not tainted"); return(buf); } + +void add_taint(unsigned flag) +{ + tainted |= flag; +} +EXPORT_SYMBOL(add_taint);