[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 05/21] aspeed/timer: Provide back-pressure informatio
From: |
Peter Maydell |
Subject: |
[Qemu-devel] [PULL 05/21] aspeed/timer: Provide back-pressure information for short periods |
Date: |
Tue, 3 Sep 2019 16:36:17 +0100 |
From: Andrew Jeffery <address@hidden>
First up: This is not the way the hardware behaves.
However, it helps resolve real-world problems with short periods being
used under Linux. Commit 4451d3f59f2a ("clocksource/drivers/fttmr010:
Fix set_next_event handler") in Linux fixed the timer driver to
correctly schedule the next event for the Aspeed controller, and in
combination with 5daa8212c08e ("ARM: dts: aspeed: Describe random number
device") Linux will now set a timer with a period as low as 1us.
Configuring a qemu timer with such a short period results in spending
time handling the interrupt in the model rather than executing guest
code, leading to noticeable "sticky" behaviour in the guest.
The behaviour of Linux is correct with respect to the hardware, so we
need to improve our handling under emulation. The approach chosen is to
provide back-pressure information by calculating an acceptable minimum
number of ticks to be set on the model. Under Linux an additional read
is added in the timer configuration path to detect back-pressure, which
will never occur on hardware. However if back-pressure is observed, the
driver alerts the clock event subsystem, which then performs its own
next event dilation via a config option - d1748302f70b ("clockevents:
Make minimum delay adjustments configurable")
A minimum period of 5us was experimentally determined on a Lenovo
T480s, which I've increased to 20us for "safety".
Signed-off-by: Andrew Jeffery <address@hidden>
Reviewed-by: Joel Stanley <address@hidden>
Reviewed-by: Philippe Mathieu-Daudé <address@hidden>
Tested-by: Joel Stanley <address@hidden>
Signed-off-by: Cédric Le Goater <address@hidden>
Message-id: address@hidden
[clg: - changed the computation of min_ticks to be done each time the
timer value is reloaded. It removes the ordering issue of the
timer and scu reset handlers but is slightly slower ]
- introduced TIMER_MIN_NS
- introduced calculate_min_ticks() ]
Signed-off-by: Cédric Le Goater <address@hidden>
Signed-off-by: Peter Maydell <address@hidden>
---
hw/timer/aspeed_timer.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
index ed81d5c44c7..59c2bbeee60 100644
--- a/hw/timer/aspeed_timer.c
+++ b/hw/timer/aspeed_timer.c
@@ -44,6 +44,13 @@ enum timer_ctrl_op {
op_pulse_enable
};
+/*
+ * Minimum value of the reload register to filter out short period
+ * timers which have a noticeable impact in emulation. 5us should be
+ * enough, use 20us for "safety".
+ */
+#define TIMER_MIN_NS (20 * SCALE_US)
+
/**
* Avoid mutual references between AspeedTimerCtrlState and AspeedTimer
* structs, as it's a waste of memory. The ptimer BH callback needs to know
@@ -98,6 +105,14 @@ static inline uint32_t calculate_ticks(struct AspeedTimer
*t, uint64_t now_ns)
return t->reload - MIN(t->reload, ticks);
}
+static uint32_t calculate_min_ticks(AspeedTimer *t, uint32_t value)
+{
+ uint32_t rate = calculate_rate(t);
+ uint32_t min_ticks = muldiv64(TIMER_MIN_NS, rate, NANOSECONDS_PER_SECOND);
+
+ return value < min_ticks ? min_ticks : value;
+}
+
static inline uint64_t calculate_time(struct AspeedTimer *t, uint32_t ticks)
{
uint64_t delta_ns;
@@ -261,7 +276,7 @@ static void aspeed_timer_set_value(AspeedTimerCtrlState *s,
int timer, int reg,
switch (reg) {
case TIMER_REG_RELOAD:
old_reload = t->reload;
- t->reload = value;
+ t->reload = calculate_min_ticks(t, value);
/* If the reload value was not previously set, or zero, and
* the current value is valid, try to start the timer if it is
--
2.20.1
- [Qemu-devel] [PULL 00/21] target-arm queue, Peter Maydell, 2019/09/03
- [Qemu-devel] [PULL 01/21] Revert "target/arm: Use unallocated_encoding for aarch32", Peter Maydell, 2019/09/03
- [Qemu-devel] [PULL 02/21] target/arm: Factor out unallocated_encoding for aarch32, Peter Maydell, 2019/09/03
- [Qemu-devel] [PULL 03/21] target/arm: Allow ARMCPRegInfo read/write functions to throw exceptions, Peter Maydell, 2019/09/03
- [Qemu-devel] [PULL 05/21] aspeed/timer: Provide back-pressure information for short periods,
Peter Maydell <=
- [Qemu-devel] [PULL 06/21] memory: Remove unused memory_region_iommu_replay_all(), Peter Maydell, 2019/09/03
- [Qemu-devel] [PULL 08/21] hw/arm/smmuv3: Remove spurious error messages on IOVA invalidations, Peter Maydell, 2019/09/03
- [Qemu-devel] [PULL 04/21] target/arm: Take exceptions on ATS instructions when needed, Peter Maydell, 2019/09/03
- [Qemu-devel] [PULL 07/21] hw/arm/smmuv3: Log a guest error when decoding an invalid STE, Peter Maydell, 2019/09/03
- [Qemu-devel] [PULL 09/21] target/arm: Fix SMMLS argument order, Peter Maydell, 2019/09/03
- [Qemu-devel] [PULL 10/21] hw/arm: Use ARM_CPU_TYPE_NAME() macro when appropriate, Peter Maydell, 2019/09/03
- [Qemu-devel] [PULL 12/21] hw/arm: Use sysbus_init_child_obj for correct reference counting, Peter Maydell, 2019/09/03
- [Qemu-devel] [PULL 11/21] hw/arm: Use object_initialize_child for correct reference counting, Peter Maydell, 2019/09/03
- [Qemu-devel] [PULL 13/21] hw/arm/fsl-imx: Add the cpu as child of the SoC object, Peter Maydell, 2019/09/03