[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