From: Paul Walmsley <pjw@kernel.org>
To: Atish Patra <atish.patra@linux.dev>
Cc: Jiri Olsa <jolsa@kernel.org>, Paul Walmsley <pjw@kernel.org>,
Mark Rutland <mark.rutland@arm.com>,
Rob Herring <robh@kernel.org>, Anup Patel <anup@brainfault.org>,
Namhyung Kim <namhyung@kernel.org>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Ian Rogers <irogers@google.com>, Will Deacon <will@kernel.org>,
James Clark <james.clark@linaro.org>,
linux-arm-kernel@lists.infradead.org,
linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org,
devicetree@vger.kernel.org, linux-perf-users@vger.kernel.org,
Conor Dooley <conor@kernel.org>
Subject: Re: [PATCH v8 11/22] RISC-V: perf: Restructure the SBI PMU code
Date: Tue, 4 Aug 2026 20:29:08 -0600 (MDT) [thread overview]
Message-ID: <150f3f8e-9a94-ecbc-4e1c-e1d1c476f5e9@kernel.org> (raw)
In-Reply-To: <20260701-counter_delegation-v8-11-7909f863a645@meta.com>
Hi Atish,
On Wed, 1 Jul 2026, Atish Patra wrote:
> From: Atish Patra <atishp@rivosinc.com>
>
> With Ssccfg/Smcdeleg, supervisor mode can program and access the
> hpmcounters and events directly, without the SBI PMU extension. The SBI
> PMU extension is still required for firmware counters. Restructure the
> existing SBI PMU code so the hpmcounter/event helpers can be shared
> between the SBI and the counter delegation paths that follow.
>
> The driver, file, module and Kconfig names are intentionally kept
> unchanged to avoid backport churn and userspace breakage (module listings,
> udev rules, cmdline options).
>
> No functional change intended.
>
> Signed-off-by: Atish Patra <atishp@rivosinc.com>
Could you write a little bit more about the specific motivation
behind these changes? I see three major themes:
1. adding _sbi_ to some variable names
2. changing "pmu" to "rvpmu" in some function names
3. removing _sbi_ from some function names
I'm assuming, maybe incorrectly, that the intent for #1 and #3 is to note
that the variables in #1 are specific to SBI interactions, and that the
functions in #3 don't use SBI, so shouldn't have SBI in their names. But
not sure what's going on with #2. Is this just a cosmetic change to
disambiguate the generic "pmu" abbreviation? I see we have a bunch of
references to "riscv_pmu", still, that aren't being changed by those
patches - should we just use that instead so we don't have a jumble of
different prefixes here? Or is there supposed to be some semantic
difference between the two? In the past, it seems we only used "rvpmu"
when struct riscv_pmu was involved; but seems that distinction is no
longer applicable after this series.
thanks,
- Paul
> ---
> drivers/perf/Kconfig | 14 ++-
> drivers/perf/riscv_pmu_sbi.c | 238 +++++++++++++++++++++++++------------------
> 2 files changed, 150 insertions(+), 102 deletions(-)
>
> diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
> index ab90932fc2d0..3245bb2969e1 100644
> --- a/drivers/perf/Kconfig
> +++ b/drivers/perf/Kconfig
> @@ -97,13 +97,17 @@ config RISCV_PMU_LEGACY
>
> config RISCV_PMU_SBI
> depends on RISCV_PMU && RISCV_SBI
> - bool "RISC-V PMU based on SBI PMU extension"
> + bool "RISC-V PMU based on SBI PMU extension and/or counter delegation"
> default y
> help
> - Say y if you want to use the CPU performance monitor
> - using SBI PMU extension on RISC-V based systems. This option provides
> - full perf feature support i.e. counter overflow, privilege mode
> - filtering, counter configuration.
> + Say y if you want to use the CPU performance monitor on RISC-V based
> + systems. This single driver supports both hardware counter access
> + mechanisms: it uses the counter delegation (Smcdeleg/Ssccfg) ISA
> + extension to program and read the hpmcounters directly in supervisor
> + mode when available, and uses the SBI PMU extension for firmware
> + counters and when counter delegation is not present. This option
> + provides full perf feature support i.e. counter overflow, privilege
> + mode filtering, counter configuration.
>
> config STARFIVE_STARLINK_PMU
> depends on ARCH_STARFIVE || COMPILE_TEST
> diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
> index 5c8924ce1f38..74d934238821 100644
> --- a/drivers/perf/riscv_pmu_sbi.c
> +++ b/drivers/perf/riscv_pmu_sbi.c
> @@ -88,6 +88,8 @@ static const struct attribute_group *riscv_pmu_attr_groups[] = {
> static int sysctl_perf_user_access __read_mostly = SYSCTL_USER_ACCESS;
>
> /*
> + * This structure is SBI specific but counter delegation also require counter
> + * width, csr mapping. Reuse it for now.
> * RISC-V doesn't have heterogeneous harts yet. This need to be part of
> * per_cpu in case of harts with different pmu counters
> */
> @@ -100,7 +102,7 @@ static unsigned int riscv_pmu_irq;
> /* Cache the available counters in a bitmask */
> static unsigned long cmask;
>
> -static int pmu_event_find_cache(u64 config);
> +static int sbi_pmu_event_find_cache(u64 config);
> struct sbi_pmu_event_data {
> union {
> union {
> @@ -121,7 +123,7 @@ struct sbi_pmu_event_data {
> };
> };
>
> -static struct sbi_pmu_event_data pmu_hw_event_map[] = {
> +static struct sbi_pmu_event_data pmu_hw_event_sbi_map[] = {
> [PERF_COUNT_HW_CPU_CYCLES] = {.hw_gen_event = {
> SBI_PMU_HW_CPU_CYCLES,
> SBI_PMU_EVENT_TYPE_HW, 0}},
> @@ -155,7 +157,7 @@ static struct sbi_pmu_event_data pmu_hw_event_map[] = {
> };
>
> #define C(x) PERF_COUNT_HW_CACHE_##x
> -static struct sbi_pmu_event_data pmu_cache_event_map[PERF_COUNT_HW_CACHE_MAX]
> +static struct sbi_pmu_event_data pmu_cache_event_sbi_map[PERF_COUNT_HW_CACHE_MAX]
> [PERF_COUNT_HW_CACHE_OP_MAX]
> [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
> [C(L1D)] = {
> @@ -302,7 +304,7 @@ static struct sbi_pmu_event_data pmu_cache_event_map[PERF_COUNT_HW_CACHE_MAX]
>
> static int pmu_sbi_check_event_info(void)
> {
> - int num_events = ARRAY_SIZE(pmu_hw_event_map) + PERF_COUNT_HW_CACHE_MAX *
> + int num_events = ARRAY_SIZE(pmu_hw_event_sbi_map) + PERF_COUNT_HW_CACHE_MAX *
> PERF_COUNT_HW_CACHE_OP_MAX * PERF_COUNT_HW_CACHE_RESULT_MAX;
> struct riscv_pmu_event_info *event_info_shmem;
> phys_addr_t base_addr;
> @@ -313,14 +315,14 @@ static int pmu_sbi_check_event_info(void)
> if (!event_info_shmem)
> return -ENOMEM;
>
> - for (i = 0; i < ARRAY_SIZE(pmu_hw_event_map); i++)
> - event_info_shmem[count++].event_idx = pmu_hw_event_map[i].event_idx;
> + for (i = 0; i < ARRAY_SIZE(pmu_hw_event_sbi_map); i++)
> + event_info_shmem[count++].event_idx = pmu_hw_event_sbi_map[i].event_idx;
>
> - for (i = 0; i < ARRAY_SIZE(pmu_cache_event_map); i++) {
> - for (j = 0; j < ARRAY_SIZE(pmu_cache_event_map[i]); j++) {
> - for (k = 0; k < ARRAY_SIZE(pmu_cache_event_map[i][j]); k++)
> + for (i = 0; i < ARRAY_SIZE(pmu_cache_event_sbi_map); i++) {
> + for (j = 0; j < ARRAY_SIZE(pmu_cache_event_sbi_map[i]); j++) {
> + for (k = 0; k < ARRAY_SIZE(pmu_cache_event_sbi_map[i][j]); k++)
> event_info_shmem[count++].event_idx =
> - pmu_cache_event_map[i][j][k].event_idx;
> + pmu_cache_event_sbi_map[i][j][k].event_idx;
> }
> }
>
> @@ -336,19 +338,19 @@ static int pmu_sbi_check_event_info(void)
> goto free_mem;
> }
>
> - for (i = 0; i < ARRAY_SIZE(pmu_hw_event_map); i++) {
> + for (i = 0; i < ARRAY_SIZE(pmu_hw_event_sbi_map); i++) {
> if (!(event_info_shmem[i].output & RISCV_PMU_EVENT_INFO_OUTPUT_MASK))
> - pmu_hw_event_map[i].event_idx = -ENOENT;
> + pmu_hw_event_sbi_map[i].event_idx = -ENOENT;
> }
>
> - count = ARRAY_SIZE(pmu_hw_event_map);
> + count = ARRAY_SIZE(pmu_hw_event_sbi_map);
>
> - for (i = 0; i < ARRAY_SIZE(pmu_cache_event_map); i++) {
> - for (j = 0; j < ARRAY_SIZE(pmu_cache_event_map[i]); j++) {
> - for (k = 0; k < ARRAY_SIZE(pmu_cache_event_map[i][j]); k++) {
> + for (i = 0; i < ARRAY_SIZE(pmu_cache_event_sbi_map); i++) {
> + for (j = 0; j < ARRAY_SIZE(pmu_cache_event_sbi_map[i]); j++) {
> + for (k = 0; k < ARRAY_SIZE(pmu_cache_event_sbi_map[i][j]); k++) {
> if (!(event_info_shmem[count].output &
> RISCV_PMU_EVENT_INFO_OUTPUT_MASK))
> - pmu_cache_event_map[i][j][k].event_idx = -ENOENT;
> + pmu_cache_event_sbi_map[i][j][k].event_idx = -ENOENT;
> count++;
> }
> }
> @@ -360,7 +362,7 @@ static int pmu_sbi_check_event_info(void)
> return result;
> }
>
> -static void pmu_sbi_check_event(struct sbi_pmu_event_data *edata)
> +static void rvpmu_sbi_check_event(struct sbi_pmu_event_data *edata)
> {
> struct sbiret ret;
>
> @@ -375,7 +377,7 @@ static void pmu_sbi_check_event(struct sbi_pmu_event_data *edata)
> }
> }
>
> -static void pmu_sbi_check_std_events(struct work_struct *work)
> +static void rvpmu_sbi_check_std_events(struct work_struct *work)
> {
> int ret;
>
> @@ -386,23 +388,23 @@ static void pmu_sbi_check_std_events(struct work_struct *work)
> return;
> }
>
> - for (int i = 0; i < ARRAY_SIZE(pmu_hw_event_map); i++)
> - pmu_sbi_check_event(&pmu_hw_event_map[i]);
> + for (int i = 0; i < ARRAY_SIZE(pmu_hw_event_sbi_map); i++)
> + rvpmu_sbi_check_event(&pmu_hw_event_sbi_map[i]);
>
> - for (int i = 0; i < ARRAY_SIZE(pmu_cache_event_map); i++)
> - for (int j = 0; j < ARRAY_SIZE(pmu_cache_event_map[i]); j++)
> - for (int k = 0; k < ARRAY_SIZE(pmu_cache_event_map[i][j]); k++)
> - pmu_sbi_check_event(&pmu_cache_event_map[i][j][k]);
> + for (int i = 0; i < ARRAY_SIZE(pmu_cache_event_sbi_map); i++)
> + for (int j = 0; j < ARRAY_SIZE(pmu_cache_event_sbi_map[i]); j++)
> + for (int k = 0; k < ARRAY_SIZE(pmu_cache_event_sbi_map[i][j]); k++)
> + rvpmu_sbi_check_event(&pmu_cache_event_sbi_map[i][j][k]);
> }
>
> -static DECLARE_WORK(check_std_events_work, pmu_sbi_check_std_events);
> +static DECLARE_WORK(check_std_events_work, rvpmu_sbi_check_std_events);
>
> -static int pmu_sbi_ctr_get_width(int idx)
> +static int rvpmu_ctr_get_width(int idx)
> {
> return pmu_ctr_list[idx].width;
> }
>
> -static bool pmu_sbi_ctr_is_fw(int cidx)
> +static bool rvpmu_ctr_is_fw(int cidx)
> {
> union sbi_pmu_ctr_info *info;
>
> @@ -421,10 +423,10 @@ int riscv_pmu_get_event_info(u32 type, u64 config, u64 *econfig)
> case PERF_TYPE_HARDWARE:
> if (config >= PERF_COUNT_HW_MAX)
> return -EINVAL;
> - ret = pmu_hw_event_map[config].event_idx;
> + ret = pmu_hw_event_sbi_map[config].event_idx;
> break;
> case PERF_TYPE_HW_CACHE:
> - ret = pmu_event_find_cache(config);
> + ret = sbi_pmu_event_find_cache(config);
> break;
> case PERF_TYPE_RAW:
> /*
> @@ -509,12 +511,12 @@ int riscv_pmu_get_hpm_info(u32 *hw_ctr_width, u32 *num_hw_ctr)
> }
> EXPORT_SYMBOL_GPL(riscv_pmu_get_hpm_info);
>
> -static uint8_t pmu_sbi_csr_index(struct perf_event *event)
> +static uint8_t rvpmu_csr_index(struct perf_event *event)
> {
> return pmu_ctr_list[event->hw.idx].csr - CSR_CYCLE;
> }
>
> -static unsigned long pmu_sbi_get_filter_flags(struct perf_event *event)
> +static unsigned long rvpmu_sbi_get_filter_flags(struct perf_event *event)
> {
> unsigned long cflags = 0;
> bool guest_events = false;
> @@ -535,7 +537,7 @@ static unsigned long pmu_sbi_get_filter_flags(struct perf_event *event)
> return cflags;
> }
>
> -static int pmu_sbi_ctr_get_idx(struct perf_event *event)
> +static int rvpmu_sbi_ctr_get_idx(struct perf_event *event)
> {
> struct hw_perf_event *hwc = &event->hw;
> struct riscv_pmu *rvpmu = to_riscv_pmu(event->pmu);
> @@ -545,7 +547,7 @@ static int pmu_sbi_ctr_get_idx(struct perf_event *event)
> uint64_t cbase = 0, cmask = rvpmu->cmask;
> unsigned long cflags = 0;
>
> - cflags = pmu_sbi_get_filter_flags(event);
> + cflags = rvpmu_sbi_get_filter_flags(event);
>
> /*
> * In legacy mode, we have to force the fixed counters for those events
> @@ -582,7 +584,7 @@ static int pmu_sbi_ctr_get_idx(struct perf_event *event)
> return -ENOENT;
>
> /* Additional sanity check for the counter id */
> - if (pmu_sbi_ctr_is_fw(idx)) {
> + if (rvpmu_ctr_is_fw(idx)) {
> if (!test_and_set_bit(idx, cpuc->used_fw_ctrs))
> return idx;
> } else {
> @@ -593,7 +595,7 @@ static int pmu_sbi_ctr_get_idx(struct perf_event *event)
> return -ENOENT;
> }
>
> -static void pmu_sbi_ctr_clear_idx(struct perf_event *event)
> +static void rvpmu_ctr_clear_idx(struct perf_event *event)
> {
>
> struct hw_perf_event *hwc = &event->hw;
> @@ -601,13 +603,13 @@ static void pmu_sbi_ctr_clear_idx(struct perf_event *event)
> struct cpu_hw_events *cpuc = this_cpu_ptr(rvpmu->hw_events);
> int idx = hwc->idx;
>
> - if (pmu_sbi_ctr_is_fw(idx))
> + if (rvpmu_ctr_is_fw(idx))
> clear_bit(idx, cpuc->used_fw_ctrs);
> else
> clear_bit(idx, cpuc->used_hw_ctrs);
> }
>
> -static int pmu_event_find_cache(u64 config)
> +static int sbi_pmu_event_find_cache(u64 config)
> {
> unsigned int cache_type, cache_op, cache_result, ret;
>
> @@ -623,7 +625,7 @@ static int pmu_event_find_cache(u64 config)
> if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
> return -EINVAL;
>
> - ret = pmu_cache_event_map[cache_type][cache_op][cache_result].event_idx;
> + ret = pmu_cache_event_sbi_map[cache_type][cache_op][cache_result].event_idx;
>
> return ret;
> }
> @@ -639,7 +641,7 @@ static bool pmu_sbi_is_fw_event(struct perf_event *event)
> return false;
> }
>
> -static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig)
> +static int rvpmu_sbi_event_map(struct perf_event *event, u64 *econfig)
> {
> u32 type = event->attr.type;
> u64 config = event->attr.config;
> @@ -736,7 +738,7 @@ static int pmu_sbi_snapshot_setup(struct riscv_pmu *pmu, int cpu)
> return 0;
> }
>
> -static u64 pmu_sbi_ctr_read(struct perf_event *event)
> +static u64 rvpmu_sbi_ctr_read(struct perf_event *event)
> {
> struct hw_perf_event *hwc = &event->hw;
> int idx = hwc->idx;
> @@ -778,25 +780,25 @@ static u64 pmu_sbi_ctr_read(struct perf_event *event)
> return val;
> }
>
> -static void pmu_sbi_set_scounteren(void *arg)
> +static void rvpmu_set_scounteren(void *arg)
> {
> struct perf_event *event = (struct perf_event *)arg;
>
> if (event->hw.idx != -1)
> csr_write(CSR_SCOUNTEREN,
> - csr_read(CSR_SCOUNTEREN) | BIT(pmu_sbi_csr_index(event)));
> + csr_read(CSR_SCOUNTEREN) | BIT(rvpmu_csr_index(event)));
> }
>
> -static void pmu_sbi_reset_scounteren(void *arg)
> +static void rvpmu_reset_scounteren(void *arg)
> {
> struct perf_event *event = (struct perf_event *)arg;
>
> if (event->hw.idx != -1)
> csr_write(CSR_SCOUNTEREN,
> - csr_read(CSR_SCOUNTEREN) & ~BIT(pmu_sbi_csr_index(event)));
> + csr_read(CSR_SCOUNTEREN) & ~BIT(rvpmu_csr_index(event)));
> }
>
> -static void pmu_sbi_ctr_start(struct perf_event *event, u64 ival)
> +static void rvpmu_sbi_ctr_start(struct perf_event *event, u64 ival)
> {
> struct sbiret ret;
> struct hw_perf_event *hwc = &event->hw;
> @@ -816,10 +818,10 @@ static void pmu_sbi_ctr_start(struct perf_event *event, u64 ival)
>
> if ((hwc->flags & PERF_EVENT_FLAG_USER_ACCESS) &&
> (hwc->flags & PERF_EVENT_FLAG_USER_READ_CNT))
> - pmu_sbi_set_scounteren((void *)event);
> + rvpmu_set_scounteren((void *)event);
> }
>
> -static void pmu_sbi_ctr_stop(struct perf_event *event, unsigned long flag)
> +static void rvpmu_sbi_ctr_stop(struct perf_event *event, unsigned long flag)
> {
> struct sbiret ret;
> struct hw_perf_event *hwc = &event->hw;
> @@ -829,7 +831,7 @@ static void pmu_sbi_ctr_stop(struct perf_event *event, unsigned long flag)
>
> if ((hwc->flags & PERF_EVENT_FLAG_USER_ACCESS) &&
> (hwc->flags & PERF_EVENT_FLAG_USER_READ_CNT))
> - pmu_sbi_reset_scounteren((void *)event);
> + rvpmu_reset_scounteren((void *)event);
>
> if (sbi_pmu_snapshot_available())
> flag |= SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT;
> @@ -855,7 +857,7 @@ static void pmu_sbi_ctr_stop(struct perf_event *event, unsigned long flag)
> }
> }
>
> -static int pmu_sbi_find_num_ctrs(void)
> +static int rvpmu_sbi_find_num_ctrs(void)
> {
> struct sbiret ret;
>
> @@ -866,7 +868,7 @@ static int pmu_sbi_find_num_ctrs(void)
> return sbi_err_map_linux_errno(ret.error);
> }
>
> -static int pmu_sbi_get_ctrinfo(int nctr, unsigned long *mask)
> +static int rvpmu_sbi_get_ctrinfo(int nctr, unsigned long *mask)
> {
> struct sbiret ret;
> int i, num_hw_ctr = 0, num_fw_ctr = 0;
> @@ -897,7 +899,7 @@ static int pmu_sbi_get_ctrinfo(int nctr, unsigned long *mask)
> return 0;
> }
>
> -static inline void pmu_sbi_stop_all(struct riscv_pmu *pmu)
> +static inline void rvpmu_sbi_stop_all(struct riscv_pmu *pmu)
> {
> /*
> * No need to check the error because we are disabling all the counters
> @@ -907,7 +909,7 @@ static inline void pmu_sbi_stop_all(struct riscv_pmu *pmu)
> 0, pmu->cmask, SBI_PMU_STOP_FLAG_RESET, 0, 0, 0);
> }
>
> -static inline void pmu_sbi_stop_hw_ctrs(struct riscv_pmu *pmu)
> +static inline void rvpmu_sbi_stop_hw_ctrs(struct riscv_pmu *pmu)
> {
> struct cpu_hw_events *cpu_hw_evt = this_cpu_ptr(pmu->hw_events);
> struct riscv_pmu_snapshot_data *sdata = cpu_hw_evt->snapshot_addr;
> @@ -951,8 +953,8 @@ static inline void pmu_sbi_stop_hw_ctrs(struct riscv_pmu *pmu)
> * while the overflowed counters need to be started with updated initialization
> * value.
> */
> -static inline void pmu_sbi_start_ovf_ctrs_sbi(struct cpu_hw_events *cpu_hw_evt,
> - u64 ctr_ovf_mask)
> +static inline void rvpmu_sbi_start_ovf_ctrs_sbi(struct cpu_hw_events *cpu_hw_evt,
> + u64 ctr_ovf_mask)
> {
> int idx = 0, i;
> struct perf_event *event;
> @@ -992,8 +994,8 @@ static inline void pmu_sbi_start_ovf_ctrs_sbi(struct cpu_hw_events *cpu_hw_evt,
> }
> }
>
> -static inline void pmu_sbi_start_ovf_ctrs_snapshot(struct cpu_hw_events *cpu_hw_evt,
> - u64 ctr_ovf_mask)
> +static inline void rvpmu_sbi_start_ovf_ctrs_snapshot(struct cpu_hw_events *cpu_hw_evt,
> + u64 ctr_ovf_mask)
> {
> int i, idx = 0;
> struct perf_event *event;
> @@ -1027,18 +1029,18 @@ static inline void pmu_sbi_start_ovf_ctrs_snapshot(struct cpu_hw_events *cpu_hw_
> }
> }
>
> -static void pmu_sbi_start_overflow_mask(struct riscv_pmu *pmu,
> - u64 ctr_ovf_mask)
> +static void rvpmu_sbi_start_overflow_mask(struct riscv_pmu *pmu,
> + u64 ctr_ovf_mask)
> {
> struct cpu_hw_events *cpu_hw_evt = this_cpu_ptr(pmu->hw_events);
>
> if (sbi_pmu_snapshot_available())
> - pmu_sbi_start_ovf_ctrs_snapshot(cpu_hw_evt, ctr_ovf_mask);
> + rvpmu_sbi_start_ovf_ctrs_snapshot(cpu_hw_evt, ctr_ovf_mask);
> else
> - pmu_sbi_start_ovf_ctrs_sbi(cpu_hw_evt, ctr_ovf_mask);
> + rvpmu_sbi_start_ovf_ctrs_sbi(cpu_hw_evt, ctr_ovf_mask);
> }
>
> -static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev)
> +static irqreturn_t rvpmu_ovf_handler(int irq, void *dev)
> {
> struct perf_sample_data data;
> struct pt_regs *regs;
> @@ -1070,7 +1072,7 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev)
> }
>
> pmu = to_riscv_pmu(event->pmu);
> - pmu_sbi_stop_hw_ctrs(pmu);
> + rvpmu_sbi_stop_hw_ctrs(pmu);
>
> /* Overflow status register should only be read after counter are stopped */
> if (sbi_pmu_snapshot_available())
> @@ -1139,13 +1141,55 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev)
> hw_evt->state = 0;
> }
>
> - pmu_sbi_start_overflow_mask(pmu, overflowed_ctrs);
> + rvpmu_sbi_start_overflow_mask(pmu, overflowed_ctrs);
> perf_sample_event_took(sched_clock() - start_clock);
>
> return IRQ_HANDLED;
> }
>
> -static int pmu_sbi_starting_cpu(unsigned int cpu, struct hlist_node *node)
> +static void rvpmu_ctr_start(struct perf_event *event, u64 ival)
> +{
> + rvpmu_sbi_ctr_start(event, ival);
> + /* TODO: Counter delegation implementation */
> +}
> +
> +static void rvpmu_ctr_stop(struct perf_event *event, unsigned long flag)
> +{
> + rvpmu_sbi_ctr_stop(event, flag);
> + /* TODO: Counter delegation implementation */
> +}
> +
> +static int rvpmu_find_num_ctrs(void)
> +{
> + return rvpmu_sbi_find_num_ctrs();
> + /* TODO: Counter delegation implementation */
> +}
> +
> +static int rvpmu_get_ctrinfo(int nctr, unsigned long *mask)
> +{
> + return rvpmu_sbi_get_ctrinfo(nctr, mask);
> + /* TODO: Counter delegation implementation */
> +}
> +
> +static int rvpmu_event_map(struct perf_event *event, u64 *econfig)
> +{
> + return rvpmu_sbi_event_map(event, econfig);
> + /* TODO: Counter delegation implementation */
> +}
> +
> +static int rvpmu_ctr_get_idx(struct perf_event *event)
> +{
> + return rvpmu_sbi_ctr_get_idx(event);
> + /* TODO: Counter delegation implementation */
> +}
> +
> +static u64 rvpmu_ctr_read(struct perf_event *event)
> +{
> + return rvpmu_sbi_ctr_read(event);
> + /* TODO: Counter delegation implementation */
> +}
> +
> +static int rvpmu_starting_cpu(unsigned int cpu, struct hlist_node *node)
> {
> struct riscv_pmu *pmu = hlist_entry_safe(node, struct riscv_pmu, node);
> struct cpu_hw_events *cpu_hw_evt = this_cpu_ptr(pmu->hw_events);
> @@ -1160,7 +1204,7 @@ static int pmu_sbi_starting_cpu(unsigned int cpu, struct hlist_node *node)
> csr_write(CSR_SCOUNTEREN, 0x2);
>
> /* Stop all the counters so that they can be enabled from perf */
> - pmu_sbi_stop_all(pmu);
> + rvpmu_sbi_stop_all(pmu);
>
> if (riscv_pmu_use_irq) {
> cpu_hw_evt->irq = riscv_pmu_irq;
> @@ -1174,7 +1218,7 @@ static int pmu_sbi_starting_cpu(unsigned int cpu, struct hlist_node *node)
> return 0;
> }
>
> -static int pmu_sbi_dying_cpu(unsigned int cpu, struct hlist_node *node)
> +static int rvpmu_dying_cpu(unsigned int cpu, struct hlist_node *node)
> {
> if (riscv_pmu_use_irq) {
> disable_percpu_irq(riscv_pmu_irq);
> @@ -1189,7 +1233,7 @@ static int pmu_sbi_dying_cpu(unsigned int cpu, struct hlist_node *node)
> return 0;
> }
>
> -static int pmu_sbi_setup_irqs(struct riscv_pmu *pmu, struct platform_device *pdev)
> +static int rvpmu_setup_irqs(struct riscv_pmu *pmu, struct platform_device *pdev)
> {
> int ret;
> struct cpu_hw_events __percpu *hw_events = pmu->hw_events;
> @@ -1231,7 +1275,7 @@ static int pmu_sbi_setup_irqs(struct riscv_pmu *pmu, struct platform_device *pde
> goto err;
> }
>
> - ret = request_percpu_irq(riscv_pmu_irq, pmu_sbi_ovf_handler, "riscv-pmu", hw_events);
> + ret = request_percpu_irq(riscv_pmu_irq, rvpmu_ovf_handler, "riscv-pmu", hw_events);
> if (ret) {
> pr_err("registering percpu irq failed [%d]\n", ret);
> irq_dispose_mapping(riscv_pmu_irq);
> @@ -1313,7 +1357,7 @@ static void riscv_pmu_destroy(struct riscv_pmu *pmu)
> cpuhp_state_remove_instance(CPUHP_AP_PERF_RISCV_STARTING, &pmu->node);
> }
>
> -static void pmu_sbi_event_init(struct perf_event *event)
> +static void rvpmu_event_init(struct perf_event *event)
> {
> /*
> * The permissions are set at event_init so that we do not depend
> @@ -1327,7 +1371,7 @@ static void pmu_sbi_event_init(struct perf_event *event)
> event->hw.flags |= PERF_EVENT_FLAG_LEGACY;
> }
>
> -static void pmu_sbi_event_mapped(struct perf_event *event, struct mm_struct *mm)
> +static void rvpmu_event_mapped(struct perf_event *event, struct mm_struct *mm)
> {
> if (event->hw.flags & PERF_EVENT_FLAG_NO_USER_ACCESS)
> return;
> @@ -1355,14 +1399,14 @@ static void pmu_sbi_event_mapped(struct perf_event *event, struct mm_struct *mm)
> * that it is possible to do so to avoid any race.
> * And we must notify all cpus here because threads that currently run
> * on other cpus will try to directly access the counter too without
> - * calling pmu_sbi_ctr_start.
> + * calling rvpmu_sbi_ctr_start.
> */
> if (event->hw.flags & PERF_EVENT_FLAG_USER_ACCESS)
> on_each_cpu_mask(mm_cpumask(mm),
> - pmu_sbi_set_scounteren, (void *)event, 1);
> + rvpmu_set_scounteren, (void *)event, 1);
> }
>
> -static void pmu_sbi_event_unmapped(struct perf_event *event, struct mm_struct *mm)
> +static void rvpmu_event_unmapped(struct perf_event *event, struct mm_struct *mm)
> {
> if (event->hw.flags & PERF_EVENT_FLAG_NO_USER_ACCESS)
> return;
> @@ -1384,7 +1428,7 @@ static void pmu_sbi_event_unmapped(struct perf_event *event, struct mm_struct *m
>
> if (event->hw.flags & PERF_EVENT_FLAG_USER_ACCESS)
> on_each_cpu_mask(mm_cpumask(mm),
> - pmu_sbi_reset_scounteren, (void *)event, 1);
> + rvpmu_reset_scounteren, (void *)event, 1);
> }
>
> static void riscv_pmu_update_counter_access(void *info)
> @@ -1427,7 +1471,7 @@ static const struct ctl_table sbi_pmu_sysctl_table[] = {
> },
> };
>
> -static int pmu_sbi_device_probe(struct platform_device *pdev)
> +static int rvpmu_device_probe(struct platform_device *pdev)
> {
> struct riscv_pmu *pmu = NULL;
> int ret = -ENODEV;
> @@ -1439,7 +1483,7 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
> if (!pmu)
> return -ENOMEM;
>
> - num_counters = pmu_sbi_find_num_ctrs();
> + num_counters = rvpmu_find_num_ctrs();
> if (num_counters < 0) {
> pr_err("SBI PMU extension doesn't provide any counters\n");
> goto out_free;
> @@ -1452,10 +1496,10 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
> }
>
> /* cache all the information about counters now */
> - if (pmu_sbi_get_ctrinfo(num_counters, &cmask))
> + if (rvpmu_get_ctrinfo(num_counters, &cmask))
> goto out_free;
>
> - ret = pmu_sbi_setup_irqs(pmu, pdev);
> + ret = rvpmu_setup_irqs(pmu, pdev);
> if (ret < 0) {
> pr_info("Perf sampling/filtering is not supported as sscof extension is not available\n");
> pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
> @@ -1466,17 +1510,17 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
> pmu->pmu.attr_groups = riscv_pmu_attr_groups;
> pmu->pmu.parent = &pdev->dev;
> pmu->cmask = cmask;
> - pmu->ctr_start = pmu_sbi_ctr_start;
> - pmu->ctr_stop = pmu_sbi_ctr_stop;
> - pmu->event_map = pmu_sbi_event_map;
> - pmu->ctr_get_idx = pmu_sbi_ctr_get_idx;
> - pmu->ctr_get_width = pmu_sbi_ctr_get_width;
> - pmu->ctr_clear_idx = pmu_sbi_ctr_clear_idx;
> - pmu->ctr_read = pmu_sbi_ctr_read;
> - pmu->event_init = pmu_sbi_event_init;
> - pmu->event_mapped = pmu_sbi_event_mapped;
> - pmu->event_unmapped = pmu_sbi_event_unmapped;
> - pmu->csr_index = pmu_sbi_csr_index;
> + pmu->ctr_start = rvpmu_ctr_start;
> + pmu->ctr_stop = rvpmu_ctr_stop;
> + pmu->event_map = rvpmu_event_map;
> + pmu->ctr_get_idx = rvpmu_ctr_get_idx;
> + pmu->ctr_get_width = rvpmu_ctr_get_width;
> + pmu->ctr_clear_idx = rvpmu_ctr_clear_idx;
> + pmu->ctr_read = rvpmu_ctr_read;
> + pmu->event_init = rvpmu_event_init;
> + pmu->event_mapped = rvpmu_event_mapped;
> + pmu->event_unmapped = rvpmu_event_unmapped;
> + pmu->csr_index = rvpmu_csr_index;
>
> ret = riscv_pm_pmu_register(pmu);
> if (ret)
> @@ -1543,14 +1587,14 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
> return ret;
> }
>
> -static struct platform_driver pmu_sbi_driver = {
> - .probe = pmu_sbi_device_probe,
> +static struct platform_driver rvpmu_driver = {
> + .probe = rvpmu_device_probe,
> .driver = {
> .name = RISCV_PMU_SBI_PDEV_NAME,
> },
> };
>
> -static int __init pmu_sbi_devinit(void)
> +static int __init rvpmu_devinit(void)
> {
> int ret;
> struct platform_device *pdev;
> @@ -1568,20 +1612,20 @@ static int __init pmu_sbi_devinit(void)
>
> ret = cpuhp_setup_state_multi(CPUHP_AP_PERF_RISCV_STARTING,
> "perf/riscv/pmu:starting",
> - pmu_sbi_starting_cpu, pmu_sbi_dying_cpu);
> + rvpmu_starting_cpu, rvpmu_dying_cpu);
> if (ret) {
> pr_err("CPU hotplug notifier could not be registered: %d\n",
> ret);
> return ret;
> }
>
> - ret = platform_driver_register(&pmu_sbi_driver);
> + ret = platform_driver_register(&rvpmu_driver);
> if (ret)
> return ret;
>
> pdev = platform_device_register_simple(RISCV_PMU_SBI_PDEV_NAME, -1, NULL, 0);
> if (IS_ERR(pdev)) {
> - platform_driver_unregister(&pmu_sbi_driver);
> + platform_driver_unregister(&rvpmu_driver);
> return PTR_ERR(pdev);
> }
>
> @@ -1590,4 +1634,4 @@ static int __init pmu_sbi_devinit(void)
>
> return ret;
> }
> -device_initcall(pmu_sbi_devinit)
> +device_initcall(rvpmu_devinit)
>
> --
> 2.53.0-Meta
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv
>
next prev parent reply other threads:[~2026-08-05 2:29 UTC|newest]
Thread overview: 60+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-01 8:46 [PATCH v8 00/22] Add Counter delegation ISA extension support Atish Patra
2026-07-01 8:46 ` [PATCH v8 01/22] RISC-V: perf: fix resource cleanup on driver probe failure Atish Patra
2026-07-20 7:21 ` Charlie Jenkins
2026-08-04 23:25 ` Paul Walmsley
2026-07-01 8:46 ` [PATCH v8 02/22] RISC-V: Add Sxcsrind ISA extension CSR definitions Atish Patra
2026-07-20 7:21 ` Charlie Jenkins
2026-08-04 23:35 ` Paul Walmsley
2026-08-04 23:42 ` Paul Walmsley
2026-08-05 7:30 ` Atish Patra
2026-07-01 8:46 ` [PATCH v8 03/22] RISC-V: Add Sxcsrind ISA extension definition and parsing Atish Patra
2026-07-20 7:21 ` Charlie Jenkins
2026-08-04 23:58 ` Paul Walmsley
2026-07-01 8:46 ` [PATCH v8 04/22] dt-bindings: riscv: add Sxcsrind ISA extension description Atish Patra
2026-08-05 0:29 ` Paul Walmsley
2026-07-01 8:46 ` [PATCH v8 05/22] RISC-V: Define indirect CSR access helpers Atish Patra
2026-07-20 7:21 ` Charlie Jenkins
2026-08-05 0:39 ` Paul Walmsley
2026-08-05 7:59 ` Atish Patra
2026-08-05 8:07 ` Atish Patra
2026-07-01 8:46 ` [PATCH v8 06/22] RISC-V: Add Smcntrpmf extension parsing Atish Patra
2026-07-20 7:21 ` Charlie Jenkins
2026-08-05 0:44 ` Paul Walmsley
2026-07-01 8:46 ` [PATCH v8 07/22] dt-bindings: riscv: add Smcntrpmf ISA extension description Atish Patra
2026-08-05 0:44 ` Paul Walmsley
2026-07-01 8:46 ` [PATCH v8 08/22] RISC-V: Add Sscfg extension CSR definition Atish Patra
2026-07-20 7:21 ` Charlie Jenkins
2026-08-05 0:43 ` Paul Walmsley
2026-07-01 8:46 ` [PATCH v8 09/22] RISC-V: Add Ssccfg/Smcdeleg ISA extension definition and parsing Atish Patra
2026-07-20 7:21 ` Charlie Jenkins
2026-08-05 0:46 ` Paul Walmsley
2026-07-01 8:46 ` [PATCH v8 10/22] dt-bindings: riscv: add Counter delegation ISA extensions description Atish Patra
2026-08-05 0:48 ` Paul Walmsley
2026-07-01 8:46 ` [PATCH v8 11/22] RISC-V: perf: Restructure the SBI PMU code Atish Patra
2026-08-05 2:29 ` Paul Walmsley [this message]
2026-07-01 8:47 ` [PATCH v8 12/22] RISC-V: perf: Modify the counter discovery mechanism Atish Patra
2026-07-07 7:45 ` Yicong Yang
2026-07-20 7:21 ` Charlie Jenkins
2026-07-01 8:47 ` [PATCH v8 13/22] RISC-V: perf: Add a mechanism to defined legacy event encoding Atish Patra
2026-07-07 7:51 ` Yicong Yang
2026-08-03 21:53 ` Atish Patra
2026-07-20 7:21 ` Charlie Jenkins
2026-07-01 8:47 ` [PATCH v8 14/22] RISC-V: perf: Implement supervisor counter delegation support Atish Patra
2026-07-07 8:24 ` Yicong Yang
2026-07-20 7:21 ` Charlie Jenkins
2026-07-01 8:47 ` [PATCH v8 15/22] RISC-V: perf: Skip PMU SBI extension when not implemented Atish Patra
2026-07-01 8:47 ` [PATCH v8 16/22] RISC-V: perf: Use config2/vendor table for event to counter mapping Atish Patra
2026-07-20 7:21 ` Charlie Jenkins
2026-07-01 8:47 ` [PATCH v8 17/22] RISC-V: perf: Add legacy event encodings via sysfs Atish Patra
2026-07-20 7:21 ` Charlie Jenkins
2026-07-01 8:47 ` [PATCH v8 18/22] RISC-V: perf: Add Qemu virt machine events Atish Patra
2026-07-20 7:21 ` Charlie Jenkins
2026-07-01 8:47 ` [PATCH v8 19/22] tools/perf: Support event code for arch standard events Atish Patra
2026-07-01 17:44 ` Ian Rogers
2026-07-01 8:47 ` [PATCH v8 20/22] tools/perf: Add RISC-V CounterIDMask event field Atish Patra
2026-07-01 17:44 ` Ian Rogers
2026-07-01 8:47 ` [PATCH v8 21/22] TEST(do-not-upstream): fake qemu-virt PMU events for cdeleg counter-mask testing Atish Patra
2026-07-01 8:47 ` [PATCH v8 22/22] TEST(do-not-upstream): fake qemu vendor JSON + mapfile entry for CounterIDMask path Atish Patra
2026-08-05 1:00 ` [PATCH v8 00/22] Add Counter delegation ISA extension support patchwork-bot+linux-riscv
2026-08-05 2:14 ` Paul Walmsley
2026-08-05 8:03 ` Atish Patra
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=150f3f8e-9a94-ecbc-4e1c-e1d1c476f5e9@kernel.org \
--to=pjw@kernel.org \
--cc=acme@kernel.org \
--cc=anup@brainfault.org \
--cc=atish.patra@linux.dev \
--cc=conor@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=irogers@google.com \
--cc=james.clark@linaro.org \
--cc=jolsa@kernel.org \
--cc=krzk+dt@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=mark.rutland@arm.com \
--cc=namhyung@kernel.org \
--cc=robh@kernel.org \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox