Commit 8ba0b706 authored by Dapeng Mi's avatar Dapeng Mi Committed by Peter Zijlstra
Browse files

perf/x86/intel: Always reprogram ACR events to prevent stale masks



Members of an ACR group are logically linked via a bitmask of their
hardware counter indices. If some members of the group are assigned new
hardware counters during rescheduling, even events that keep their
original counter index must be updated with a new mask.

Without this, an event will continue to use a stale acr_mask that
references the old indices of its group peers. Ensure all ACR events are
reprogrammed during the scheduling path to maintain consistency across
the group.

Fixes: ec980e4f ("perf/x86/intel: Support auto counter reload")
Signed-off-by: default avatarDapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260430002558.712334-3-dapeng1.mi@linux.intel.com
parent 5ad732a5
Loading
Loading
Loading
Loading
+8 −5
Original line number Diff line number Diff line
@@ -1294,13 +1294,16 @@ int x86_perf_rdpmc_index(struct perf_event *event)
	return event->hw.event_base_rdpmc;
}

static inline int match_prev_assignment(struct hw_perf_event *hwc,
static inline int match_prev_assignment(struct perf_event *event,
					struct cpu_hw_events *cpuc,
					int i)
{
	struct hw_perf_event *hwc = &event->hw;

	return hwc->idx == cpuc->assign[i] &&
	       hwc->last_cpu == smp_processor_id() &&
		hwc->last_tag == cpuc->tags[i];
	       hwc->last_tag == cpuc->tags[i] &&
	       !is_acr_event_group(event);
}

static void x86_pmu_start(struct perf_event *event, int flags);
@@ -1346,7 +1349,7 @@ static void x86_pmu_enable(struct pmu *pmu)
			 * - no other event has used the counter since
			 */
			if (hwc->idx == -1 ||
			    match_prev_assignment(hwc, cpuc, i))
			    match_prev_assignment(event, cpuc, i))
				continue;

			/*
@@ -1367,7 +1370,7 @@ static void x86_pmu_enable(struct pmu *pmu)
			event = cpuc->event_list[i];
			hwc = &event->hw;

			if (!match_prev_assignment(hwc, cpuc, i))
			if (!match_prev_assignment(event, cpuc, i))
				x86_assign_hw_event(event, cpuc, i);
			else if (i < n_running)
				continue;