再生产
我们构建了一个崩溃再现应用程序,它除了分配内存和附加到日志文件之外什么也不做。该进程分配 4GB(以小块形式)并在循环中写入它们,该循环还将日志追加到文件中。 (填满 4GB RAM,其中 400MB 分配给 GPU,并占用约 500M 的 2GB 交换空间)。当分配少于交换空间并且完全没有交换空间时,我们也遇到过这种情况。将大量分配放入交换区似乎会加速崩溃,这向我们暗示了一些与 IO 相关的事情。
症状
我们在附加的 TTY 串行终端中看到以下内容:
[ 926.386714] rcu: INFO: rcu_preempt self-detected stall on CPU
[ 926.392580] rcu: 0-....: (5249 ticks this GP) idle=6be/1/0x4000000000000002 softirq=29651/29651 fqs=2625
[ 926.402388] (t=5250 jiffies g=61417 q=108)
[ 926.406637] Task dump for CPU 0:
[ 926.409914] task:kswapd0 state:R running task stack: 0 pid: 69 ppid: 2 flags:0x0000002a
[ 926.419997] Call trace:
[ 926.422497] dump_backtrace+0x0/0x1c0
[ 926.426219] show_stack+0x24/0x30
[ 926.429591] sched_show_task+0x154/0x180
[ 926.433579] dump_cpu_task+0x50/0x60
[ 926.437210] rcu_dump_cpu_stacks+0xb8/0xf8
[ 926.441371] rcu_sched_clock_irq+0x9b4/0xed0
[ 926.445710] update_process_times+0x6c/0xe0
[ 926.449961] tick_sched_handle+0x3c/0x60
[ 926.453946] tick_sched_timer+0x84/0x110
[ 926.457931] __hrtimer_run_queues+0x15c/0x410
[ 926.462356] hrtimer_interrupt+0x100/0x2d0
[ 926.466517] arch_timer_handler_phys+0x40/0x50
[ 926.471032] handle_percpu_devid_irq+0xb0/0x2b0
[ 926.475631] __handle_domain_irq+0xbc/0x140
[ 926.479879] gic_handle_irq+0x5c/0xf0
[ 926.483598] el1_irq+0xcc/0x180
[ 926.486791] check_preemption_disabled+0x2c/0x110
[ 926.491571] debug_smp_processor_id+0x24/0x30
[ 926.495996] scan_swap_map_try_ssd_cluster+0xa8/0x1f0
[ 926.501126] scan_swap_map_slots+0x74/0x760
[ 926.505374] get_swap_pages+0x174/0x280
[ 926.509268] get_swap_page+0xc4/0x230
[ 926.512989] add_to_swap+0x24/0xa0
[ 926.516445] shrink_page_list+0xa28/0xc30
[ 926.520515] shrink_inactive_list+0x174/0x460
[ 926.524940] shrink_lruvec+0x3b8/0x5e0
[ 926.528746] shrink_node+0x390/0x6f0
[ 926.532377] balance_pgdat+0x288/0x660
[ 926.536184] kswapd+0x210/0x560
[ 926.539374] kthread+0x14c/0x160
[ 926.542652] ret_from_fork+0x10/0x38
Journalctl 中没有记录任何有趣的内容,它显示记录的条目,然后就结束了。一旦崩溃,除了rcu: INFO: rcu_preempt self-detected stall on CPU
串行终端上定期重复的消息之外,没有网络响应或任何其他生命迹象。我们启用了 coredumpctl,但似乎没有得到转储。
诊断尝试
- 我们已经尝试过我们的自定义 Buildroot 操作系统以及 Raspberry Pi 操作系统。
- 我们在多个设备上进行了尝试,结果相同。
- 我们尝试了不同品牌的 SD 卡。
- 我们尝试删除辅助 SD 卡覆盖层 (sd2-wifi) 和 wifi 覆盖层 - 由于这些未删除,我们在上述故障转储之前看到了这一点:
[ 911.006842] brcmfmac: brcmf_sdio_bus_rxctl: resumed on timeout
[ 911.013511] ieee80211 phy0: brcmf_cfg80211_dump_station: BRCMF_C_GET_ASSOCLIST unsupported, err=-110
我们不是内核开发人员,我们不知道如何诊断这个问题。我们发现这个线程,这似乎与早期内核上的相同驱动程序和相同错误有关,但由于我们删除了 wifi 和辅助 SD 覆盖,它看起来像是其他东西。我们可以尝试至少确定原因吗?