From nobody Mon Feb 9 21:12:15 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 155255310618517.64611320331096; Thu, 14 Mar 2019 01:45:06 -0700 (PDT) Received: from localhost ([127.0.0.1]:59114 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h4Lz0-0000rY-VP for importer@patchew.org; Thu, 14 Mar 2019 04:44:59 -0400 Received: from eggs.gnu.org ([209.51.188.92]:54490) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h4LxE-0008Ef-AU for qemu-devel@nongnu.org; Thu, 14 Mar 2019 04:43:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h4LxC-0002QP-Nx for qemu-devel@nongnu.org; Thu, 14 Mar 2019 04:43:07 -0400 Received: from 4.mo179.mail-out.ovh.net ([46.105.36.149]:60018) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h4LxC-0002LU-DY for qemu-devel@nongnu.org; Thu, 14 Mar 2019 04:43:06 -0400 Received: from player762.ha.ovh.net (unknown [10.109.143.225]) by mo179.mail-out.ovh.net (Postfix) with ESMTP id 50C88121745 for ; Thu, 14 Mar 2019 09:43:03 +0100 (CET) Received: from kaod.org (lfbn-1-2226-17.w90-76.abo.wanadoo.fr [90.76.48.17]) (Authenticated sender: clg@kaod.org) by player762.ha.ovh.net (Postfix) with ESMTPSA id D8AE73AA2DBB; Thu, 14 Mar 2019 08:42:54 +0000 (UTC) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: Peter Maydell Date: Thu, 14 Mar 2019 09:42:31 +0100 Message-Id: <20190314084235.9887-2-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190314084235.9887-1-clg@kaod.org> References: <20190314084235.9887-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 1447625806499908369 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedutddrhedugdduvdefucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 46.105.36.149 Subject: [Qemu-devel] [PATCH 1/5] aspeed/timer: Fix behaviour running Linux X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrew Jeffery , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , qemu-arm@nongnu.org, Joel Stanley , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Joel Stanley The Linux kernel driver was updated in commit 4451d3f59f2a ("clocksource/drivers/fttmr010: Fix set_next_event handler) to fix an issue observed on hardware: > RELOAD register is loaded into COUNT register when the aspeed timer > is enabled, which means the next event may be delayed because timer > interrupt won't be generated until <0xFFFFFFFF - current_count + > cycles>. When running under Qemu, the system appeared "laggy". The guest is now scheduling timer events too regularly, starving the host of CPU time. This patch modifies the timer model to attempt to schedule the timer expiry as the guest requests, but if we have missed the deadline we re interrupt and try again, which allows the guest to catch up. Provides expected behaviour with old and new guest code. Fixes: c04bd47db6b9 ("hw/timer: Add ASPEED timer device model") Signed-off-by: Joel Stanley [clg: - merged a fix from Andrew Jeffery "Fire interrupt on failure to meet deadline" https://lists.ozlabs.org/pipermail/openbmc/2019-January/014641.html - adapted commit log - checkpatch fixes ] Signed-off-by: C=C3=A9dric Le Goater --- hw/timer/aspeed_timer.c | 59 ++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c index 5c786e512815..9ffd8e09f670 100644 --- a/hw/timer/aspeed_timer.c +++ b/hw/timer/aspeed_timer.c @@ -109,37 +109,40 @@ static inline uint64_t calculate_time(struct AspeedTi= mer *t, uint32_t ticks) =20 static uint64_t calculate_next(struct AspeedTimer *t) { - uint64_t next =3D 0; - uint32_t rate =3D calculate_rate(t); + uint64_t now =3D qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + uint64_t next; =20 - while (!next) { - /* We don't know the relationship between the values in the match - * registers, so sort using MAX/MIN/zero. We sort in that order as= the - * timer counts down to zero. */ - uint64_t seq[] =3D { - calculate_time(t, MAX(t->match[0], t->match[1])), - calculate_time(t, MIN(t->match[0], t->match[1])), - calculate_time(t, 0), - }; - uint64_t reload_ns; - uint64_t now =3D qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - - if (now < seq[0]) { - next =3D seq[0]; - } else if (now < seq[1]) { - next =3D seq[1]; - } else if (now < seq[2]) { - next =3D seq[2]; - } else if (t->reload) { - reload_ns =3D muldiv64(t->reload, NANOSECONDS_PER_SECOND, rate= ); - t->start =3D now - ((now - t->start) % reload_ns); - } else { - /* no reload value, return 0 */ - break; - } + /* + * We don't know the relationship between the values in the match + * registers, so sort using MAX/MIN/zero. We sort in that order as + * the timer counts down to zero. + */ + + next =3D calculate_time(t, MAX(t->match[0], t->match[1])); + if (now < next) { + return next; + } + + next =3D calculate_time(t, MIN(t->match[0], t->match[1])); + if (now < next) { + return next; + } + + next =3D calculate_time(t, 0); + if (now < next) { + return next; + } + + /* We've missed all deadlines, fire interrupt and try again */ + timer_del(&t->timer); + + if (timer_overflow_interrupt(t)) { + t->level =3D !t->level; + qemu_set_irq(t->irq, t->level); } =20 - return next; + t->start =3D qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + return calculate_time(t, MAX(MAX(t->match[0], t->match[1]), 0)); } =20 static void aspeed_timer_mod(AspeedTimer *t) --=20 2.20.1