目前看来就是内核中有死循环!
一、问题简述

在网上看到很多软死锁的问题,经过对自己程序的理解,结合网上一些相关资料,基本上可以确定是由于内核bug造成的,这个问题基本上在内核模块加载或卸载的时候发生,对我的模块而言,每次卸载时候发生,其他一切情况均正常,而且在2.6.28和3.0.0内核下均有问题。
二、问题过程
2.1 系统由两个模块:cpu模块和mem模块构成,每个模块由若干个故障检测对象组成,对象由单链表相互连接并由一个结构体作为头部head;
2.2 加载模块时,先对每个模块的每一个故障检测对象初始化,然后对每个模块的每个故障检测对象建立proc文件接口,

即 objectsInit();

interfaceInit();

该过程执行正常
2.3 卸载模块时,先对每个模块的每一个故障检测对象进行初始化内存的释放,然后对每个模块的每个故障检测对象进行proc文件接口的回收
即 objectsExit();
interfaceExit();
2.4 问题:卸载模块时,当对cpu模块的所有故障检测对象进行proc文件接口回收时,执行正常,但是当对mem模块的所有故障检测对象进行proc文件接口回收时,出现BUG: soft lockup 问题,通过分析,问题出在无法遍历memHead的每个对象成员,即执行下面循环时出现问题。
struct objAddr* pptr = memModuleHead.next;
while(pptr)
{
printk("–%lx—\n",(unsigned long)pptr);
pptr = pptr->next;
}
2.5 解决: 卸载模块时,先对每个模块的每个故障检测对象进行proc文件接口的回收,然后在再对每个模块的每一个故障检测对象进行初始化内存的释放,便可解决问题
即 interfaceExit();
objectsExit();
2.6 原因: 实在想不明白,因为:memModuleHead链表中的所有对象都是在各个文件中定义的静态全局变量,而且在初始化内存的释放过程中,并没有对这些对象进行操作,所以应该可以正常便利该单链表每个成员,而且在模块正常运行时可以遍历每个成员,只有在卸载模块时会出现这个错误;cpu模块的处理方式和mem模块的完全一致,但是cpu模块卸载过程中并没有发生上述问题;全局静态变量的地址在程序执行过程中都是可以访问的,如果出现访存问题,系统一般情况下杀死内核模块卸载进程或者直接奔溃,不应该每个固定周期出现BUG: soft lockup - CPU#0 stuck for 61s!提示。

近期在服务器跑大量高负载程序,造成cpu soft lockup。如果确认不是软件的问题。采用下面的解决办法:

echo 30 > /proc/sys/kernel/watchdog_thresh

sysctl -w kernel.watchdog_thresh=30

cat /etc/sysctl.conf

kernel.watchdog_thresh=30

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