- /**
-
* panic - halt the system
-
* @fmt: The text string to print
-
*
-
* Display a message, then perform cleanups.
-
*
-
* This function never returns.
-
*/
-
NORET_TYPE void panic(const char * fmt, ...)
-
{
-
static char buf[1024];
-
va_list args;
-
long i, i_next = 0;
-
int state = 0;
-
-
/*
-
* It's possible to come here directly from a panic-assertion and
-
* not have preempt disabled. Some functions called from here want
-
* preempt to be disabled. No point enabling it later though...
-
*/
- /**
- * 英文注释已经很清晰啦,就是在panic执行过程CPU不能被抢占。
- */
-
preempt_disable();
- /**
- * 修改console 级别,以便printk能把消息打印出来。
- */
-
console_verbose();
- /*
- * Unlock any spinlocks which will prevent
- * us from getting the
- message out.
- * 英文注释没有看多大明白啊,大概意思好像是抑制打印。
- */
-
bust_spinlocks(1);
-
va_start(args, fmt);
-
vsnprintf(buf, sizeof(buf), fmt, args);
-
va_end(args);
-
printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf);
-
#ifdef CONFIG_DEBUG_BUGVERBOSE
-
dump_stack();
-
#endif
-
-
/*
-
* If we have crashed and we have a crash kernel loaded let it handle
-
* everything else.
-
* Do we want to call this before we try to display a message?
-
*/
-
crash_kexec(NULL);
-
/××
- × 应该主要是dump CPU寄存器的状态值已经一些堆栈的信息。
- ×/
-
kmsg_dump(KMSG_DUMP_PANIC);
-
-
/*
-
* Note smp_send_stop is the usual smp shutdown function, which
-
* unfortunately means it may not be hardened to work in a panic
-
* situation.
-
*/
-
smp_send_stop();
- /××
- × 调用注册到panic时需要特殊处理的函数,如kgdb调试的入口等,
- ×/
-
atomic_notifier_call_chain(&panic_notifier_list, 0, buf);
-
-
bust_spinlocks(0);
-
-
if (!panic_blink)
-
panic_blink = no_blink;
/**
* 如果sysctl配置了panic_timeout > 0则在panic_timeout后重 * 启系统
*/
-
if (panic_timeout > 0) {
-
/*
-
* 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 * 1000; i += PANIC_TIMER_STEP) {
-
touch_nmi_watchdog();
-
if (i >= i_next) {
-
i += panic_blink(state ^= 1);
-
i_next = i + 3600 / PANIC_BLINK_SPD;
-
}
-
mdelay(PANIC_TIMER_STEP);
-
}
-
/*
-
* This will not be a clean reboot, with everything
-
* shutting down. But if there is a chance of
-
* rebooting the system it will be rebooted.
-
*/
-
emergency_restart();
-
}
-
#ifdef __sparc__
-
{
-
extern int stop_a_enabled;
-
/* Make sure the user can actually press Stop-A (L1-A) */
-
stop_a_enabled = 1;
-
printk(KERN_EMERG "Press Stop-A (L1-A) to return to the boot prom\n");
-
}
-
#endif
-
#if defined(CONFIG_S390)
-
{
-
unsigned long caller;
-
-
caller = (unsigned long)__builtin_return_address(0);
-
disabled_wait(caller);
-
}
-
#endif
-
local_irq_enable();
- /**
- * 进行死循环,抢占被禁止,CPU一直运行panic程序中运行。
- */
-
for (i = 0; ; i += PANIC_TIMER_STEP) {
-
touch_softlockup_watchdog();
-
if (i >= i_next) {
-
i += panic_blink(state ^= 1);
-
i_next = i + 3600 / PANIC_BLINK_SPD;
-
}
-
mdelay(PANIC_TIMER_STEP);
-
}
-
}