[PATCH] lib: sbi_pmu: fix mapping reset for already stopped counters
Fengwei Tan
tfx2001 at outlook.com
Sat Oct 3 08:18:06 PDT 2026
Linux stops a counter before issuing another stop with RESET flag when
deleting an event [1]. Returning early on SBI_EALREADY_STOPPED skips
counter-to-event mapping reset, eventually exhausting the hardware
counters.
Continue the stop and reset process for the remaining counters when a
counter in the set is already stopped. Preserve SBI_EALREADY_STOPPED in
the final result, while still returning immediately on other errors.
[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/perf/riscv_pmu.c?id=72d3fcf802c45d00b300f25b848a93c3a2bd7c7e#n318
Fixes: c5077d497d0f ("lib: sbi_pmu: Fix counter and event info error codes as per SBI v3.0 spec")
Signed-off-by: Fengwei Tan <tfx2001 at outlook.com>
---
This patch fixes a regression introduced by c5077d497d0f ("lib: sbi_pmu:
Fix counter and event info error codes as per SBI v3.0 spec"), where the
counter-to-event mapping reset is skipped if a counter in the set is
already stopped. This eventually exhausts the hardware counters.
The sbi_pmu_ctr_start() path is left unchanged as it doesn't seem to hit
any issue, but please let me know if I missed anything and I will follow
up with a v2.
---
lib/sbi/sbi_pmu.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/lib/sbi/sbi_pmu.c b/lib/sbi/sbi_pmu.c
index b4abfa1e..fbc66e2b 100644
--- a/lib/sbi/sbi_pmu.c
+++ b/lib/sbi/sbi_pmu.c
@@ -696,6 +696,7 @@ int sbi_pmu_ctr_stop(unsigned long cbase, unsigned long cmask,
int event_idx_type;
uint32_t event_code;
int i, cidx;
+ bool any_already_stopped = false;
if (!pmu_ctr_idx_validate(cbase, cmask))
return ret;
@@ -718,8 +719,11 @@ int sbi_pmu_ctr_stop(unsigned long cbase, unsigned long cmask,
else
ret = pmu_ctr_stop_hw(cidx);
- if(ret)
+ if (ret == SBI_EALREADY_STOPPED) {
+ any_already_stopped = true;
+ } else if (ret) {
return ret;
+ }
if (cidx > (CSR_INSTRET - CSR_CYCLE) && flag & SBI_PMU_STOP_FLAG_RESET) {
phs->active_events[cidx] = SBI_PMU_EVENT_IDX_INVALID;
@@ -731,6 +735,10 @@ int sbi_pmu_ctr_stop(unsigned long cbase, unsigned long cmask,
if (phs->sse_enabled)
csr_clear(CSR_MIP, sbi_pmu_irq_mask());
+ if (!ret && any_already_stopped) {
+ ret = SBI_EALREADY_STOPPED;
+ }
+
return ret;
}
---
base-commit: a50211e908af9017f316361f89a04ad9446cb330
change-id: 20261003-fix-pmu-counter-reset-failed-777e5d62d5de
Best regards,
--
Fengwei Tan <tfx2001 at outlook.com>
More information about the opensbi
mailing list