我正在尝试隔离 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 摊位:
这是输出的一部分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/N
和rcub/N
线程的优先级设置为 99。
为了提供完整的画面,我通过 Kubernetes 在服务器上运行优先级高达 50 的 RT 工作负载。我还与 RT 工作负载并行运行单元测试和构建测试。
有人能证实上述假设吗,即 ksoftirqd 仍然处理计时器并且在 Ubuntu 上仍然正确?我在研究时找不到太多关于它的信息。
关于这个主题,我还有一个问题,为什么没有将所有 rcu 工作负载正确移动到 housekeeping 组?我不想使用 isolcpus,我猜这会有所帮助。还有其他方法可以完全移动中断,以便隔离核心可以自由地处理 RT 工作负载吗?提前致谢!