在 Ubuntu Server 22.04、5.15-realtime 上调试 RCU 停顿

在 Ubuntu Server 22.04、5.15-realtime 上调试 RCU 停顿

我正在尝试隔离 AMD EPYC 8534PN (64C/128T) 上的 CPU。不幸的是,我看到 RCU 停滞并且服务器一次又一次崩溃。我不太确定我做错了什么。

崩溃只发生在服务器负载过大时。通常,我会在那里运行构建作业和一些具有 RT 优先级的任务(集成测试)。但据我所知,通过rcu_nocbs=8-63,72-127 irqaffinity=0-7,64-71 rcu_nocb_poll在 grub 中使用,设置IRQBALANCE_BANNED_CPULIST=8-63,72-127并将剩余的 rco 移至内务处理组,tuna -t rcu* -c 0-7,64-71 -m应该可以避免这种情况,不是吗?我预计不再在隔离核心上执行 rcu。

我看到的错误如下所示:

RCU 摊位:

RCU 摊位

这是输出的一部分dmesg

Apr 22 00:08:37 hp-epyc kernel: rcu: INFO: rcu_preempt detected stalls on CPUs/tasks:
Apr 22 00:08:37 hp-epyc kernel: rcu:         Tasks blocked on level-1 rcu_node (CPUs 48-63): P497/2:b..l
Apr 22 00:08:37 hp-epyc kernel:         (detected by 53, t=2940082 jiffies, g=1051549, q=30752212)
Apr 22 00:08:37 hp-epyc kernel: task:ksoftirqd/53    state:R  running task     stack:    0 pid:  497 ppid:     2 flags:0x00004000
Apr 22 00:08:37 hp-epyc kernel: Call Trace:
Apr 22 00:08:37 hp-epyc kernel:  <TASK>
Apr 22 00:08:37 hp-epyc kernel:  __schedule+0x238/0x5e0
Apr 22 00:08:37 hp-epyc kernel:  ? asm_sysvec_reschedule_ipi+0x1b/0x20
Apr 22 00:08:37 hp-epyc kernel:  preempt_schedule+0x60/0x80
Apr 22 00:08:37 hp-epyc kernel:  preempt_schedule_thunk+0x16/0x18
Apr 22 00:08:37 hp-epyc kernel:  rt_mutex_slowunlock+0x280/0x2f0
Apr 22 00:08:37 hp-epyc kernel:  ? try_to_wake_up+0x307/0x670
Apr 22 00:08:37 hp-epyc kernel:  rt_spin_unlock+0x3e/0x50
Apr 22 00:08:37 hp-epyc kernel:  __hrtimer_run_queues+0x3a0/0x3c0
Apr 22 00:08:37 hp-epyc kernel:  hrtimer_run_softirq+0xa6/0x110
Apr 22 00:08:37 hp-epyc kernel:  __do_softirq+0xc9/0x2cc
Apr 22 00:08:37 hp-epyc kernel:  run_ksoftirqd+0x30/0x80
Apr 22 00:08:37 hp-epyc kernel:  smpboot_thread_fn+0x1d3/0x2d0
Apr 22 00:08:37 hp-epyc kernel:  kthread+0x191/0x1b0
Apr 22 00:08:37 hp-epyc kernel:  ? smpboot_register_percpu_thread+0xe0/0xe0
Apr 22 00:08:37 hp-epyc kernel:  ? set_kthread_struct+0x50/0x50
Apr 22 00:08:37 hp-epyc kernel:  ret_from_fork+0x22/0x30
Apr 22 00:08:37 hp-epyc kernel:  </TASK>

完成输出

根据lscpu -p输出我想出了以下隔离方案:

housekeeping & IRQs: 0-7,64-71
isolation: 8-63,72-127

Systemd 配置如下:

sudo systemctl set-property user.slice AllowedCPUs=0-7,64-71
sudo systemctl set-property system.slice AllowedCPUs=0-7,64-71
sudo systemctl set-property init.scope AllowedCPUs=0-7,64-71

禁止隔离核心发出 IRQ 的情况如下/etc/default/irqbalance

IRQBALANCE_BANNED_CPULIST=8-63,72-127
IRQBALANCE_ONESHOT=0

并且我已经将 rcuo 的 via 移到tuna -t rcu* -c 0-7,64-71 -m了 housekeeping 组。

Grub配置如下:

BOOT_IMAGE=/vmlinuz-5.15.0-1032-realtime root=/dev/mapper/ubuntu--vg-ubuntu--lv ro quiet splash selinux=0 enforcing=0 nmi_watchdog=0 crashkernel=auto softlockup_panic=0 nosoftlockup audit=0 mce=off tsc=nowatchdog skew_tick=1 default_hugepagesz=1GB hugepagesz=1G hugepages=12 iommu=pt amd_iommu=on nohz_full=8-63,72-127 rcu_nocbs=8-63,72-127 irqaffinity=0-7,64-71 nohz=on rcu_nocb_poll numa_balancing=disable transparent_hugepage=never nosoftlockup rcu_nocb_poll processor.max_cstate=0 kthread_cpus=0-7,64-71

操作系统:Ubuntu Server 22.04.4 LTS \ 内核:5.15.0-1032-realtime \
CPU:AMD EPYC 8534PN 64 核处理器

编辑:

我能够稳定服务器。这给了我一些帮助文章(遗憾的是,仅限订阅)。以下是我采取的步骤:

第一步是禁用 irqbalanced。我发现有一个漏洞默默地无法强制执行该IRQBALANCE_BANNED_CPULIST参数。我尝试使用IRQBALANCE_BANNED_CPU,但这个参数在我们使用的版本中已被弃用。所以我完全禁用了 irqbalanced。

文章中说“过去,ksoftirqd/N 线程处理定时器软中断任务,以及其他软中断的工作。”我找不到任何 ksoftirqd 进程,而是只找到了也出现在内核日志中的软中断。

这就是为什么我将 ksoftirqd 线程移至最高优先级以避免它们耗尽 CPU 资源。

x=8
y=63
for i in $(seq $x $y) ; do tuna -t "ksoftirqd/$i" -p fifo:99; done
a=72
b=127
for i in $(seq $a $b) ; do echo "$i"; tuna -t "ksoftirqd/$i" -p fifo:99; done

我还将rcutree.kthread_prio=99内核参数应用到内核命令行,将 RCUrcuc/Nrcub/N线程的优先级设置为 99。

为了提供完整的画面,我通过 Kubernetes 在服务器上运行优先级高达 50 的 RT 工作负载。我还与 RT 工作负载并行运行单元测试和构建测试。

有人能证实上述假设吗,即 ksoftirqd 仍然处理计时器并且在 Ubuntu 上仍然正确?我在研究时找不到太多关于它的信息。

关于这个主题,我还有一个问题,为什么没有将所有 rcu 工作负载正确移动到 housekeeping 组?我不想使用 isolcpus,我猜这会有所帮助。还有其他方法可以完全移动中断,以便隔离核心可以自由地处理 RT 工作负载吗?提前致谢!

相关内容