在我新安装的使用内核 3.2 的系统上,我看到一个 kworker-thread 不断消耗 CPU。我想找出内核/模块的哪个部分创建了这个工作队列。
如何在内核空间中跟踪名为“kworker/0:3”的 kworker 线程到其起源?
我试图查看 /sys/kernel/debug/tracing/events/workqueue,但无法弄清楚。
在我新安装的使用内核 3.2 的系统上,我看到一个 kworker-thread 不断消耗 CPU。我想找出内核/模块的哪个部分创建了这个工作队列。
如何在内核空间中跟踪名为“kworker/0:3”的 kworker 线程到其起源?
我试图查看 /sys/kernel/debug/tracing/events/workqueue,但无法弄清楚。
(在我看来,这不是主题,但这是我在unix.stackexchange.com上发布的答案。)
我在 lkml 上找到了这个帖子,可以稍微回答你的问题。(似乎连 Linus 本人都对如何找出这些线程的来源感到困惑。)
基本上,有两种方法可以做到这一点:
$ echo workqueue:workqueue_queue_work > /sys/kernel/debug/tracing/set_event
$ cat /sys/kernel/debug/tracing/trace_pipe > out.txt
(wait a few secs)
为此,您需要在内核中编译ftrace 。
这将输出线程都在做什么,并且对于跟踪多个小型作业很有用。
cat /proc/THE_OFFENDING_KWORKER/stack
这将输出做大量工作的单个线程的堆栈。它可以让您找出导致该特定线程占用 CPU 的原因(例如)。THE_OFFENDING_KWORKER
是进程列表中kworker的pid。
所以,一段时间后,我找到了解决方案。事实上,Anthon 是对的,发送中断的是 ACPI 子系统。在我的系统上,我禁用了以下中断并且 kworker-thread 平静下来。
echo disable > /sys/firmware/acpi/interrupts/gpe1B
echo disable > /sys/firmware/acpi/interrupts/gpe08
然而,直到现在还没有确定虚假 IRQ 来自gpe08
和gpe1B
。
kworker / watchdog 在不使用电缆电源时经常导致高负载 - 解决方法
仅当笔记本电脑由电缆供电时,kworker(导致 kernel_thread_helper+0x6/0x10 ?)线程 1 每 5 秒达到 100% 的 cpu 1 秒。电池电量没有问题。电池是否充满电无关紧要。
它或多或少是突然出现的,所以我猜最近的 Ubuntu 更新是原因(现在是 3.2.0-55-generic-pae)。
找了半天,试图找出根本原因是,endet up 试图禁用所有 acpi 中断,这没关系。
最后将 GRUB_CMDLINE_LINUX_DEFAULT=”acpi=off” 添加到 /etc/defaults/grub 有帮助。
正如我现在发现的那样,我用这些确切的特殊 unicode 引号添加了它,这可能解释了与“安静的飞溅”(带有默认引号)的不兼容,这让我感到困惑。我必须查看更多 grub 问题(但我尝试未显示启动菜单,未使用默认条目配置......)所以我将把测试留到以后。
PS:一周后,问题又回来了(没有重启,只是中间暂停)。可能与使用 USB 鼠标有关。断电/通电有帮助(重启没有)。抛弃所有 grub 选项。我期待这个问题会在某个时候再次出现。
PPS:花了一些时间(半年),但在ram恢复后又回来了。没有最近的更新,只是像我经常做的那样插入/拔出电源。没有插入/拔出 USB 设备。在暂停期间有一个图腾在运行(但没有播放)。插上电源线断电/通电没有帮助,拔下电源线断电/通电有帮助。
针对此类问题的另一个解决方案(我已经在不久前发布在不同的线程中,也许您可以找到解决您问题的其他解决方案)是使用perf 工具 (默认情况下并不总是启用它,您可以需要在您的设备上安装 perf )。
第 1 步:设置 perf 以记录工作队列事件:
perf record -e 'workqueue:*' -ag -T
第 2 步:只要您认为需要捕捉事件就运行它(如果此事件足够频繁,10 秒应该没问题,但您可以让它运行更长时间,具体取决于您设备上剩余的可用空间)然后用Ctrl + C
.
第 3 步:打印捕获的事件(在 Linux 版本 < 4.1 我认为应该是 -f 而不是 -F):
perf script -F comm,pid,tid,time,event,trace
这将显示如下内容:
task-name pid/tid timestamp event
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
turtle 9201/9201 1473.339166: workqueue:workqueue_queue_work: work struct=0xef20d4c4 function=pm_runtime_work workqueue=0xef1cb600 req_cpu=8 cpu=1
turtle 9201/9201 1473.339176: workqueue:workqueue_activate_work: work struct 0xef20d4c4
kworker/0:3 24223/24223 1473.339221: workqueue:workqueue_execute_start: work struct 0xef20d4c4: function pm_runtime_work
kworker/0:3 24223/24223 1473.339248: workqueue:workqueue_execute_end: work struct 0xef20d4c4
第四步:分析上表:
在第一行,一个名为的任务turtle (pid 9201)
将工作推pm_runtime_work
送到工作队列。在第三行中,我们可以看到 kworker/0:3 (pid 24223)
正在执行该工作。
摘要:现在回到您的问题,我们看到任务kworker/0:3
已请求turtle
运行该pm_runtime_work
功能。那么让我们回到代码中,看看这个 pm_runtime_work
函数做了什么!也许在这里我们将设法理解为什么它会消耗如此多的 CPU。
kworker 是处理工作队列的内核线程。该线程在文件 linux/kernel/workqueue.c 文件中创建。