“timekeeping watchdog expired”是内核检测到clocksource严重失准而触发的硬性中断,导致时间跳变;常见于TSC不稳定、BIOS电源管理启用、虚拟机未正确配置invtsc或kvm-clock等场景。

timekeeping watchdog expired 是什么信号
这个内核日志不是普通警告,而是 timekeeping 子系统检测到 clocksource 严重失准的硬性中断:内核连续多次无法在预期窗口内读取到稳定、单调递增的时间源值,于是触发 watchdog 并强制 fallback 到更保守的 clocksource(如 jiffies),同时可能重置 tk_core 状态——这直接导致 getnstimeofday() 或 ktime_get_real() 返回值突变,表现为系统时间跳跃(向前或向后几十毫秒到数秒)。
物理机上最常出问题的 clocksource 和对应检查项
Linux 默认优先使用 tsc(Time Stamp Counter),但它依赖 CPU 频率稳定和跨核 TSC 同步。常见失效场景包括:
-
cpupower frequency-set -g powersave类动态调频策略会令 TSC 不可靠,需确认 BIOS 中关闭Intel SpeedStep/AMD Cool'n'Quiet,或内核启动加intel_idle.max_cstate=1 - 多路服务器若未启用
invariant_tsc(现代 CPU 一般支持),且 BIOS 中禁用了TSC Deadline Timer或HPET,tsc可能被降级为hpet或acpi_pm,而后者精度低、延迟高,易触发 watchdog - 用
cat /sys/devices/system/clocksource/clocksource0/current_clocksource查当前源;用dmesg | grep -i "clocksource.*switch"看是否发生过 fallback
KVM/QEMU 虚拟机里 timekeeping 失效的典型原因
虚拟机不直接访问物理 TSC,其 clocksource 完全由宿主机 vCPU 模拟提供,因此问题往往藏在配置链路上:
- 宿主机未启用
invariant_tsc,且 QEMU 启动时没加-cpu ...,+invtsc,会导致 guest 内tsc不可作为 stable clocksource - guest 内核启动参数遗漏
clocksource=tsc tsc=reliable,即使宿主机支持,guest 也可能因探测失败而退回到acpi_pm - 使用
virtio-vga或qxl显卡时,QEMU 的图形线程抢占 vCPU 时间片,间接干扰 clocksource 读取周期,建议改用virtio-gpu或禁用 GUI(-nographic) - 检查 guest 是否启用了
CONFIG_KVM_CLOCK(应为 y),并确认/sys/devices/system/clocksource/clocksource0/available_clocksource中含kvm-clock
快速验证和临时缓解手段
不能立刻改 BIOS 或重装内核时,可用以下方式缩小范围并稳住时间:
- 立即切换 clocksource:
echo tsc > /sys/devices/system/clocksource/clocksource0/current_clocksource(仅当tsc在 available 列表中) - 禁用 watchdog(仅调试用):
echo 0 > /proc/sys/kernel/timekeeping_watchdog_enabled,但会掩盖底层硬件问题 - 对虚拟机,宿主机执行
virsh domtime guest-name --set realtime=1强制同步 host 实时钟(注意:不解决 clocksource 本身漂移) - 关键业务务必开启
chronyd并配置makestep 1.0 -1,避免 NTP 自身因时间跳变拒绝校正
真正稳定的 timekeeping 依赖硬件能力、固件设置、hypervisor 配置、内核参数四层对齐,缺一不可。最容易被忽略的是 BIOS 中那些看似无关的电源管理选项,它们常常是 timekeeping watchdog expired 的沉默推手。











