File: /usr/src/linux/kernel/panic.c

1     /*
2      *  linux/kernel/panic.c
3      *
4      *  Copyright (C) 1991, 1992  Linus Torvalds
5      */
6     
7     /*
8      * This function is used through-out the kernel (including mm and fs)
9      * to indicate a major problem.
10      */
11     #include <linux/config.h>
12     #include <linux/sched.h>
13     #include <linux/delay.h>
14     #include <linux/reboot.h>
15     #include <linux/notifier.h>
16     #include <linux/init.h>
17     #include <linux/sysrq.h>
18     #include <linux/interrupt.h>
19     
20     asmlinkage void sys_sync(void);	/* it's really int */
21     
22     int panic_timeout;
23     
24     struct notifier_block *panic_notifier_list;
25     
26     static int __init panic_setup(char *str)
27     {
28     	panic_timeout = simple_strtoul(str, NULL, 0);
29     	return 1;
30     }
31     
32     __setup("panic=", panic_setup);
33     
34     /**
35      *	panic - halt the system
36      *	@fmt: The text string to print
37      *
38      *	Display a message, then perform cleanups. Functions in the panic
39      *	notifier list are called after the filesystem cache is flushed (when possible).
40      *
41      *	This function never returns.
42      */
43      
44     NORET_TYPE void panic(const char * fmt, ...)
45     {
46     	static char buf[1024];
47     	va_list args;
48     #if defined(CONFIG_ARCH_S390)
49             unsigned long caller = (unsigned long) __builtin_return_address(0);
50     #endif
51     
52     	bust_spinlocks(1);
53     	va_start(args, fmt);
54     	vsprintf(buf, fmt, args);
55     	va_end(args);
56     	printk(KERN_EMERG "Kernel panic: %s\n",buf);
57     	if (in_interrupt())
58     		printk(KERN_EMERG "In interrupt handler - not syncing\n");
59     	else if (!current->pid)
60     		printk(KERN_EMERG "In idle task - not syncing\n");
61     	else
62     		sys_sync();
63     	bust_spinlocks(0);
64     
65     #ifdef CONFIG_SMP
66     	smp_send_stop();
67     #endif
68     
69     	notifier_call_chain(&panic_notifier_list, 0, NULL);
70     
71     	if (panic_timeout > 0)
72     	{
73     		/*
74     	 	 * Delay timeout seconds before rebooting the machine. 
75     		 * We can't use the "normal" timers since we just panicked..
76     	 	 */
77     		printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout);
78     		mdelay(panic_timeout*1000);
79     		/*
80     		 *	Should we run the reboot notifier. For the moment Im
81     		 *	choosing not too. It might crash, be corrupt or do
82     		 *	more harm than good for other reasons.
83     		 */
84     		machine_restart(NULL);
85     	}
86     #ifdef __sparc__
87     	{
88     		extern int stop_a_enabled;
89     		/* Make sure the user can actually press L1-A */
90     		stop_a_enabled = 1;
91     		printk("Press L1-A to return to the boot prom\n");
92     	}
93     #endif
94     #if defined(CONFIG_ARCH_S390)
95             disabled_wait(caller);
96     #endif
97     	sti();
98     	for(;;) {
99     		CHECK_EMERGENCY_SYNC
100     	}
101     }
102