Linux内核中如何产生软锁定以及如何验证?

Linux内核中如何产生软锁定以及如何验证?

我正在测试 Linux 内核的软锁定恢复过程。我将 /proc/sys/kernel/softlockup_panic 设置为 1。

我创建了一个内核模块,如下面的链接所述。https://github.com/saiyamd/softlockup_test

当我插入模块时,我的 Linux 系统在短暂挂起后重新启动。如果我将 /proc/sys/kernel/softloup_panic 设置为 0。我的 Linux 系统仍然挂起并且从未重新启动。似乎发生软锁定时重新启动的方案有效,但我看不到“BUG:软锁定 - CPU#2 卡住 20 秒!”之类的日志消息。

即使它重新启动,我也不确定这是否是生成软锁定和从软锁定恢复程序的正确测试程序。

如果我做错了或者您发现我有任何误解,请告诉我。谢谢,

答案1

softlockup_panic on

此处的“恢复”包括内核崩溃和系统重启。由于设置为 ,因此预计会进行重启on

softlockup_panic off

您正确生成了软锁定。在普通的在某些情况下,您会看到类似“BUG:软锁定 - CPU#2 卡住 20 秒!”的消息。您看不到任何内容的原因是由于您的内核模块正在调用printk 处于紧密循环中。假设您甚至可以在如此高的 IO 负载下使用系统,您的模块将与其他内核线程竞争日志记录。这就是您看不到任何软锁定消息的原因。


建议的解决方案:更新无限循环以使用计数器变量仅在每 X 次迭代时打印消息,其中 X 至少为 10,000,000(<- 有点随意)。以下示例依赖于无符号整数溢出。

unsigned int i;
for (i=0; ; i++) {
    if (i == 0) {
        printk("message\n");
    }
}

答案2

如果您没有串行控制台,那么您可以使用 netconsole 来跟踪软锁。

netconsole 的语法:

netconsole=<LOCAL_PORT>@<SENDER_IP_ADDRESS>/<SENDER_INTERFACE>,<REMOTE_PORT>@<RECEIVER_IP_ADDRESS>/<STEP_1_MAC_ADDRESS>
  1. 添加

    netconsole [email protected]/enp0s3,[email protected]/14:ab:c5:83:50:36 loglevel=8 
    

    在启动参数中。或者

    sudo modprobe netconsole netconsole="[email protected]/enp0s3,[email protected]/14:ab:c5:83:50:36" 
    

    在运行时。
    或者

    sudo modprobe netconsole netconsole="6666@/enp0s3,[email protected]/" at run time.
    
  2. 启动后,设置

    dmesg -n 8 
    

    (获取常规内核 dmesg)

  3. 在接收方,运行

    netcat -l -u 6666
    

笔记 :
从 while(1) 循环中注释printk,否则控制台将充斥着打印内容。 20 秒或更长时间后,您将看到软锁消息。如下所示

看门狗:BUG:软锁定 - CPU#0 卡住了 23 秒![softlockup_thre:3444]
while(1) {
   printk(KERN_INFO "%s:%d\n",函数线(英文):
}

相关内容