VMs freezing after PVE8 → PVE9 upgrade — TSC marked unstable, HPET fallback causes cascading perf interrupt storm on EPYC 7401 nodes

Apr 9, 2026
1
0
1
Hi all,
I recently upgraded my cluster from PVE 8 to PVE 9 and I'm experiencing VM freezes that I've now partially diagnosed via the host journals. Posting for confirmation and to find a proper fix.

Environment
  • pve-manager/9.1.6/71482d1833ded40a
  • Kernel: Linux 6.17.13-2-pve (2026-03-13T08:06Z)
  • Enterprise repository, multi-node cluster
Affected nodes
NodeCPUAffected
proxmox-0 (Node 1)96 × AMD EPYC 7401 24-Core (2 Sockets)✅ Yes
proxmox-2 (Node 3)96 × AMD EPYC 7401 24-Core (2 Sockets)✅ Yes
Node 296 × AMD EPYC 7402 24-Core (2 Sockets)❌ No (running a debian vm)

Note on Node 2
Node 2 is currently running our core production application on a Debian VM, which has been completely stable since the PVE 9 upgrade. However, since this is a critical production workload, I'm not willing to migrate the problematic VMs to Node 2 to test whether the EPYC 7402 is genuinely the differentiating factor — the risk of introducing instability there is too high. The node comparison is therefore observational only.

Symptoms
After an unpredictable period (minutes to hours), VMs become completely unresponsive:
  • Proxmox console fails to connect or freezes on a single frame
  • VM web interfaces (e.g. pfSense) become unreachable
  • CPU usage for the affected VM spikes and stays elevated in the Proxmox UI
  • PSI (pressure stall information) spikes simultaneously
  • VM reset is unreliable (~50% success for pfSense); only a full node reboot reliably recovers
Affected guest OSes: pfSense (OpenBSD) and Alpine Linux — so this is not guest-OS specific.

Root cause finding — host journal
Both affected nodes show an identical sequence in journalctl -k immediately before each freeze:
Code:
kernel: clocksource: timekeeping watchdog on CPU16: Marking clocksource 'tsc' as unstable because the skew is too large:
kernel: clocksource: 'tsc' skewed 580600 ns (0 ms) over watchdog 'hpet' interval of 496033364 ns
kernel: tsc: Marking TSC unstable due to clocksource watchdog
kernel: TSC found unstable after boot, most likely due to broken BIOS. Use 'tsc=unstable'.
kernel: sched_clock: Marking unstable [...]
kernel: clocksource: Switched to clocksource hpet
Immediately after the HPET fallback, a cascading perf interrupt storm follows — the sample rate gets throttled down progressively from ~40 000 to 1 000 over the next ~15 minutes, and hrtimer interrupts are reported taking >1 ms:
Code:
kernel: perf: interrupt took too long (5557 > 4911), lowering kernel.perf_event_max_sample_rate to 35000
kernel: perf: interrupt took too long (7617 > 6946), lowering kernel.perf_event_max_sample_rate to 26000
...
kernel: hrtimer: interrupt took 1209720 ns
...
kernel: perf: interrupt took too long (115918 > 115180), lowering kernel.perf_event_max_sample_rate to 1000

This same pattern appears independently on both Node 1 and Node 3. Node 2 (EPYC 7402) does not show this behaviour at all.
My interpretation: The TSC becomes skewed (possibly due to cross-socket drift or a NUMA sync issue on the EPYC 7401), the kernel falls back to HPET, and HPET's much higher interrupt latency then causes the perf subsystem to spiral into an interrupt storm that effectively starves QEMU processes and locks up the VMs.

VM configs (relevant parts)
pfSense:
Code:
cpu: host
machine: pc-i440fx-8.1
sockets: 1
cores: 4
net0..net12: virtio, multiple VLANs with MTU 9000
scsi0: ceph-vm (iothread=1)
Alpine (bastion-0):
Code:
cpu: x86-64-v2-AES
sockets: 2
cores: 1
net0: virtio, mtu=1
scsi0: ceph-vm (iothread=1)

Questions
  1. Is there a known regression in kernel 6.17 or PVE 9 regarding TSC stability on EPYC Naples (Zen 1 / 7401)?
  2. Is adding tsc=unstable to the host kernel boot parameters the right mitigation, or is there a better approach (e.g. clocksource=hpet from the start, disabling TSC entirely)?
  3. Could the EPYC 7401's dual-socket TSC sync be the underlying cause? Both affected nodes are 2-socket systems and the drift appears cross-socket.
  4. Any known differences in how the 7401 and 7402 handle TSC synchronization that would explain why Node 2 is unaffected?
  5. Are there BIOS/firmware settings (TSC sync policy, C-states) known to help stabilise TSC on Naples-generation EPYC under newer PVE kernels?
