Linux RT 分析Linux 6.12.107

10 · Kconfig 差异:RT 强制了什么、禁用了什么

结论:选中 CONFIG_PREEMPT_RT 不只是换一种抢占模型。它要求 EXPERTARCH_SUPPORTS_RT(6.12.107 只有 x86 / arm64 / riscv),与 PREEMPT_DYNAMIC 互斥,强制 RT_MUTEXESPREEMPT_RCURCU_BOOST,把 THPNUMA_BALANCINGDRM_I915QUEUED_RWLOCKSKMSANDEBUG_MUTEXESDEBUG_RWSEMS 等直接变成不可选,并把一批运行时参数(use_softirqrcu_normal_after_bootthreadirqs)固定为常量。本章是全树 34 处 Kconfig 引用的完整清单。

第一层:特性矩阵

先看结论:RT 不是「多一个选项」——它砍掉 11 个特性(THP、NUMA balancing、i915、PREEMPT_DYNAMIC…)并固定一批运行时参数。

非 RT可选特性全集
非 RT:可选特性全集
同一场景 · 换成 PREEMPT_RT 内核
PREEMPT_RT同一批特性的状态
RT:同一批特性的状态

第二层:依赖关系

先看结论:入口只有 depends on EXPERT && ARCH_SUPPORTS_RT + select PREEMPTION 两行,其余联动靠各子系统自己的 default/depends

非 RT抢占模型 choice 与 PREEMPT_DYNAMIC
非 RT:抢占模型 choice 与 PREEMPT_DYNAMIC
同一场景 · 换成 PREEMPT_RT 内核
PREEMPT_RTselect / depends 联动图
RT:select / depends 联动图

入口

kernel/Kconfig.preempt:70-73

config PREEMPT_RT
    bool "Fully Preemptible Kernel (Real-Time)"
    depends on EXPERT && ARCH_SUPPORTS_RT
    select PREEMPTION

PREEMPTIONselect PREEMPT_COUNT:92-94)。ARCH_SUPPORTS_RT 定义于 arch/Kconfig:1359-1360,由 arch/x86/Kconfig:128arch/arm64/Kconfig:105arch/riscv/Kconfig:68 选中;32 位 ARM、PowerPC、MIPS、s390、LoongArch 在 6.12.107 不能选 RT。菜单里要先勾 General setup → Configure standard kernel features (expert users),"Fully Preemptible Kernel (Real-Time)" 才会出现在 Preemption Model 里。

不可选(depends on !PREEMPT_RT

符号 含义 位置 原因
PREEMPT_DYNAMIC 启动参数切换抢占模型 kernel/Kconfig.preempt:98 RT 是独立实现
TRANSPARENT_HUGEPAGE 透明大页 mm/Kconfig:818 折叠/压缩延迟
NUMA_BALANCING 自动 NUMA 迁移 init/Kconfig:953 迁移引起的延迟
QUEUED_RWLOCKS 队列读写锁 kernel/Kconfig.locks:254 rwlock_t 换成 rwbase_rt
DRM_I915 Intel 集显驱动(x86;arm64 无关) drivers/gpu/drm/i915/Kconfig:6 驱动内大量不兼容 RT 的锁用法
KMSAN 未初始化内存检测 lib/Kconfig.kmsan:15
DEBUG_MUTEXES / DEBUG_RWSEMS 经典锁调试 lib/Kconfig.debug:1456, 1481 DEBUG_RT_MUTEXES
DEBUG_VM_IRQSOFF DEBUG_VM 的关中断子集 lib/Kconfig.debug:812 RT 下不关中断
SOFTIRQ_ON_OWN_STACK softirq 独立栈 arch/Kconfig:1046 softirq 在线程栈上
HIGHPTE(仅 32 位 arm) 二级页表放 highmem arch/arm/Kconfig:1232 arm64 无此项
LEDS_TRIGGER_CPU CPU 活动 LED drivers/leds/trigger/Kconfig:67 原子上下文更新

PROVE_LOCKING / LOCK_STAT / DEBUG_LOCK_ALLOC / DEBUG_WW_MUTEX_SLOWPATHselect DEBUG_MUTEXES if !PREEMPT_RTlib/Kconfig.debug:1356, 1358, 1420, 1466, 1490)与 select DEBUG_RT_MUTEXES if PREEMPT_RT:1467)随之切换。

强制 / 默认改变

符号 RT 下 位置 说明
RT_MUTEXES default y init/Kconfig:2026 所有睡眠锁的基底
PREEMPT_RCU default y if PREEMPTION kernel/rcu/Kconfig:20
RCU_BOOST default y,且不需要 RCU_EXPERT kernel/rcu/Kconfig:200-201
RCU_NOCB_CPU_CB_BOOST default y kernel/rcu/Kconfig:282 offload 回调用 FIFO
RCU_EXP_KTHREAD 默认关 kernel/rcu/Kconfig:227 加急 GP 启动后被禁
TASKS_TRACE_RCU_READ_MB default PREEMPT_RT kernel/rcu/Kconfig:298 屏障代替 IPI
EFI_DISABLE_RUNTIME default y drivers/firmware/efi/Kconfig:240-249 「测量表明某些 EFI 调用耗时过长」
COMPACT_UNEVICTABLE_DEFAULT 0(非 RT 1) mm/Kconfig:651 避免压缩引起缺页
DRM_MGAG200_DISABLE_WRITECOMBINE RT 专属选项 drivers/gpu/drm/mgag200/Kconfig:17 Write-Combine 干扰其它核上的 RT 任务
NET_RX_BUSY_POLL default y 仅当无 NETCONSOLE net/Kconfig:345

编译期固定的运行时行为

行为 非 RT RT 位置
force_irqthreads() static key,threadirqs 参数打开 恒 true,参数不存在 include/linux/interrupt.h:516-525kernel/irq/manage.c:27-35
rcutree.use_softirq 默认 1,可调 恒 0,参数不注册 kernel/rcu/tree.c:105-109
rcupdate.rcu_normal_after_boot 默认 0,可调 恒 1(无 NO_HZ_FULL 时不注册) kernel/rcu/update.c:60-62
irqfixup / irqpoll 可用 拒绝 kernel/irq/spurious.c:450-468
thread_backlog_napi 参数可开 恒开 net/core/dev.c:204-225
软 IRQ 合并默认 net/core/dev.c:11202-11210
TTWU_QUEUE / RT_PUSH_IPI / SCHED_NR_MIGRATE_BREAK true / false / 32 false / true / 8 kernel/sched/features.h:75-116kernel/sched/sched.h:2833-2837
cgroup v1 soft_limit_in_bytescgroup.event_control 可用 -EOPNOTSUPP mm/memcontrol-v1.c:1946-1947, 2576-2577
preempt= 启动参数 none/voluntary/full 无(没有 preempt=rt Documentation/admin-guide/kernel-parameters.txt:4826-4833

只是帮助文本提到 RT

6.12.107 没有的

ARM64 相关的 Kconfig(arch/arm64/Kconfig

符号 / 行 含义 对 RT 的意义
:105 select ARCH_SUPPORTS_RT arm64 可选 RT 本文成立的前提
:249 select IRQ_FORCED_THREADING 支持强制线程化 第 03 章
:237 select HAVE_POSIX_CPU_TIMERS_TASK_WORK POSIX CPU 定时器走 task_work 第 05 章
:235 select HAVE_PREEMPT_DYNAMIC_KEY DYNAMIC 用静态键 RT 下无效(DYNAMIC 与 RT 互斥)
:58-83 ARCH_INLINE_*_LOCK if !PREEMPTION 非抢占内核内联锁操作 RT 下全部 out-of-line
:101 / :191 ARCH_SUPPORTS_NUMA_BALANCING / HAVE_ARCH_TRANSPARENT_HUGEPAGE 两者在 RT 下都被上层 !PREEMPT_RT 砍掉
:224-225, 232 硬死锁检测器需 HAVE_PERF_EVENTS_NMI if ARM64_PSEUDO_NMI 要 NMI 看门狗必须开伪 NMI
:2292-2315 ARM64_PSEUDO_NMI / ARM64_DEBUG_PRIORITY_MASKING 伪 NMI 与其调试检查 调试选项每次开关中断多一次 PMR 读,延迟测试时关掉
:1372-1394 页大小 choice 4K / 16K / 64K 64K 页补偿 THP 缺失;:1678-1680 ARCH_FORCE_MAX_ORDER 随之变大(13/11/10)
:1527-1544 SCHED_MC / SCHED_CLUSTER / SCHED_SMT 调度拓扑 DynamIQ 集群感知
:128 select CPU_PM if (SUSPEND || CPU_IDLE) CPU 电源管理 与 PSCI idle 配合
drivers/cpuidle/Kconfig.arm:17-44 ARM_PSCI_CPUIDLE / _DOMAIN(default y) PSCI idle 驱动 RT 限制:27-33):分层 idle 布局下只有 per-CPU 状态可用,cluster 级状态不可用
drivers/firmware/efi/Kconfig:238-249 EFI_DISABLE_RUNTIME default y if PREEMPT_RT 对 arm64 UEFI 平台同样生效
drivers/firmware/Kconfig:31-38 ARM_SDE_INTERFACE SDEI(固件→OS 回调,RAS 通知) 固件侧干扰源
kernel/power/Kconfig:362 ENERGY_MODELarch/arm64/configs/defconfig:88 EAS 默认开 kernel/sched/topology.c:211, 317-322, 432 sched_energy_aware 可关
:1696 UNMAP_KERNEL_AT_EL0:1708 MITIGATE_SPECTRE_BRANCH_HISTORY KPTI 与 Spectre-BHB 缓解 入口开销(第 01 章);39 个 ARM64_ERRATUM_*:461-1142)部分会加屏障
:2005 ARM64_PTR_AUTH:2115 ARM64_BTI:2158 ARM64_E0PD:2178 ARM64_MTE:2249 ARM64_SVE:2280 ARM64_SME:2330 RANDOMIZE_BASE:2381 ARM64_CONTPTE 安全/向量扩展/大页连续 PTE MTE 同步模式与 SVE 状态切换有可见开销;其余可忽略
kernel/Kconfig.hz:8 default HZ_250arch/arm64/configs/defconfig:4, 8, 88 arm64 默认 HZ=250、NO_HZ_IDLEPREEMPT=yENERGY_MODEL=y RT 建议 HZ_1000 + NO_HZ_FULL
HIGHMEM、无 arch/arm64/include/asm/highmem.h 第 06 章的 kmap_atomic 议题在 arm64 不存在
select GENERIC_ENTRY 自有入口代码 第 01 章

性能影响

净影响:无运行时开销,但决定了能力边界(大页、NUMA、集显、EFI runtime、cgroup v1 软限制)。

Kconfig 差异本身不产生运行时开销,但它决定了能力边界:没有 THP 意味着 TLB 压力只能靠 hugetlbfs;没有 NUMA balancing 意味着跨节点访问要手工 numactl;EFI runtime 关闭意味着 efivarfs、固件更新工具不可用;DEBUG_MUTEXES 换成 DEBUG_RT_MUTEXES 意味着调试构建的开销特征不同。

源码定位

见上表;完整 34 处引用来自 grep -rn "PREEMPT_RT" --include=Kconfig*

调优要点

小结