From: Vikram Singh <vikram.singh3@oss.qualcomm.com>
To: Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@redhat.com>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Namhyung Kim <namhyung@kernel.org>,
Mark Rutland <mark.rutland@arm.com>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
Jiri Olsa <jolsa@kernel.org>, Ian Rogers <irogers@google.com>,
Adrian Hunter <adrian.hunter@intel.com>,
"Liang, Kan" <kan.liang@linux.intel.com>,
Paul Walmsley <paul.walmsley@sifive.com>,
Palmer Dabbelt <palmer@dabbelt.com>,
Albert Ou <aou@eecs.berkeley.edu>,
Alexandre Ghiti <alex@ghiti.fr>,
Atish Kumar Patra <atishp@rivosinc.com>,
Anup Patel <anup.patel@oss.qualcomm.com>,
Will Deacon <will@kernel.org>, Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
Beeman Strong <beeman@rivosinc.com>
Cc: Vikram Singh <vikram.singh3@oss.qualcomm.com>,
Rajnesh Kanwal <rajnesh.kanwal49@gmail.com>,
linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-riscv@lists.infradead.org,
linux-arm-kernel@lists.infradead.org,
Palmer Dabbelt <palmer@sifive.com>,
Conor Dooley <conor@kernel.org>,
devicetree@vger.kernel.org
Subject: [PATCH v4 6/7] riscv: pmu: Integrate CTR Ext support in riscv_pmu_dev driver
Date: Fri, 6 Nov 2026 23:09:41 +0530 [thread overview]
Message-ID: <20261106173942.3175069-7-vikram.singh3@oss.qualcomm.com> (raw)
In-Reply-To: <20261106173942.3175069-1-vikram.singh3@oss.qualcomm.com>
This integrates recently added CTR ext support in riscv_pmu_dev driver
to enable branch stack sampling using PMU events.
This mainly adds CTR enable/disable callbacks in rvpmu_ctr_stop()
and rvpmu_ctr_start() function to start/stop branch recording along
with the event.
PMU overflow handler rvpmu_ovf_handler() is also updated to sample
CTR entries in case of the overflow for the particular event programmed
to records branches. The recorded entries are fed to core perf for
further processing.
Co-developed-by: Rajnesh Kanwal <rajnesh.kanwal49@gmail.com>
Signed-off-by: Rajnesh Kanwal <rajnesh.kanwal49@gmail.com>
Signed-off-by: Vikram Singh <vikram.singh3@oss.qualcomm.com>
---
drivers/perf/riscv_pmu.c | 2 +-
drivers/perf/riscv_pmu_sbi.c | 68 +++++++++++++++++++++++++++++++++++-
2 files changed, 68 insertions(+), 2 deletions(-)
diff --git a/drivers/perf/riscv_pmu.c b/drivers/perf/riscv_pmu.c
index a1ae490d94c9..407028f24674 100644
--- a/drivers/perf/riscv_pmu.c
+++ b/drivers/perf/riscv_pmu.c
@@ -310,7 +310,7 @@ static int riscv_pmu_event_init(struct perf_event *event)
uint64_t cmask;
/* driver does not support branch stack sampling */
- if (has_branch_stack(event))
+ if (has_branch_stack(event) && !riscv_pmu_ctr_supported(rvpmu))
return -EOPNOTSUPP;
hwc->flags = 0;
diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
index 400de6bed369..684f02122f68 100644
--- a/drivers/perf/riscv_pmu_sbi.c
+++ b/drivers/perf/riscv_pmu_sbi.c
@@ -650,6 +650,9 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig)
*/
flush_work(&check_std_events_work);
+ if (needs_branch_stack(event) && !riscv_pmu_ctr_valid(event))
+ return -EOPNOTSUPP;
+
return riscv_pmu_get_event_info(type, config, econfig);
}
@@ -798,10 +801,14 @@ static void pmu_sbi_reset_scounteren(void *arg)
static void pmu_sbi_ctr_add(struct perf_event *event, int flags)
{
+ if (needs_branch_stack(event))
+ riscv_pmu_ctr_add(event);
}
static void pmu_sbi_ctr_del(struct perf_event *event, int flags)
{
+ if (needs_branch_stack(event))
+ riscv_pmu_ctr_del(event);
}
static void pmu_sbi_ctr_start(struct perf_event *event, u64 ival)
@@ -818,6 +825,10 @@ static void pmu_sbi_ctr_start(struct perf_event *event, u64 ival)
ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, hwc->idx,
1, flag, ival, 0, 0);
#endif
+
+ if (needs_branch_stack(event))
+ riscv_pmu_ctr_enable(event);
+
if (ret.error && (ret.error != SBI_ERR_ALREADY_STARTED))
pr_err("Starting counter idx %d failed with error %d\n",
hwc->idx, sbi_err_map_linux_errno(ret.error));
@@ -835,6 +846,9 @@ static void pmu_sbi_ctr_stop(struct perf_event *event, unsigned long flag)
struct cpu_hw_events *cpu_hw_evt = this_cpu_ptr(pmu->hw_events);
struct riscv_pmu_snapshot_data *sdata = cpu_hw_evt->snapshot_addr;
+ if (needs_branch_stack(event) && flag != RISCV_PMU_STOP_FLAG_RESET)
+ riscv_pmu_ctr_disable(event);
+
if ((hwc->flags & PERF_EVENT_FLAG_USER_ACCESS) &&
(hwc->flags & PERF_EVENT_FLAG_USER_READ_CNT))
pmu_sbi_reset_scounteren((void *)event);
@@ -866,7 +880,7 @@ static void pmu_sbi_ctr_stop(struct perf_event *event, unsigned long flag)
static void pmu_sbi_sched_task(struct perf_event_pmu_context *pmu_ctx, struct task_struct *task,
bool sched_in)
{
- /* Call CTR specific Sched hook. */
+ riscv_pmu_ctr_sched_task(pmu_ctx, task, sched_in);
}
static int pmu_sbi_find_num_ctrs(void)
@@ -1140,6 +1154,12 @@ static irqreturn_t pmu_sbi_ovf_handler(struct cpu_hw_events *cpu_hw_evt,
hw_evt->state |= PERF_HES_UPTODATE;
perf_sample_data_init(&data, 0, hw_evt->last_period);
if (riscv_pmu_event_set_period(event)) {
+ if (needs_branch_stack(event)) {
+ riscv_pmu_ctr_consume(cpu_hw_evt, event);
+ perf_sample_save_brstack(&data, event,
+ &cpu_hw_evt->branches->branch_stack, NULL);
+ }
+
/*
* Unlike other ISAs, RISC-V don't have to disable interrupts
* to avoid throttling here. As per the specification, the
@@ -1228,6 +1248,8 @@ static int pmu_sbi_starting_cpu(unsigned int cpu, struct hlist_node *node)
enable_percpu_irq(riscv_pmu_irq, IRQ_TYPE_NONE);
}
+ riscv_pmu_ctr_starting_cpu();
+
if (sbi_pmu_snapshot_available())
return pmu_sbi_snapshot_setup(pmu, cpu);
@@ -1243,6 +1265,8 @@ static int pmu_sbi_dying_cpu(unsigned int cpu, struct hlist_node *node)
/* Disable all counters access for user mode now */
csr_write(CSR_SCOUNTEREN, 0x0);
+ riscv_pmu_ctr_dying_cpu();
+
if (sbi_pmu_snapshot_available())
return pmu_sbi_snapshot_disable();
@@ -1369,6 +1393,29 @@ static void riscv_pmu_destroy(struct riscv_pmu *pmu)
cpuhp_state_remove_instance(CPUHP_AP_PERF_RISCV_STARTING, &pmu->node);
}
+static int branch_records_alloc(struct riscv_pmu *pmu)
+{
+ struct branch_records __percpu *tmp_alloc_ptr;
+ struct branch_records *records;
+ struct cpu_hw_events *events;
+ int cpu;
+
+ if (!riscv_pmu_ctr_supported(pmu))
+ return 0;
+
+ tmp_alloc_ptr = alloc_percpu_gfp(struct branch_records, GFP_KERNEL);
+ if (!tmp_alloc_ptr)
+ return -ENOMEM;
+
+ for_each_possible_cpu(cpu) {
+ events = per_cpu_ptr(pmu->hw_events, cpu);
+ records = per_cpu_ptr(tmp_alloc_ptr, cpu);
+ events->branches = records;
+ }
+
+ return 0;
+}
+
static void pmu_sbi_event_init(struct perf_event *event)
{
/*
@@ -1381,6 +1428,9 @@ static void pmu_sbi_event_init(struct perf_event *event)
event->hw.flags |= PERF_EVENT_FLAG_USER_ACCESS;
else
event->hw.flags |= PERF_EVENT_FLAG_LEGACY;
+
+ if (branch_sample_call_stack(event))
+ event->attach_state |= PERF_ATTACH_TASK_DATA;
}
static void pmu_sbi_event_mapped(struct perf_event *event, struct mm_struct *mm)
@@ -1519,6 +1569,15 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
pmu->pmu.attr_groups = riscv_pmu_attr_groups;
pmu->pmu.parent = &pdev->dev;
+
+ ret = riscv_pmu_ctr_init(pmu);
+ if (ret)
+ goto out_free;
+
+ ret = branch_records_alloc(pmu);
+ if (ret)
+ goto out_ctr_finish;
+
pmu->cmask = cmask;
pmu->ctr_add = pmu_sbi_ctr_add;
pmu->ctr_del = pmu_sbi_ctr_del;
@@ -1535,6 +1594,10 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
pmu->csr_index = pmu_sbi_csr_index;
pmu->sched_task = pmu_sbi_sched_task;
+ ret = cpuhp_state_add_instance(CPUHP_AP_PERF_RISCV_STARTING, &pmu->node);
+ if (ret)
+ goto out_ctr_finish;
+
ret = riscv_pm_pmu_register(pmu);
if (ret)
goto out_unregister;
@@ -1584,6 +1647,9 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
out_unregister:
riscv_pmu_destroy(pmu);
+out_ctr_finish:
+ riscv_pmu_ctr_finish(pmu);
+
out_free:
kfree(pmu);
return ret;
--
2.43.0
next prev parent reply other threads:[~2026-11-06 17:41 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-06 17:39 [PATCH v4 0/7] riscv: pmu: Add support for Control Transfer Records Ext Vikram Singh
2026-11-06 17:39 ` [PATCH v4 1/7] perf: Increase the maximum number of branches remove_loops() can process Vikram Singh
2026-11-06 17:39 ` [PATCH v4 2/7] riscv: pmu: Add Control transfer records CSR definations Vikram Singh
2026-11-06 17:39 ` [PATCH v4 3/7] riscv: Add Control Transfer Records extension parsing Vikram Singh
2026-11-06 17:39 ` [PATCH v4 4/7] riscv: pmu: Add infrastructure for Control Transfer Record Vikram Singh
2026-11-06 17:39 ` [PATCH v4 5/7] riscv: pmu: Add driver for Control Transfer Records Ext Vikram Singh
2026-11-06 17:39 ` Vikram Singh [this message]
2026-11-06 17:39 ` [PATCH v4 7/7] dt-bindings: riscv: add Sxctr ISA extension description Vikram Singh
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=20261106173942.3175069-7-vikram.singh3@oss.qualcomm.com \
--to=vikram.singh3@oss.qualcomm.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=alex@ghiti.fr \
--cc=alexander.shishkin@linux.intel.com \
--cc=anup.patel@oss.qualcomm.com \
--cc=aou@eecs.berkeley.edu \
--cc=atishp@rivosinc.com \
--cc=beeman@rivosinc.com \
--cc=conor+dt@kernel.org \
--cc=conor@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=irogers@google.com \
--cc=jolsa@kernel.org \
--cc=kan.liang@linux.intel.com \
--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=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=palmer@dabbelt.com \
--cc=palmer@sifive.com \
--cc=paul.walmsley@sifive.com \
--cc=peterz@infradead.org \
--cc=rajnesh.kanwal49@gmail.com \
--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
all inboxes | Powered by JetHome®