1. Linux 如何查看支持的时钟源和正在使用的时钟源

在 Linux 内核时间子系统(timekeeping)里,clocksource 表示内核用来累计时间的“基准计时器”(对比 clockevent 用来产生周期性中断)。

在支持 sysfs 的系统上,可以直接读取 clocksource 相关文件:

1.1 当前正在使用的时钟源

cat /sys/devices/system/clocksource/clocksource0/current_clocksource

输出的就是当前启用的 clocksource 名称(例如常见会看到 tschpetacpi_pmkvm-clock 等,具体取决于平台与内核选择逻辑)。

1.2 支持/可用的时钟源

cat /sys/devices/system/clocksource/clocksource0/available_clocksource

available_clocksource 通常以空格或换行方式列出当前系统“已注册/可用”的 clocksource 列表。

如果机器可能存在多个 clocksource 目录,也可以直接列出所有可读目录后逐个查看(一般只会有 clocksource0):

ls /sys/devices/system/clocksource/

1.3 通过内核日志交叉验证(选择过程)

内核在启动与必要时切换 clocksource 时,会在日志里打印相关信息。可以用关键字过滤:

dmesg | grep -i "clocksource"

1.4 不依赖 sysfs 的补充:查看计时/定时器信息

/proc/timer_list 更偏向“计时器/clockevent”视角,但有时也能辅助判断时间子系统是否正常工作。可以作为补充排查手段:

cat /proc/timer_list

1.5 内核选择 clocksource 的思路(以实时场景为例)

在 multiprocessor(SMP/NUMA)系统中,内核会在启动阶段发现可用 clock sources,并为当前场景选择一个合适的 clocksource 来累计时间。

在 Red Hat 的参考中,preferred 的选择通常是:

  • 优先:TSC
  • 次选:HPET

如果系统缺少 TSCHPET,才会考虑其它来源,例如 ACPI_PMPITRTC 等。其中 PITRTC 由于“读取开销较大或分辨率较低”,在(尤其是)实时内核场景里属于次优选项。

如果你的系统支持手动切换,可以写入:

echo hpet > /sys/devices/system/clocksource/clocksource0/current_clocksource

同时,Red Hat 也强调:内核会自动选择“最佳可用 clocksource”,除非你非常确定影响,否则不建议强行覆盖选择。

2. PIT 时钟源有哪些问题

PIT 指 x86 经典硬件计时器(8254/8253 Programmable Interval Timer)。在 Linux 里,PIT 可能会被用作 clocksource(也可能仅作为早期/校准/兜底方案)。它的主要问题通常集中在“可用性、并发稳定性、精度与校准、以及平台电源/芯片特性”。

2.1 PIT 在 SMP 上可能出现锁死/活锁(历史已知问题)

在多核(SMP)场景下,PIT 的访问/读取涉及对 i8253/PIT 相关资源的锁保护;在特定时序条件下可能触发活锁/锁死类问题。

因此内核后来会在 SMP 场景下更倾向于禁用/降低 PIT 作为 clocksource 的优先级(例如“仅 UP/单核环境更可能用 PIT”这类策略)。

2.2 现代平台可能对 8254 进行 clock gating / 禁用

部分较新的 Intel 平台为省电,可能会把 8254 PIT 做时钟门控(clock gating)。表现通常是:寄存器看起来仍可配置,但 PIT 无法按预期产生 IRQ0 定时中断。

当内核在早期时间初始化阶段依赖 PIT(或 PIT 相关校准流程)且 PIT 实际不可用时,可能导致启动失败甚至内核 panic(常见报错会与 APIC + timer 初始化失败相关)。

这类问题的常见处理方式是:BIOS/固件侧关闭“8254 clock gating”(如果提供该选项),或依赖内核侧补丁/替代时钟源初始化逻辑来避开 PIT 初始化。

2.3 精度/抖动与校准更容易受干扰

PIT 的读写需要通过端口访问(IO 操作),相对 TSC/HPET 等更现代的计时器,PIT 在校准与读计数时更容易受到:

  • 中断/调度延迟
  • SMI/SMM 等固件阶段打断
  • 读取延迟波动

这些因素会让 PIT 参与的校准算法更不稳定,从而表现为更大的抖动(jitter)或校准失败/误校准的风险。最终内核通常更倾向选择稳定性更好的 clocksource(如 TSC/HPET/ACPI PM 等)。

2.4 性能与可扩展性:IO 访问开销

作为 legacy 计时器,PIT 在高频率访问/轮询读取时会带来额外开销;这也是为什么当系统存在更合适的时钟源时,PIT 往往不会被作为首选。

2.5 为什么 PIT 在实时时间戳场景里往往不被优先

从 Red Hat 的描述来看,PIT 相比 TSC/HPET 的典型短板在于:

  • 读取成本更高(需要更“贵”的硬件访问/时序开销)
  • 分辨率/时间粒度更难满足高频时间戳需求

因此即使内核在某些机器上最终“能用 PIT”,在强调低抖动与高吞吐的场景中,选择 PIT 往往意味着更高的时间戳开销或更差的时间粒度表现。

3. 小结

在 Linux 上:

  • 看“正在使用的 clocksource”优先读 current_clocksource
  • 看“支持/可用的 clocksource”读 available_clocksource
  • 需要更深入排查时,用 dmesg | rg -i clocksource 看内核选择/切换过程

在 PIT 方面:

  • 历史上 SMP 下存在活锁/锁死风险
  • 现代平台可能对 PIT 做 clock gating,导致内核早期时间初始化失败
  • PIT 参与校准时更容易受 IO 访问延迟、固件打断影响

4. 参考资料