Any insights appreciated. Happy to collect additional diagnostics.
 
I had have the same issue and I want to share the path that I go and the solution that worked for me.

My Promox-Cluster has three nodes 1 x AMD 3900 and 2x AMD 5600G. After the Migration from 8.2 to 9.2 the nodes with the AMD 5600G show high CPU-Usage and become unrespronsive. (The monitored VM show in Grafana Node Exporter "CPU busy other").

After installing the perf tool (apt install linux-perf) on the node and starting it with:

perf top

I get following output:
Code:
Samples: 47K of event 'cycles:P', 4000 Hz, Event count (approx.): 10521686522 lost: 0/0 drop: 0/0
Overhead  Shared Object                         Symbol
  10.80%  [kernel]                              [k] read_hpet
   4.79%  [kernel]                              [k] native_sched_clock
   2.94%  [kernel]                              [k] _copy_to_user


ChatGPT says:
  • read_hpet reads the High Precision Event Timer (HPET).
  • The fact that nearly 19% of the samples fall into this category is unusually high. This indicates that the system time is being queried very frequently or that the kernel is using the HPET as its time source. HPET accesses are relatively slow compared to the CPU timestamp counter (TSC).
Checking the clock source:
Code:
cat /sys/devices/system/clocksource/clocksource0/current_clocksource
hpet

And looking for log:
Code:
dmesg | grep -i tsc
[    0.000000] tsc: Fast TSC calibration using PIT
[    0.000000] tsc: Detected 3892.541 MHz processor
[    0.188905] clocksource: tsc-early: mask: 0xffffffffffffffff max_cycles: 0x7037a739c92, max_idle_ns: 881590545044 ns
[    0.446458] clocksource: Switched to clocksource tsc-early
[    1.494614] tsc: Refined TSC clocksource calibration: 3919.900 MHz
[    1.494627] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x71019232b77, max_idle_ns: 881590954696 ns
[    1.494674] clocksource: Switched to clocksource tsc
[    2.190581] clocksource: timekeeping watchdog on CPU3: Marking clocksource 'tsc' as unstable because the skew is too large:
[    2.190593] clocksource:                       'tsc' cs_nsec: 496013619 cs_now: 19fda9b094 cs_last: 1989c5ab2b mask: ffffffffffffffff
[    2.190595] clocksource:                       Clocksource 'tsc' skewed -3467320 ns (-3 ms) over watchdog 'hpet' interval of 499480939 ns (499 ms)
[    2.190597] clocksource:                       'tsc' is current clocksource.
[    2.190609] tsc: Marking TSC unstable due to clocksource watchdog
[    2.190633] TSC found unstable after boot, most likely due to broken BIOS. Use 'tsc=unstable'.
[    2.190824] clocksource: Checking clocksource tsc synchronization from CPU 2 to CPUs 0,4,6-8.
[    2.190858] clocksource:         CPU 2 check durations 2158ns - 10884ns for clocksource tsc.
[    4.774675] kvm_amd: TSC scaling supported
[   25.966118] kvm: SMP vm created on host with unstable TSC; guest TSC will not be reliable


The normal clocksource tsc is marked as unstable and is not used.

The hint for the problem is making an bios update, but I don't want it now and go another way:

Editing /etc/default/grub:

Code:
GRUB_CMDLINE_LINUX_DEFAULT="quiet clocksource=tsc tsc=reliable"

and make the following commands:

Code:
update-grub
update-initramfs -u -k all

After rebooting the system

Code:
dmesg | grep -i tsc
[    0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-7.0.14-5-pve root=/dev/mapper/pve-root ro quiet clocksource=tsc tsc=reliable
[    0.000000] tsc: Fast TSC calibration using PIT
[    0.000000] tsc: Detected 3892.674 MHz processor
[    0.072211] Kernel command line: BOOT_IMAGE=/boot/vmlinuz-7.0.14-5-pve root=/dev/mapper/pve-root ro quiet clocksource=tsc tsc=reliable
[    0.189215] clocksource: tsc-early: mask: 0xffffffffffffffff max_cycles: 0x7038a355cf6, max_idle_ns: 881590429099 ns
[    0.438215] clocksource: Switched to clocksource tsc-early
[    2.262623] tsc: Refined TSC clocksource calibration: 3920.033 MHz
[    2.262636] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x71028ebf016, max_idle_ns: 881590929694 ns
[    2.262679] clocksource: Switched to clocksource tsc
[    5.253479] kvm_amd: TSC scaling supported

Problem solved - I hope this helps!
 
Last edited: