mirror of
https://git.proxmox.com/git/pve-qemu
synced 2025-08-18 03:14:42 +00:00

As reported in the community forum [0][1], QEMU processes for Linux guests would consume more CPU on the host after an update to QEMU 9.2. The issue was reproduced and bisecting pointed to QEMU commit f0ccf77078 ("hpet: fix and cleanup persistence of interrupt status"). Some quick experimentation suggests that in particular the last part is responsible for the issue: > - the timer must be kept running even if not enabled, in > order to set the ISR flag, so writes to HPET_TN_CFG must > not call hpet_del_timer() Users confirmed that setting the hpet=off machine flag works around the issue[0]. For Windows (7 or later) guests, the flag is already disabled, because of issues in the past [2]. Upstream suggested reverting the relevant patches for now [3], because other issues were reported too. All except commit 5895879aca ("hpet: remove unnecessary variable "index"") are actually dependent on each other for cleanly reverting f0ccf77078, and while not strictly required, that one was reverted too for completeness. [0]: https://forum.proxmox.com/threads/163694/ [1]: https://forum.proxmox.com/threads/161849/post-756793 [2]: https://lists.proxmox.com/pipermail/pve-devel/2012-December/004958.html [3]: https://lore.kernel.org/qemu-devel/CABgObfaKJ5NFVKmYLFmu4C0iZZLJJtcWksLCzyA0tBoz0koZ4A@mail.gmail.com/ Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
51 lines
1.8 KiB
Diff
51 lines
1.8 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Fiona Ebner <f.ebner@proxmox.com>
|
|
Date: Wed, 19 Mar 2025 17:31:05 +0100
|
|
Subject: [PATCH] Revert "hpet: avoid timer storms on periodic timers"
|
|
|
|
This reverts commit 7c912ffb59e8137091894d767433e65c3df8b0bf.
|
|
|
|
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
|
---
|
|
hw/timer/hpet.c | 13 ++-----------
|
|
1 file changed, 2 insertions(+), 11 deletions(-)
|
|
|
|
diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c
|
|
index 5399f1b2a3..8ccc421cbb 100644
|
|
--- a/hw/timer/hpet.c
|
|
+++ b/hw/timer/hpet.c
|
|
@@ -59,7 +59,6 @@ typedef struct HPETTimer { /* timers */
|
|
uint8_t wrap_flag; /* timer pop will indicate wrap for one-shot 32-bit
|
|
* mode. Next pop will be actual timer expiration.
|
|
*/
|
|
- uint64_t last; /* last value armed, to avoid timer storms */
|
|
} HPETTimer;
|
|
|
|
struct HPETState {
|
|
@@ -267,7 +266,6 @@ static int hpet_post_load(void *opaque, int version_id)
|
|
for (i = 0; i < s->num_timers; i++) {
|
|
HPETTimer *t = &s->timer[i];
|
|
t->cmp64 = hpet_calculate_cmp64(t, s->hpet_counter, t->cmp);
|
|
- t->last = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - NANOSECONDS_PER_SECOND;
|
|
}
|
|
/* Recalculate the offset between the main counter and guest time */
|
|
if (!s->hpet_offset_saved) {
|
|
@@ -366,15 +364,8 @@ static const VMStateDescription vmstate_hpet = {
|
|
|
|
static void hpet_arm(HPETTimer *t, uint64_t tick)
|
|
{
|
|
- uint64_t ns = hpet_get_ns(t->state, tick);
|
|
-
|
|
- /* Clamp period to reasonable min value (1 us) */
|
|
- if (timer_is_periodic(t) && ns - t->last < 1000) {
|
|
- ns = t->last + 1000;
|
|
- }
|
|
-
|
|
- t->last = ns;
|
|
- timer_mod(t->qemu_timer, ns);
|
|
+ /* FIXME: Clamp period to reasonable min value? */
|
|
+ timer_mod(t->qemu_timer, hpet_get_ns(t->state, tick));
|
|
}
|
|
|
|
/*
|