kworker任务阻塞超过120秒
服务器系统日志连续显示
May 8 14:57:25 example_server kernel: INFO: task kworker/88:2:80044 blocked for more than 120 seconds.
May 8 14:57:25 example_server kernel: "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
May 8 14:57:25 example_server kernel: kworker/88:2 D ffff88019bc5e380 0 80044 2 0x00000000
May 8 14:57:25 example_server kernel: ffff8803c5d87bf0 0000000000000046 ffff88011d666380 ffff8803c5d87fd8
May 8 14:57:25 example_server kernel: ffff8803c5d87fd8 ffff8803c5d87fd8 ffff88011d666380 ffff8803c5d87d58
May 8 14:57:25 example_server kernel: ffff8803c5d87d60 7fffffffffffffff ffff88011d666380 ffff8803c5d87dd8
May 8 14:57:25 example_server kernel: Call Trace:
May 8 14:57:25 example_server kernel: [<ffffffff8163a1c9>] schedule+0x29/0x70
May 8 14:57:25 example_server kernel: [<ffffffff81637e29>] schedule_timeout+0x209/0x2d0
May 8 14:57:25 example_server kernel: [<ffffffff8101d165>] ? native_sched_clock+0x35/0x80
May 8 14:57:25 example_server kernel: [<ffffffff8101d1b9>] ? sched_clock+0x9/0x10
May 8 14:57:25 example_server kernel: [<ffffffff8163a5a6>] wait_for_completion+0x116/0x170
May 8 14:57:25 example_server kernel: [<ffffffff810b4b00>] ? wake_up_state+0x20/0x20
May 8 14:57:25 example_server kernel: [<ffffffff810a15e8>] kthread_create_on_node+0xa8/0x140
May 8 14:57:25 example_server kernel: [<ffffffff81099ed0>] ? rescuer_thread+0x400/0x400
May 8 14:57:25 example_server kernel: [<ffffffff810995fa>] create_worker+0xea/0x250
May 8 14:57:25 example_server kernel: [<ffffffff810998f6>] manage_workers.isra.24+0xf6/0x2d0
May 8 14:57:25 example_server kernel: [<ffffffff8109a209>] worker_thread+0x339/0x400
May 8 14:57:25 example_server kernel: [<ffffffff81099ed0>] ? rescuer_thread+0x400/0x400
May 8 14:57:25 example_server kernel: [<ffffffff810a174f>] kthread+0xcf/0xe0
May 8 14:57:25 example_server kernel: [<ffffffff810a1680>] ? kthread_create_on_node+0x140/0x140
May 8 14:57:25 example_server kernel: [<ffffffff81644fd8>] ret_from_fork+0x58/0x90
May 8 14:57:25 example_server kernel: [<ffffffff810a1680>] ? kthread_create_on_node+0x140/0x140
同时在KVM虚拟机中也观察到
INFO: task jbd2/vdb5-8:1648 blocked for more than 120 seconds.
Not tainted 2.6.32-696.3.2.el6.x86_64 #1
echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
INFO: task sadc:30102 blocked for more than 120 seconds.
Not tainted 2.6.32-696.3.2.el6.x86_64 #1
echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
INFO: task jbd2/vda1-8:327 blocked for more than 120 seconds.
Not tainted 2.6.32-696.3.2.el6.x86_64 #1
echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
这个现象和块设备阻塞事件类似,有可能存在存储异常或内核bug导致写入磁盘性能不足,影响了系统运行。
排查建议
首先检查内存使用,查看是否内存不足
sar -r
检查CPU使用,如果不是CPU很繁忙,需要检查磁盘使用
sar -u
检查是否有
ioniced
在运行,当这个进程在运行,idle-class
意味着策略限制,也就是存在大量的IO检查是否是定时任务导致的
检查是否内存不足
cat /proc/buddyinfo
如果使用了某些性能缓慢的存储,例如NFS,需要检查writeback cache是否已经填满导致性能下降。当写缓存满时候,NFS表现性能非常低下并且类似于文件系统故障。
检查负载是否过高
处理IO缓慢
很多时候,在磁盘或文件系统出现异常时,会出现task XXXX blocked for more than 120 seconds.
,这种现象在系统负载极高或者IO负载极高时候出现,原因是默认情况下Linux使用40%的可用内存作为文件系统缓存。当达到这个阀值之后,就会将缓存内容刷新到磁盘以实现IO同步。对于刷新数据到磁盘默认设置了120秒作为时间限制。如果IO系统不是足够快速,不能在120秒内完成数据刷新就会出现上述报警。
例如IO子系统响应缓慢,或者有太多的请求需要服务,系统内存就会填满导致上述错误。
可以通过以下内核配置降低刷新脏页阀值版本比,以便能够降低批量刷新数据量,避免120秒无法完成触发上述异常:
sudo sysctl -w vm.dirty_ratio=10
sudo sysctl -w vm.dirty_background_ratio=5
sudo sysctl -p
持久化配置/etc/sysctl.conf
vm.dirty_background_ratio = 5
vm.dirty_ratio = 10
背景知识:kworker
kworker
kworker
即kernel worker processes,通常执行很多内核任务,例如:
缓存回写
处理硬件事件(中断、记时器、I/O)
很多,很多其他系统任务
要了解某个kworker
在执行什么工作,可以打印该kworker
堆栈:
sudo cat /proc/<kworker_pid>/stack
例如输出:
$ cat /proc/$(pgrep -of kworker)/stack
[<ffffffff85c0c705>] acpi_ns_evaluate+0x1bc/0x23a
[<ffffffff85bffe09>] acpi_ev_asynch_execute_gpe_method+0x98/0xff
[<ffffffff85be4e30>] acpi_os_execute_deferred+0x10/0x20
[<ffffffff8588dc21>] process_one_work+0x181/0x370
[<ffffffff8588de5d>] worker_thread+0x4d/0x3a0
[<ffffffff85893f1c>] kthread+0xfc/0x130
[<ffffffff8588de10>] process_one_work+0x370/0x370
[<ffffffff85893e20>] kthread_create_on_node+0x70/0x70
[<ffffffff858791ba>] do_group_exit+0x3a/0xa0
[<ffffffff85e6a2b5>] ret_from_fork+0x25/0x30
[<ffffffffffffffff>] 0xffffffffffffffff
上述堆栈表明这个kworker
正在处理ACPI事件,其中关键字process_one_work
表明正在处理中,处理的是acpi_os_execute_deferred
事件。
如果显示堆栈如下:
[<ffffffff9409a37d>] worker_thread+0xbd/0x400
[<ffffffff940a0355>] kthread+0x125/0x140
[<ffffffff946780c5>] ret_from_fork+0x25/0x30
[<ffffffffffffffff>] 0xffffffffffffffff
则表明该kworker
正在等待工作。
如果kwoker大量消耗了CPU资源,可以通过echo l > /proc/sysrq-trigger
创建一个backtrace,这样就能够在系统日志中观察问题来源:
sysctl -w kernel.sysrq=1
echo l > /proc/sysrq-trigger
需要先设置
kernel.sysrq=1
以便激活sysrq功能
此外,可以通过 Perf 来统计所有CPU的backtrace:
sudo perf record -g -a sleep 10
然后分析:
sudo perf report
参考
Last updated
Was this helpful?