【问题标题】:System hanged and CPU high under kernel code wait_event() and wake_up()在内核代码 wait_event() 和 wake_up() 下系统挂起且 CPU 高
【发布时间】:2013-10-22 17:24:13
【问题描述】:

我有两个内核线程,分别运行 a() 和 b()。 a() 正在尝试唤醒 b(),如下所示。

a() {
    while(1) {
       while( atomic_read(status) != SET_SLEEP )
           msleep(10);

       atomic_set(status, SET_RUN);
       printk( "..." );
       wake_up( wq );
    }

b() {
    while(1) {
        atomic_set(status, SET_SLEEP);
        printk( "..." );
        wait_event( wq, atomic_read(status) != SET_SLEEP );
        printk( "..." );
    }

长时间运行后,整个系统都会死机,CPU会变高。没有打印任何恐慌消息。有人知道吗?

【问题讨论】:

  • 在问题出现之前它会运行多长时间?您是否打开了任何可用的调试来尝试缩小根本原因?
  • 大约 10 分钟。我不知道打开可能的调试。它没有崩溃。刚刚上吊,什么也看不见。现在,我怀疑wait_event() 和wake_up() 中是否存在导致死锁和忙等待的“spin_lock”。
  • 您可以通过使用变量名吐出某些值来创建调试。您还可以添加代码以显示 #CPU 线程等内容。
  • 如果我增加线程 b() 的数量,它可能会挂起大约 1 分钟。
  • 嗨 Lizz,我当然做到了。我什至打印了哪个线程正在哪个#CPU上工作,状态等等......但我什么也没得到。我怀疑他们被挂在 wait_event() 或 wake_up() 中。

标签: linux multithreading kernel wait


【解决方案1】:

我们想解决的越多,得到的就越少......

正如 Lizz 所说,我添加了许多 printk 来打印一些信息以进行调试。但我一无所获,因为“printk”对这个错误负有最大责任。

我做了以下实验,发现了一个令人难以置信的结果。
运行 a() 的 1 个线程和 b() 的 1024 个线程。 a() 在 while 循环中唤醒每个 b()
修改printk如下。

write_lock_bh( &pk_lock );
printk( "print some debugging message" );
write_unlock_bh( &pk_lock );

加锁运行一次,不加锁运行一次。
没有锁,它会挂起。
加锁,运行正常。

printk 本来是用来调试的。现在看来是根本原因。

有人有这样的经历吗?

【讨论】:

    【解决方案2】:

    尝试在状态上加一个锁,锁会将 CPU a 的缓存中的状态刷新到主内存中,以便 CPU b 获得最新的更新。或者可能将状态设置为 volatile。

    【讨论】:

    • 谢谢,我已经修改了我的第一篇文章(使用 atomic_t)。但是有了printk,还是挂了。
    猜你喜欢
    • 1970-01-01
    • 2011-12-11
    • 2019-08-04
    • 1970-01-01
    • 1970-01-01
    • 2011-01-07
    • 1970-01-01
    • 2012-09-09
    • 1970-01-01
    相关资源
    最近更新 更多