From: Anup Patel <apatel@ventanamicro.com>
To: Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
Paul Walmsley <paul.walmsley@sifive.com>,
Palmer Dabbelt <palmer@dabbelt.com>,
Greg KH <gregkh@linuxfoundation.org>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
Ian Rogers <irogers@google.com>
Cc: Alexandre Ghiti <alex@ghiti.fr>,
Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@redhat.com>,
Namhyung Kim <namhyung@kernel.org>,
Mark Rutland <mark.rutland@arm.com>, Jiri Olsa <jolsa@kernel.org>,
Adrian Hunter <adrian.hunter@intel.com>,
Liang Kan <kan.liang@linux.intel.com>,
Mayuresh Chitale <mchitale@gmail.com>,
Anup Patel <anup@brainfault.org>,
Atish Patra <atish.patra@linux.dev>,
Andrew Jones <ajones@ventanamicro.com>,
Sunil V L <sunilvl@ventanamicro.com>,
linux-riscv@lists.infradead.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org,
Mayuresh Chitale <mchitale@ventanamicro.com>,
Anup Patel <apatel@ventanamicro.com>
Subject: [PATCH v2 10/12] perf tools: Add RISC-V trace PMU record capabilities
Date: Sat, 1 Nov 2025 21:12:43 +0530 [thread overview]
Message-ID: <20251101154245.162492-11-apatel@ventanamicro.com> (raw)
In-Reply-To: <20251101154245.162492-1-apatel@ventanamicro.com>
From: Mayuresh Chitale <mchitale@ventanamicro.com>
Introduce the required auxiliary API functions allowing the perf core
to interact with RISC-V trace perf driver.
Co-developed-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
---
tools/perf/arch/riscv/util/Build | 1 +
tools/perf/arch/riscv/util/auxtrace.c | 218 ++++++++++++++++++++++++++
tools/perf/util/auxtrace.c | 1 +
tools/perf/util/auxtrace.h | 1 +
tools/perf/util/rvtrace.h | 18 +++
5 files changed, 239 insertions(+)
create mode 100644 tools/perf/arch/riscv/util/auxtrace.c
create mode 100644 tools/perf/util/rvtrace.h
diff --git a/tools/perf/arch/riscv/util/Build b/tools/perf/arch/riscv/util/Build
index 58a672246024..2ba1fb98a0ad 100644
--- a/tools/perf/arch/riscv/util/Build
+++ b/tools/perf/arch/riscv/util/Build
@@ -3,3 +3,4 @@ perf-util-y += header.o
perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
+perf-util-$(CONFIG_AUXTRACE) += auxtrace.o
diff --git a/tools/perf/arch/riscv/util/auxtrace.c b/tools/perf/arch/riscv/util/auxtrace.c
new file mode 100644
index 000000000000..adc86bd38998
--- /dev/null
+++ b/tools/perf/arch/riscv/util/auxtrace.c
@@ -0,0 +1,218 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Risc-V E-Trace support
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/bitops.h>
+#include <linux/log2.h>
+#include <linux/zalloc.h>
+#include <time.h>
+
+#include <internal/lib.h> // page_size
+#include "../../../util/auxtrace.h"
+#include "../../../util/cpumap.h"
+#include "../../../util/debug.h"
+#include "../../../util/event.h"
+#include "../../../util/evlist.h"
+#include "../../../util/evsel.h"
+#include "../../../util/rvtrace.h"
+#include "../../../util/pmu.h"
+#include "../../../util/record.h"
+#include "../../../util/session.h"
+#include "../../../util/tsc.h"
+
+#define RVTRACE_PMU_NAME "rvtrace"
+#define KiB(x) ((x) * 1024)
+#define MiB(x) ((x) * 1024 * 1024)
+
+struct rvtrace_recording {
+ struct auxtrace_record itr;
+ struct perf_pmu *rvtrace_pmu;
+ struct evlist *evlist;
+};
+
+static size_t rvtrace_info_priv_size(struct auxtrace_record *itr __maybe_unused,
+ struct evlist *evlist __maybe_unused)
+{
+ return RVTRACE_AUXTRACE_PRIV_SIZE;
+}
+
+static int rvtrace_info_fill(struct auxtrace_record *itr, struct perf_session *session,
+ struct perf_record_auxtrace_info *auxtrace_info, size_t priv_size)
+{
+ struct rvtrace_recording *ptr = container_of(itr, struct rvtrace_recording, itr);
+ struct perf_pmu *rvtrace_pmu = ptr->rvtrace_pmu;
+
+ if (priv_size != RVTRACE_AUXTRACE_PRIV_SIZE)
+ return -EINVAL;
+
+ if (!session->evlist->core.nr_mmaps)
+ return -EINVAL;
+
+ auxtrace_info->type = PERF_AUXTRACE_RISCV_TRACE;
+ auxtrace_info->priv[0] = rvtrace_pmu->type;
+
+ return 0;
+}
+
+static int rvtrace_set_auxtrace_mmap_page(struct record_opts *opts)
+{
+ bool privileged = perf_event_paranoid_check(-1);
+
+ if (!opts->full_auxtrace)
+ return 0;
+
+ if (opts->full_auxtrace && !opts->auxtrace_mmap_pages) {
+ if (privileged) {
+ opts->auxtrace_mmap_pages = MiB(16) / page_size;
+ } else {
+ opts->auxtrace_mmap_pages = KiB(128) / page_size;
+ if (opts->mmap_pages == UINT_MAX)
+ opts->mmap_pages = KiB(256) / page_size;
+ }
+ }
+
+ /* Validate auxtrace_mmap_pages */
+ if (opts->auxtrace_mmap_pages) {
+ size_t sz = opts->auxtrace_mmap_pages * (size_t)page_size;
+ size_t min_sz = KiB(8);
+
+ if (sz < min_sz || !is_power_of_2(sz)) {
+ pr_err("Invalid mmap size : must be at least %zuKiB and a power of 2\n",
+ min_sz / 1024);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static int rvtrace_recording_options(struct auxtrace_record *itr, struct evlist *evlist,
+ struct record_opts *opts)
+{
+ struct rvtrace_recording *ptr = container_of(itr, struct rvtrace_recording, itr);
+ struct perf_pmu *rvtrace_pmu = ptr->rvtrace_pmu;
+ struct evsel *evsel, *rvtrace_evsel = NULL;
+ struct evsel *tracking_evsel;
+ int err;
+
+ ptr->evlist = evlist;
+ evlist__for_each_entry(evlist, evsel) {
+ if (evsel->core.attr.type == rvtrace_pmu->type) {
+ if (rvtrace_evsel) {
+ pr_err("There may be only one " RVTRACE_PMU_NAME "x event\n");
+ return -EINVAL;
+ }
+ evsel->core.attr.freq = 0;
+ evsel->core.attr.sample_period = 1;
+ evsel->needs_auxtrace_mmap = true;
+ rvtrace_evsel = evsel;
+ opts->full_auxtrace = true;
+ }
+ }
+
+ err = rvtrace_set_auxtrace_mmap_page(opts);
+ if (err)
+ return err;
+ /*
+ * To obtain the auxtrace buffer file descriptor, the auxtrace event
+ * must come first.
+ */
+ evlist__to_front(evlist, rvtrace_evsel);
+ evsel__set_sample_bit(rvtrace_evsel, TIME);
+
+ /* Add dummy event to keep tracking */
+ err = parse_event(evlist, "dummy:u");
+ if (err)
+ return err;
+
+ tracking_evsel = evlist__last(evlist);
+ evlist__set_tracking_event(evlist, tracking_evsel);
+
+ tracking_evsel->core.attr.freq = 0;
+ tracking_evsel->core.attr.sample_period = 1;
+ evsel__set_sample_bit(tracking_evsel, TIME);
+
+ return 0;
+}
+
+static u64 rvtrace_reference(struct auxtrace_record *itr __maybe_unused)
+{
+ return rdtsc();
+}
+
+static void rvtrace_recording_free(struct auxtrace_record *itr)
+{
+ struct rvtrace_recording *ptr =
+ container_of(itr, struct rvtrace_recording, itr);
+
+ free(ptr);
+}
+
+static struct auxtrace_record *rvtrace_recording_init(int *err, struct perf_pmu *rvtrace_pmu)
+{
+ struct rvtrace_recording *ptr;
+
+ if (!rvtrace_pmu) {
+ *err = -ENODEV;
+ return NULL;
+ }
+
+ ptr = zalloc(sizeof(*ptr));
+ if (!ptr) {
+ *err = -ENOMEM;
+ return NULL;
+ }
+
+ ptr->rvtrace_pmu = rvtrace_pmu;
+ ptr->itr.recording_options = rvtrace_recording_options;
+ ptr->itr.info_priv_size = rvtrace_info_priv_size;
+ ptr->itr.info_fill = rvtrace_info_fill;
+ ptr->itr.free = rvtrace_recording_free;
+ ptr->itr.reference = rvtrace_reference;
+ ptr->itr.read_finish = auxtrace_record__read_finish;
+ ptr->itr.alignment = 0;
+
+ *err = 0;
+ return &ptr->itr;
+}
+
+static struct perf_pmu *find_pmu_for_event(struct perf_pmu **pmus,
+ int pmu_nr, struct evsel *evsel)
+{
+ int i;
+
+ if (!pmus)
+ return NULL;
+
+ for (i = 0; i < pmu_nr; i++) {
+ if (evsel->core.attr.type == pmus[i]->type)
+ return pmus[i];
+ }
+
+ return NULL;
+}
+
+struct auxtrace_record *auxtrace_record__init(struct evlist *evlist, int *err)
+{
+ struct perf_pmu *rvtrace_pmu = NULL;
+ struct perf_pmu *found_etm = NULL;
+ struct evsel *evsel;
+
+ if (!evlist)
+ return NULL;
+
+ rvtrace_pmu = perf_pmus__find(RVTRACE_PMU_NAME);
+ evlist__for_each_entry(evlist, evsel) {
+ if (rvtrace_pmu && !found_etm)
+ found_etm = find_pmu_for_event(&rvtrace_pmu, 1, evsel);
+ }
+
+ if (found_etm)
+ return rvtrace_recording_init(err, rvtrace_pmu);
+
+ *err = 0;
+ return NULL;
+}
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
index 1539c1dc823c..c905563e0d8a 100644
--- a/tools/perf/util/auxtrace.c
+++ b/tools/perf/util/auxtrace.c
@@ -1394,6 +1394,7 @@ int perf_event__process_auxtrace_info(struct perf_session *session,
case PERF_AUXTRACE_VPA_DTL:
err = powerpc_vpadtl_process_auxtrace_info(event, session);
break;
+ case PERF_AUXTRACE_RISCV_TRACE:
case PERF_AUXTRACE_UNKNOWN:
default:
return -EINVAL;
diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h
index e0a5b39fed12..1c89a281a06c 100644
--- a/tools/perf/util/auxtrace.h
+++ b/tools/perf/util/auxtrace.h
@@ -51,6 +51,7 @@ enum auxtrace_type {
PERF_AUXTRACE_S390_CPUMSF,
PERF_AUXTRACE_HISI_PTT,
PERF_AUXTRACE_VPA_DTL,
+ PERF_AUXTRACE_RISCV_TRACE,
};
enum itrace_period_type {
diff --git a/tools/perf/util/rvtrace.h b/tools/perf/util/rvtrace.h
new file mode 100644
index 000000000000..93c041db8660
--- /dev/null
+++ b/tools/perf/util/rvtrace.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright(C) 2015 Linaro Limited. All rights reserved.
+ * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
+ */
+
+#ifndef INCLUDE__UTIL_PERF_RVTRACE_H__
+#define INCLUDE__UTIL_PERF_RVTRACE_H__
+
+#include "debug.h"
+#include "auxtrace.h"
+#include "util/event.h"
+#include "util/session.h"
+#include <linux/bits.h>
+
+#define RVTRACE_AUXTRACE_PRIV_SIZE sizeof(u64)
+
+#endif
--
2.43.0
next prev parent reply other threads:[~2025-11-01 15:44 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-01 15:42 [PATCH v2 00/12] Linux RISC-V trace framework and drivers Anup Patel
2025-11-01 15:42 ` [PATCH v2 01/12] dt-bindings: Add RISC-V trace component bindings Anup Patel
2025-11-20 16:39 ` Rob Herring
2026-01-02 3:38 ` Anup Patel
2025-11-01 15:42 ` [PATCH v2 02/12] rvtrace: Initial implementation of driver framework Anup Patel
2025-11-21 7:49 ` Nutty.Liu
2025-12-02 10:41 ` Bo Gan
2025-11-01 15:42 ` [PATCH v2 03/12] rvtrace: Add functions to create/destroy a trace component path Anup Patel
2025-11-01 15:42 ` [PATCH v2 04/12] rvtrace: Add functions to start/stop tracing on a " Anup Patel
2025-11-01 15:42 ` [PATCH v2 05/12] rvtrace: Add trace encoder driver Anup Patel
2025-11-01 15:42 ` [PATCH v2 06/12] rvtrace: Add function to copy into perf AUX buffer Anup Patel
2025-11-01 15:42 ` [PATCH v2 07/12] rvtrace: Add trace ramsink driver Anup Patel
2025-11-30 7:45 ` Bo Gan
2025-12-02 11:47 ` Mayuresh Chitale
2025-12-03 1:10 ` Bo Gan
2025-12-06 17:59 ` Mayuresh Chitale
2025-11-01 15:42 ` [PATCH v2 08/12] riscv: Enable DMA_RESTRICTED_POOL in defconfig Anup Patel
2025-11-01 15:42 ` [PATCH v2 09/12] rvtrace: Add perf driver for tracing using perf tool Anup Patel
2025-11-01 15:42 ` Anup Patel [this message]
2025-11-21 8:09 ` [PATCH v2 10/12] perf tools: Add RISC-V trace PMU record capabilities Nutty.Liu
2026-01-02 3:52 ` Anup Patel
2025-11-01 15:42 ` [PATCH v2 11/12] perf tools: Initial support for RISC-V trace decoder Anup Patel
2025-11-01 15:42 ` [PATCH v2 12/12] MAINTAINERS: Add entry for RISC-V trace framework and drivers Anup Patel
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=20251101154245.162492-11-apatel@ventanamicro.com \
--to=apatel@ventanamicro.com \
--cc=adrian.hunter@intel.com \
--cc=ajones@ventanamicro.com \
--cc=alex@ghiti.fr \
--cc=alexander.shishkin@linux.intel.com \
--cc=anup@brainfault.org \
--cc=atish.patra@linux.dev \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=gregkh@linuxfoundation.org \
--cc=irogers@google.com \
--cc=jolsa@kernel.org \
--cc=kan.liang@linux.intel.com \
--cc=krzk+dt@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=mark.rutland@arm.com \
--cc=mchitale@gmail.com \
--cc=mchitale@ventanamicro.com \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=palmer@dabbelt.com \
--cc=paul.walmsley@sifive.com \
--cc=peterz@infradead.org \
--cc=robh@kernel.org \
--cc=sunilvl@ventanamicro.com \
/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;
as well as URLs for NNTP newsgroup(s).