[PATCH RFC 09/11] um: Delay timer_read in time travel mode only after consecutive reads

Benjamin Beichler
2023-11-03T16:42:26Z

Given the presence of numerous timer_read calls in well-behaved code
within the kernel and userspace, particularly those that do not employ
busy loops, we introduce a delay in reading the timer only after several
consecutive attempts (currently set at 10).

Unfortunately, it is challenging to differentiate between various
callers and pinpoint specific misbehaving code, so this is only a
mediocre heuristic.

Signed-off-by: Benjamin Beichler <benjamin.beichler@uni-rostock.de>
---
arch/um/kernel/time.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index f1b2ca45994d..f76237cfc1ea 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -723,6 +723,9 @@ static irqreturn_t um_timer(int irq, void *dev)

static u64 timer_read(struct clocksource *cs)
{
+ static unsigned long long last_timer_read;
+ static int consecutive_calls_at_same_time;
+
if (time_travel_mode != TT_MODE_OFF) {
/*
* We make reading the timer cost a bit so that we don't get
@@ -736,8 +739,14 @@ static u64 timer_read(struct clocksource *cs)
* "what do I do next" and onstack event we use to know when
* to return from time_travel_update_time().
*/
+ if (last_timer_read != time_travel_time) {
+ last_timer_read = time_travel_time;
+ consecutive_calls_at_same_time = 0;
+ } else {
+ consecutive_calls_at_same_time++;
+ }
if (!irqs_disabled() && !in_interrupt() && !in_softirq() &&
- !time_travel_ext_waiting)
+ !time_travel_ext_waiting && consecutive_calls_at_same_time > 10)
time_travel_update_time(time_travel_time +
TIMER_MULTIPLIER,
false);

--
2.34.1