[PATCH] perf/core: Update cgroup time when rotating multiplexed events
From: Antoine Huret via B4 Relay
Date: Thu Oct 15 2026 - 09:18:59 EST
From: Antoine Huret <antoine.huret@xxxxxxxx>
Since commit bd2756811766 ("perf: Rewrite core context handling"),
perf_rotate_context() only updates the context time before scheduling
out the flexible events. It no longer updates the cgroup time, which
ctx_sched_out() used to do.
Cgroup events take their times from the per-cpu cgroup clock, so
between two cgroup switches the rotations see a frozen clock. The
events rotated out lose the running time they accumulated, and the next
update, usually a read, credits the whole interval to the events that
happen to be on the PMU at that moment.
As a result, the time_running of multiplexed cgroup events is wrong,
and so are their scaled counts, as long as no other cgroup runs on the
CPU, e.g. a busy job alone on its CPUs. Counting cycles over one second
of a busy loop in a cgroup gives from half to several times the max
frequency of the CPU.
Update the cgroup time before rotating the CPU context, as was done
before the rewrite.
Fixes: bd2756811766 ("perf: Rewrite core context handling")
Closes: https://lore.kernel.org/r/PR3PR07MB69223331EED5BEBE150375B7849C2@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Antoine Huret <antoine.huret@xxxxxxxx>
---
The reproducer and the results are in the report linked by the Closes:
tag. Tested on v7.3-rc7: multiplexed cgroup events read correct values
again. The culprit was confirmed by testing bd2756811766 and its parent
(v6.1-rc2).
Peter suggested a cleanup using ctx_time_update() in the rotation, to
go on top of this minimal fix.
---
kernel/events/core.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 7846d70be..971cd4b49 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -4639,6 +4639,7 @@ static bool perf_rotate_context(struct perf_cpu_pmu_context *cpc)
if (cpu_event) {
update_context_time(&cpuctx->ctx);
+ update_cgrp_time_from_cpuctx(cpuctx, false);
__pmu_ctx_sched_out(cpu_epc, EVENT_FLEXIBLE);
rotate_ctx(&cpuctx->ctx, cpu_event);
__pmu_ctx_sched_in(cpu_epc, EVENT_FLEXIBLE);
---
base-commit: 357e8a77a501d96c9517f01f4a211eed5e9c9184
change-id: 20261015-perf-cgroup-rotation-time-5bc3b5a74daa
Best regards,
--
Antoine Huret <antoine.huret@xxxxxxxx>