[PATCH] lib: sbi_pmu: fix mapping reset for already stopped counters
Anup Patel
anup at brainfault.org
Mon Nov 2 00:00:52 PST 2026
On Sat, Oct 3, 2026 at 8:48 PM Fengwei Tan <tfx2001 at outlook.com> wrote:
>
> 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>
LGTM.
Reviewed-by: Anup Patel <anup at brainfault.org>
Applied this patch to the riscv/opensbi repo.
Thanks,
Anup
> ---
> 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