]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
sched: Don't account irq time if sched_clock_irqtime is disabled
authorYafang Shao <laoar.shao@gmail.com>
Fri, 3 Jan 2025 02:24:07 +0000 (10:24 +0800)
committerPeter Zijlstra <peterz@infradead.org>
Mon, 13 Jan 2025 13:10:25 +0000 (14:10 +0100)
sched_clock_irqtime may be disabled due to the clock source, in which case
IRQ time should not be accounted. Let's add a conditional check to avoid
unnecessary logic.

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Michal Koutný <mkoutny@suse.com>
Reviewed-by: Vincent Guittot <vincent.guittot@linaro.org>
Link: https://lore.kernel.org/r/20250103022409.2544-3-laoar.shao@gmail.com
kernel/sched/core.c

index 84902936a6204677e8a00a4a6f54f7f11ab3e236..22dfcd3e92ed2fd30b7992cf35219580971ef9ea 100644 (file)
@@ -740,29 +740,31 @@ static void update_rq_clock_task(struct rq *rq, s64 delta)
        s64 __maybe_unused steal = 0, irq_delta = 0;
 
 #ifdef CONFIG_IRQ_TIME_ACCOUNTING
-       irq_delta = irq_time_read(cpu_of(rq)) - rq->prev_irq_time;
+       if (irqtime_enabled()) {
+               irq_delta = irq_time_read(cpu_of(rq)) - rq->prev_irq_time;
 
-       /*
-        * Since irq_time is only updated on {soft,}irq_exit, we might run into
-        * this case when a previous update_rq_clock() happened inside a
-        * {soft,}IRQ region.
-        *
-        * When this happens, we stop ->clock_task and only update the
-        * prev_irq_time stamp to account for the part that fit, so that a next
-        * update will consume the rest. This ensures ->clock_task is
-        * monotonic.
-        *
-        * It does however cause some slight miss-attribution of {soft,}IRQ
-        * time, a more accurate solution would be to update the irq_time using
-        * the current rq->clock timestamp, except that would require using
-        * atomic ops.
-        */
-       if (irq_delta > delta)
-               irq_delta = delta;
+               /*
+                * Since irq_time is only updated on {soft,}irq_exit, we might run into
+                * this case when a previous update_rq_clock() happened inside a
+                * {soft,}IRQ region.
+                *
+                * When this happens, we stop ->clock_task and only update the
+                * prev_irq_time stamp to account for the part that fit, so that a next
+                * update will consume the rest. This ensures ->clock_task is
+                * monotonic.
+                *
+                * It does however cause some slight miss-attribution of {soft,}IRQ
+                * time, a more accurate solution would be to update the irq_time using
+                * the current rq->clock timestamp, except that would require using
+                * atomic ops.
+                */
+               if (irq_delta > delta)
+                       irq_delta = delta;
 
-       rq->prev_irq_time += irq_delta;
-       delta -= irq_delta;
-       delayacct_irq(rq->curr, irq_delta);
+               rq->prev_irq_time += irq_delta;
+               delta -= irq_delta;
+               delayacct_irq(rq->curr, irq_delta);
+       }
 #endif
 #ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING
        if (static_key_false((&paravirt_steal_rq_enabled))) {