rcu_preempt 自我检测到 CPU 停顿 { 0}

问题描述 投票:0回答:3

我正在我的 intel rangeley 板上运行一个应用程序,它有 3.14.29-rt22 内核 在上面运行。应用程序将运行两个线程,每个线程的 pri :39。周期性地持续 1 和 2 毫秒。 两个线程都将在连续的 while 循环中运行,which will be running 仅在核心 0 上。 运行一段时间后,大约 10 分钟。当我按 ctrl+c 时,它会在下面给出日志。

**INFO: rcu_preempt self-detected stall on CPU { 0}  (t=21000 jiffies g=2362 c=2361 q=207)**
**sending NMI to all CPUs:
 NMI backtrace for cpu 1**

 CPU: 1 PID: 0 Comm: swapper/1 Not tainted 3.14.29ltsi-rt22-yocto-preempt-rt+ #1

 Hardware name: ADI Engineering RCC-VE/RCC-VE, BIOS ADI_RCCVE-01.00.00.04-nodebug 05/06/2015

task: ffff8802761a0000 ti: ffff8802761a8000 task.ti: ffff8802761a8000
RIP: 0010:[<ffffffff8100b451>]  [<ffffffff8100b451>]   native_read_tsc+0x1/0x20
RSP: 0018:ffff8802761abe28  EFLAGS: 00000003
RAX: 0000000000000000 RBX: ffffffff81e1acc0 RCX: 0000000000000000
RDX: 0000000000000001 RSI: 0000000000000202 RDI: ffffffff81e1acc0
RBP: ffff8802761abe38 R08: ffff8802761a8000 R09: 0000000000000001
R10: 0000000000000800 R11: 0000000000000000 R12: 000000000000003e
R13: 0000000000014e76 R14: ffff8802761abfd8 R15: ffff88027fc8cf00
FS:  0000000000000000(0000) GS:ffff88027fc80000(0000)   knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 00007fabcd23f000 CR3: 0000000269589000 CR4: 00000000001007e0
Stack:
ffff8802761abe38 ffffffff8100b4a9 ffff8802761abe60 ffffffff810a6b73
0000000000000001 ffff8802761abfd8 ffffffff81edc030 ffff8802761abec0
ffffffff810b01a5 ffffffffffffff10 ffffffff8103b906 0000000000000000
Call Trace:
[<ffffffff8100b4a9>] ? read_tsc+0x9/0x20
[<ffffffff810a6b73>] ktime_get+0x43/0xc0
[<ffffffff810b01a5>] __tick_nohz_idle_enter+0x25/0x480
[<ffffffff8103b906>] ? native_safe_halt+0x6/0x10
[<ffffffff810b064a>] tick_nohz_idle_enter+0x4a/0x80
[<ffffffff8109a626>] cpu_startup_entry+0x46/0x290
[<ffffffff81031597>] start_secondary+0x1b7/0x210

可能是什么原因?是因为我长时间连续使用CPU吗? 当我从控制台上的线程打印任何内容时,不会发生崩溃。

linux-kernel scheduling
3个回答
3
投票

是的,长时间从高优先级线程持续使用 CPU(从调度程序的角度来看,1ms 是一个很大的周期)可能是 RCU 停顿的原因。

来自关于RCU失速检测器的文档:

以下问题会导致RCU CPU stall 警告:

... CONFIG_PREEMPT 内核中的 CPU 绑定实时任务,可能 碰巧在 RCU 中间抢占了一个低优先级的任务 读端临界区。如果 低优先级任务不允许在任何其他 CPU 上运行, 在这种情况下,下一个 RCU 宽限期永远无法完成,这 最终会导致系统内存不足而挂起

... CONFIG_PREEMPT_RT 内核中的 CPU 绑定实时任务 以比 RCU 软中断线程更高的优先级运行。 这将阻止 RCU 回调被调用, 并且在 CONFIG_PREEMPT_RCU 内核中将进一步防止 RCU 宽限期从永远完成。无论哪种方式, 系统最终会耗尽内存并挂起。

从高优先级线程执行任何系统调用(如

write()
到控制台)让内核执行一些针对系统维护的工作。

可能,sched_yield 也会有帮助。


2
投票

所以我在启动过程中得到了与此惊人相似的东西,它会挂起并按任何键(甚至是数字锁定)都会取消挂起并在几秒钟后再次挂起。每次启动必须这样做 5-7 次!

罪魁祸首是 BIOS 中的一个设置,AMD C1E 支持设置为启用并将其设置为自动或禁用(均已测试)为我解决了这个问题!没有更多的摊位/挂起!


0
投票

所以我在启动过程中得到了与此惊人相似的东西,它会挂起并按任何键(甚至是数字锁定)都会取消挂起并在几秒钟后再次挂起。每次启动必须这样做 5-7 次!

这很可能是由于随机数生成器没有足够的熵来满足请求。当你按下一个键时,它会产生一些熵,足以让启动序列走得更远,它再次挂起,等待更多的熵。

© www.soinside.com 2019 - 2024. All rights reserved.