|Index|SUSE Telco Cloud 文档|电信功能配置|用于低延迟和高性能的内核参数
Applies to SUSE Telco Cloud 3.6

35 用于低延迟和高性能的内核参数

配置适当的内核参数对于优化性能、实现低延迟以及确保电信工作负载的集群部署成功至关重要。虽然某些参数是专门为使实时内核发挥最佳功能而设计的,但本节适用于 RT 和默认内核配置。此外,某些参数对于定向网络配置 (Directed Network Provisioning) 方法成功部署下游集群节点是强制性的。

  • 使用 SUSE 实时内核时,请去除 kthread_cpus。此参数控制在哪些 CPU 上创建内核线程。它还控制允许 PID 1 和加载内核模块(kmod 用户空间辅助程序)使用哪些 CPU。此参数无法识别,且不起任何作用。

  • 使用 isolcpusnohz_fullrcu_nocbsirqaffinity 隔离 CPU 核心。有关 CPU 绑定技术的完整列表,请参阅 CPU Pinning on Host (Chapter 36, 主机上的 CPU 绑定) 章节。

  • domain,nohz,managed_irq 标志添加到 isolcpus 内核参数中。在没有任何标志的情况下,isolcpus 等同于仅指定 domain 标志。这会将指定的 CPU 从调度中隔离出来,包括内核任务。nohz 标志会停止指定 CPU 上的调度程序节拍(如果 CPU 上只有一个可运行任务),而 managed_irq 标志则避免将受管外部(设备)中断路由到指定的 CPU。请注意,NVMe 设备的 IRQ 线路完全由内核管理,因此它们将被路由到非隔离(常规)核心。例如,本节末尾提供的命令行将导致系统上仅分配四个队列(外加一个管理/控制队列):

    for I in $(grep nvme0 /proc/interrupts | cut -d ':' -f1); do cat /proc/irq/${I}/effective_affinity_list; done | column
    39      0       19      20      39

    此行为可防止磁盘 I/O 对运行在隔离核心上的任何时间敏感型应用程序造成干扰,但对于以存储为主的工作负载,可能需要特别关注并进行仔细设计。

  • 调整时钟节拍(内核的周期性定时器中断):

    • skew_tick=1:时钟节拍有时会同时发生。skew_tick=1 不会让所有 CPU 在同一时刻接收定时器节拍,而是使它们在略有偏差的时间发生。这有助于减少系统抖动,从而实现更一致且更低的中断响应时间(这是延迟敏感型应用程序的基本要求)。

    • nohz=on:停止空闲 CPU 上的周期性定时器节拍。

    • nohz_full=<cpu-cores>:停止专用于实时应用程序的指定 CPU 上的周期性定时器节拍。

  • 通过指定 mce=off 来禁用机器检查异常 (MCE) 处理。MCE 是处理器检测到的硬件错误,禁用它们可以避免产生冗余日志。

  • 添加 nowatchdog 以禁用软锁定监视程序,该监视程序实现为在定时器硬中断上下文中运行的定时器。当它过期(即检测到软锁定)时,它将打印一条警告(在硬中断上下文中),从而影响任何延迟目标。即使它永不过期,它也会进入计时器列表,从而略微增加每次计时器中断的开销。此选项还会禁用 NMI 看门狗,因此 NMI 不会产生干扰。

  • nmi_watchdog=0 禁用 NMI(不可屏蔽中断)看门狗。使用 nowatchdog 时可以省略此项。

  • RCU(读取-复制-更新)是一种内核机制,它使多个读取者能够对共享数据进行并发、无锁的访问。RCU 回调是一种在“宽限期”后触发的函数,它确保所有先前的读取者都已完成工作,以便可以安全地回收旧数据。我们对 RCU 进行微调,特别是针对敏感工作负载,将这些回调从专用(固定)CPU 上卸载,防止内核操作干扰关键的、时间敏感的任务。

    • rcu_nocbs 中指定固定 CPU,以便 RCU 回调不会在这些 CPU 上运行。这有助于减少实时工作负载的抖动和延迟。

    • rcu_nocb_poll 使无回调 CPU 定期“轮询”以查看是否需要处理回调。这可以减少中断开销。

    • rcupdate.rcu_cpu_stall_suppress=1 禁止 RCU CPU 停滞警告,在负载繁重的实时系统中,这些警告有时可能是误报。

    • rcupdate.rcu_expedited=1 加快 RCU 操作的宽限期,使读取侧临界区响应更迅速。

    • rcupdate.rcu_normal_after_boot=1 当与 rcu_expedited 一起使用时,它允许 RCU 在系统引导后恢复为正常(非加速)操作。

    • rcupdate.rcu_task_stall_timeout=0 禁用 RCU 任务停滞检测器,防止因长时间运行的 RCU 任务而产生潜在的警告或系统挂起。

    • rcutree.kthread_prio=99 将 RCU 回调内核线程的优先级设置为最高(99),确保在需要时它能被调度并及时处理 RCU 回调。

  • 添加 ignition.platform.id=openstack 以供 Metal3 和 Cluster API 成功配置/取消配置集群。这由 Metal3 Python 代理使用,该代理源自 Openstack Ironic。

  • 通过 net.ifnames=1 启用 可预测网络接口命名。从 SUSE Linux Micro 6.2 开始,此功能默认启用,无需进行显式配置。对于 6.2 之前的版本,必须将其显式设置为内核参数。这与管理集群的 Metal3 Helm 图表中的 predictableNicNames 配置一致,这是定向网络配置正常运行所必需的。当使用 SR-IOV 时,一致的接口命名也至关重要。

  • 去除 intel_pstate=passive。此选项配置 intel_pstate 以与通用 cpufreq 调控器配合使用,但为了使其生效,它会产生禁用硬件管理的 P-states (HWP) 的副作用。为了减少硬件延迟,不建议将此选项用于实时工作负载。

  • intel_idle.max_cstate=0 processor.max_cstate=1 替换为 idle=poll。为了避免 C-State 转换,使用 idle=poll 选项来禁用 C-State 转换并使 CPU 保持在最高 C-State。intel_idle.max_cstate=0 选项禁用 intel_idle,因此使用 acpi_idle,然后 acpi_idle.max_cstate=1 为 acpi_idle 设置最大 C-state。 在 AMD64/Intel 64 架构上,第一个 ACPI C-State 始终是 POLL,但它使用 poll_idle() 函数,该函数可能会通过定期读取时钟并在超时后在 do_idle() 中重新启动主循环来引入一些微小的延迟(这也涉及清除和设置 TIF_POLL 任务标志)。 相比之下,idle=poll 在紧密循环中运行,忙等待任务被重新调度。这最大限度地减少了退出空闲状态的延迟,但代价是使 CPU 在空闲线程中全速运行。

  • 在 BIOS 中禁用 C1E。此选项对于在 BIOS 中禁用 C1E 状态非常重要,以避免 CPU 在空闲时进入 C1E 状态。C1E 状态是一种低功耗状态,在 CPU 空闲时可能会引入延迟。

