[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20251110-arm_spe_fix_truncated_flag-v2-2-a629740985cc@arm.com>
Date: Mon, 10 Nov 2025 16:28:32 +0000
From: Leo Yan <leo.yan@....com>
To: Will Deacon <will@...nel.org>, Mark Rutland <mark.rutland@....com>,
Alexandru Elisei <alexandru.elisei@....com>,
James Clark <james.clark@...aro.org>
Cc: linux-arm-kernel@...ts.infradead.org, linux-perf-users@...r.kernel.org,
linux-kernel@...r.kernel.org, Leo Yan <leo.yan@....com>
Subject: [PATCH v2 2/2] perf: arm_spe: Ensure profiling buffer is properly
disabled
During interrupt handling, if arm_spe_perf_aux_output_begin() fails to
calculate a valid limit, it queues the disable callback in the IRQ work
and sets the PERF_HES_STOPPED flag.
Afterwards, the disable callback arm_spe_pmu_stop() is invoked, but
since the PERF_HES_STOPPED flag has already been set, arm_spe_pmu_stop()
exits immediately. As a result, the profiling buffer is not properly
stopped — profiling on exception levels is not disabled, and buffered
data is not drained.
To fix this, explicitly disable the profiling buffer for stopped events
in the interrupt handler.
Fixes: d5d9696b0380 ("drivers/perf: Add support for ARMv8.2 Statistical Profiling Extension")
Signed-off-by: Leo Yan <leo.yan@....com>
---
drivers/perf/arm_spe_pmu.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c
index fc8f908c2c3a270f2d1ae574c2badb1fbcf51484..4f51510d5f8a660c12e3934eae8a66f1a1416617 100644
--- a/drivers/perf/arm_spe_pmu.c
+++ b/drivers/perf/arm_spe_pmu.c
@@ -761,6 +761,20 @@ static irqreturn_t arm_spe_pmu_irq_handler(int irq, void *dev)
if (!(handle->aux_flags & PERF_AUX_FLAG_TRUNCATED)) {
arm_spe_perf_aux_output_begin(handle, event);
isb();
+
+ /*
+ * A non-zero state indicates that an error occurred in
+ * arm_spe_perf_aux_output_begin(), for example, if the
+ * buffer overflowed and failed to get a valid limit.
+ *
+ * Since the PERF_HES_STOPPED flag has been set, the
+ * afterwards disable callback exits immediately and
+ * the buffer disable flow is skipped (see
+ * arm_spe_pmu_stop()). Explicitly disable the profiling
+ * buffer here.
+ */
+ if (event->hw.state)
+ arm_spe_pmu_disable_and_drain_local();
}
break;
case SPE_PMU_BUF_FAULT_ACT_SPURIOUS:
--
2.34.1
Powered by blists - more mailing lists