kernel的panic()函数是否完全冻结了其他所有进程?

时间:2012-11-12 14:02:00

标签: linux kernel panic

我希望确认内核的panic()函数以及kernel_halt()machine_halt()之类的函数一旦被触发,就可以保证机器完全冻结。

那么,所有内核和用户进程都被冻结了吗?调度程序是否可以中断panic()?中断处理程序仍然可以执行吗?

使用案例:如果出现严重错误,我需要确保硬件看门狗重置机器。为此,我需要确保没有其他线程/进程使看门狗保持活动状态。我需要触发完全停止系统。目前,在我的内核模块中,我只需调用panic()来冻结所有内容。

此外,用户空间halt命令可以保证冻结系统吗?

感谢。

编辑:根据:http://linux.die.net/man/2/reboot,我认为最好的方法是使用reboot(LINUX_REBOOT_CMD_HALT):“对ROM监视器进行控制,如果有的话”

1 个答案:

答案 0 :(得分:10)

感谢您的上述评论。经过一些研究,我准备给自己一个更完整的答案,如下:

至少对于x86架构,reboot(LINUX_REBOOT_CMD_HALT)是可行的方法。反过来,这会调用系统调用reboot()(请参阅:http://lxr.linux.no/linux+v3.6.6/kernel/sys.c#L433)。然后,对于LINUX_REBOOT_CMD_HALT标志(请参阅:http://lxr.linux.no/linux+v3.6.6/kernel/sys.c#L480),系统调用调用kernel_halt()(在此处定义:http://lxr.linux.no/linux+v3.6.6/kernel/sys.c#L394)。该函数调用syscore_shutdown()来执行所有已注册的系统核心关闭回调,显示“System halted”消息,然后转储内核,最后,它调用machine_halt(),这是{{1}的包装器(参见:http://lxr.linux.no/linux+v3.6.6/arch/x86/kernel/reboot.c#L680)。正是这个函数停止了其他CPU(通过native_machine_halt()),然后调用machine_shutdown()来禁用最后剩余的工作处理器。这个函数的第一件事就是禁用当前处理器上的中断,即调度程序不再能够控制。

在调用stop_this_cpu()后,我不确定为什么系统调用reboot()仍然调用do_exit(0)。我这样理解:现在,所有处理器都标记为已禁用,系统调用kernel_halt()调用reboot()并结束自身。即使调度程序被唤醒,也没有更多启用的处理器可以调度某些任务,也不会中断:系统停止运行。我不确定这个解释,因为do_exit(0)似乎没有返回(它进入无限循环)。对于stop_this_cpu()失败(并返回)的情况,可能只是一个安全措施:在这种情况下,stop_this_cpu()将干净地结束当前任务,然后调用do_exit()函数。 / p>

对于panic()代码(在此定义:http://lxr.linux.no/linux+v3.6.6/kernel/panic.c#L69),该函数首先禁用本地中断,然后通过调用panic()禁用所有其他处理器,当前处理器除外。最后,作为在当前处理器上执行的唯一任务(唯一的处理器仍处于活动状态),禁用所有本地中断(即,可抢占调度程序 - 毕竟是计时器中断 - 没有机会...) ,然后smp_send_stop()函数循环一段时间或调用panic(),这应该重启处理器。

如果您有更好的见解,请提供帮助。