本文档的其余部分涵盖了其他参数,包括大页和 IOMMU。

这提供了一个 32 核 Intel 服务器的内核参数示例,包括上述调整:

$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.4.0-9-rt root=UUID=77b713de-5cc7-4d4c-8fc6-f5eca0a43cf9 skew_tick=1 rd.timeout=60 rd.retry=45 console=ttyS1,115200 console=tty0 default_hugepagesz=1G hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0 ignition.platform.id=openstack net.ifnames=1 intel_iommu=on iommu=pt irqaffinity=0,31,32,63 isolcpus=domain,nohz,managed_irq,1-30,33-62 nohz_full=1-30,33-62 nohz=on mce=off nosoftlockup nowatchdog nmi_watchdog=0 quiet rcu_nocb_poll rcu_nocbs=1-30,33-62 rcupdate.rcu_cpu_stall_suppress=1 rcupdate.rcu_expedited=1 rcupdate.rcu_normal_after_boot=1 rcupdate.rcu_task_stall_timeout=0 rcutree.kthread_prio=99 security=selinux selinux=1 idle=poll

这是另一个 64 核 AMD 服务器的配置示例。在 128 个逻辑处理器 (0-127) 中,前 8 个内核 (0-7) 被指定用于内务管理,而其余 120 个内核 (8-127) 则固定用于应用程序:

$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.4.0-9-rt root=UUID=575291cf-74e8-42cf-8f2c-408a20dc00b8 skew_tick=1 console=ttyS1,115200 console=tty0 default_hugepagesz=1G hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0 ignition.platform.id=openstack net.ifnames=1 amd_iommu=on iommu=pt irqaffinity=0-7 isolcpus=domain,nohz,managed_irq,8-127 nohz_full=8-127 rcu_nocbs=8-127 mce=off nohz=on nowatchdog nmi_watchdog=0 nosoftlockup quiet rcu_nocb_poll rcupdate.rcu_cpu_stall_suppress=1 rcupdate.rcu_expedited=1 rcupdate.rcu_normal_after_boot=1 rcupdate.rcu_task_stall_timeout=0 rcutree.kthread_prio=99 security=selinux selinux=1 idle=poll