我正在一个新系统上运行一个相当新的 17.10 安装(已完全修补,未虚拟化),并注意到 条目中列出的启动时间/proc/stat
一直btime
在变化。这破坏了一些使用此信息来计算某些进程启动的挂钟时间的脚本。
经过一些调试,我发现btime
计算为now() - uptime
,并且btime
漂移是由于系统时钟的增量速率与正常运行时间时钟的增量速率不同!
systemd-timesyncd.service
我假设这是由于(即替换)对系统时钟施加了某种时钟偏移ntpd
,因此我禁用timesyncd
并重新启动,作为测试。果然,现在正常运行时间计数器和系统时钟以相同的速率步进。(我还安装了adjtimex
检查内核参数以验证没有时钟偏差:没有frequency
应用偏差并且tick
值为 10000,正如它应该的那样。)
但是,如果不timesyncd
打开,很明显系统时钟非常不正常。时钟在 135 分钟内损失了大约 5 分钟(~ -37000 ppm),这与我adjtimex -l -w
在大约 20 分钟内手动估计系统时钟漂移的结果相似(它给出 ~ -40000 ppm)。(事实上,只是为了检查,使用秒表,我发现它/proc/uptime
也以错误的速率递增;~ -41000 ppm。所以这是一致的。)
CMOS时钟是也有点偏差(在 135 分钟内增加了 30 秒),但我的理解是,除了启动时,这不会影响系统时钟。/etc/adjtime
我找不到任何文件可以在启动时更改系统时钟速率——而且无论如何,如上所述,adjtimex
报告称没有时钟滴答作弊。所以我无法想象 CMOS 时钟如何导致我看到的系统时钟问题。
尽管如此,我还是会更换 CMOS 电池,因为一些报告有人认为这可以奇迹般地修复系统时钟问题。(尽管没有明显的机制可以实现这一点。)
但是,对于系统时钟为什么会如此错误,还有其他解释吗?对于系统计时器偏差如此之大,有什么解决方案吗?显然,仅仅运行并timesyncd
不能解决问题,因为它产生的过度时钟摆动是有问题的(如上所述)。
我可以adjtimex
直接更改内核参数(这至少应该能让正常运行时间和系统时钟计数器保持同步),但这实际上是为了解决 +- 500 ppm 范围内的时钟误差。我看到的误差大了 3 个数量级,我想知道这是否表明存在一些更重要的问题。
记录显示,我在一台非常相似的机器上安装的 17.10 没有这个问题。
更新:更换 CMOS 电池没有起到任何作用(正如所怀疑的那样)。请参阅下文了解问题的最终解决方案。
答案1
事实证明问题出在 TSC 时钟源上。短期内,将时钟源更改为“hpet”(通过 临时更改,或通过 中的内核启动参数echo hpet > /sys/devices/system/clocksource/clocksource0/current_clocksource
永久更改)可以解决此问题。clocksource=hpet
/etc/default/grub
更广泛地说,这个问题是由于 Linux 内核的 TSC 处理与 Skylake X 台式机 CPU 相关的错误造成的。这个问题应该在即将发布的内核版本。
更新:使用上述补丁中的一行修复重建当前内核确实可以恢复正确的 TSC 行为。
答案2
解决此问题的最佳方法是(如果本地连接)安装本地 NTP 服务器,并通过在“/etc/init.d/rc.local”文件中写入代码,无限循环重启 ntp 服务,休眠时间约为 30 秒。重启后系统时间将与服务器计算机同步。