找回密码
 立即注册

QQ登录

只需一步,快速开始

主机交流Megalayer兑换位02兑换位03
兑换位04兑换位05兑换位06兑换位07
查看: 408|回复: 0

[Linux/Centos/Ubuntu] Linux内核线程死锁或死循环

[复制链接]

602

主题

59

回帖

2776

积分

超级版主

积分
2776

最佳新人活跃会员热心会员推广大使宣传大使灌水之王突出贡献优秀版主荣誉管理论坛元老

发表于 2020-8-13 17:38:20 | 显示全部楼层 |阅读模式
Linux内核线程死锁或死循环(soft lockup)

在开发内核模块或驱动时,如果处理失误,导致内核线程中出现死锁或者死循环,你会发现,除了重启之外,你没有任何可以做的。这时你的输入不起任何作用,终端(不是指远程的ssh工具)只会在那重复的输出类似“BUG: soft lockup - CPU#0 stuck for 67s! [fclustertool:2043]”,更无奈的是你重启之后导致系统挂起的堆栈信息也看不到,你所能做的就是一遍遍的加调试信息,一遍遍的重启机器(这是我的经历,现在想想很傻)。
这种情况你肯定不是第一个遇到的,所以内核肯定会提供处理这种情况的一些机制。但是如何来找到这些机制在哪个地方,或者说根据什么信息去google呢?最有用的就是这句话“BUG: soft lockup - CPU#0 stuck for 67s! [fclustertool:2043]”,因为这句话提供你的信息量很大。首先,这条信息可以输出,说明即使发生死锁或者死循环,还是有代码可以执行。第二,可以通过这个日志信息,找到对应的处理函数,这个函数所在的模块就是用来处理CPU被过度使用时用到的。所以通过这个事情,可以看到内核打印出的只言片语都有可能成为你解决问题的关键,一定要从重视这些信息,从中找出有用的东西。
我经常看的内核版本是官方的2.6.32内核,这个版本中我找到的函数是softlockup_tick(),这个函数在时钟中断的处理函数run_local_timers()中调用。这个函数会首先检查watchdog线程是否被挂起,如果不是watchdog线程,会检查当前占有CPU的线程占有的时间是否超过系统配置的阈值,即softlockup_thresh。如果当前占有CPU的时间过长,则会在系统日志中输出我们上面看到的那条日志。接下来才是最关键的,就是输出模块信息、寄存器信息和堆栈信息,检查softlockup_panic的值是否为1。如果softlockup_panic为1,则调用panic()让内核挂起,输出OOPS信息。
但是softlockup_panic的值默认竟然是0,所以在出现死锁或者死循环的时候,会一直只输出日志信息,而不会宕机,这个真是好坑啊!所以你得手动修改/proc/sys/kernel/softlockup_panic的值,让内核可以在死锁或者死循环的时候可以宕机。如果你的机器中安装了kdump,在重启之后,你会得到一份内核的core文件,这时从core文件中查找问题就方便很多了,而且再也不用手动重启机器了。如果你的内核是标准内核的话,可以通过修改/proc/sys/kernel/softlockup_thresh来修改超时的阈值,如果是CentOS内核的话,对应的文件是/proc/sys/kernel/watchdog_thresh。CentOS内核和标准内核还有一个地方不一样,就是处理CPU占用时间过长的函数,CentOS下是watchdog_timer_fn()函数。
==========================================以下为日志输出==========================================
Jan 16 22:40:01 web1-jnj CRON[14713]: (smmsp) CMD (test -x /etc/init.d/sendmail && /usr/share/sendmail/sendmail cron-msp)
Jan 16 22:40:06 web1-jnj kernel: [1563980.028004] BUG: soft lockup - CPU#0 stuck for 22s! [apache2:14695]
Jan 16 22:40:06 web1-jnj kernel: [1563980.028004] Modules linked in: ip6table_filter ip6_tables iptable_filter xt_nat iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack ip_tables x_tables nfsd auth_rpcgss nfs_acl nfs lockd sunrpc fscache cirrus ttm drm_kms_helper psmouse serio_raw drm syscopyarea sysfillrect sysimgblt i2c_piix4 lp parport mac_hid floppy
Jan 16 22:40:06 web1-jnj kernel: [1563980.028004] CPU: 0 PID: 14695 Comm: apache2 Not tainted 3.13.0-24-generic #46-Ubuntu
Jan 16 22:40:06 web1-jnj kernel: [1563980.028004] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2007
Jan 16 22:40:06 web1-jnj kernel: [1563980.028004] task: ffff8801170a5fc0 ti: ffff8801182e8000 task.ti: ffff8801182e8000
Jan 16 22:40:06 web1-jnj kernel: [1563980.028004] RIP: 0010:[<ffffffff81209b89>] [<ffffffff81209b89>] time_out_leases+0x49/0xb0
Jan 16 22:40:06 web1-jnj kernel: [1563980.028004] RSP: 0018:ffff8801182e9de8 EFLAGS: 00000202
==================================================================================================
现象还会有负载过高的情况


可以优化内核参数来改善

修改Linux的锁死的机制时间(默认为10)
echo "kernel.watchdog_thresh=30" >>/etc/sysctl.conf
最后重新加载
sysctl -p

GDC主机交流论坛 https://www.globaldc.cn/
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|GDC主机交流论坛_GDC之家

GMT+8, 2024-3-29 08:40 , Processed in 0.056384 second(s), 21 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表