[PATCH v2 1/2] perf riscv: Implement rdtsc()
Chen Pei
cp0613 at linux.alibaba.com
Mon Sep 28 20:41:32 PDT 2026
Perf has no riscv implementation of rdtsc(), so it links against the weak
stub in util/tsc.c and every caller reads a constant 0 that cannot be
told apart from a counter standing still.
Implement rdtsc() over the time CSR with rdtime. The time CSR is a TSC
equivalent on riscv: readable from user mode, constant frequency, and the
same counter riscv's arch_perf_update_userpage() builds the user page
conversion fields from, so the counter and perf time share a timebase.
Define it for RV64 only. Reading the counter whole on RV32 takes time and
timeh in a loop, and no RV32 user in tools/perf needs it that much, so
RV32 keeps the weak stub.
Reviewed-by: Anup Patel <anup at brainfault.org>
Signed-off-by: Chen Pei <cp0613 at linux.alibaba.com>
---
Changes in v2:
- Define rdtsc() for RV64 only.
tools/perf/arch/riscv/util/Build | 1 +
tools/perf/arch/riscv/util/tsc.c | 27 +++++++++++++++++++++++++++
2 files changed, 28 insertions(+)
create mode 100644 tools/perf/arch/riscv/util/tsc.c
diff --git a/tools/perf/arch/riscv/util/Build b/tools/perf/arch/riscv/util/Build
index 2328fb9a30a3..52cd6a481de8 100644
--- a/tools/perf/arch/riscv/util/Build
+++ b/tools/perf/arch/riscv/util/Build
@@ -1 +1,2 @@
perf-util-y += header.o
+perf-util-y += tsc.o
diff --git a/tools/perf/arch/riscv/util/tsc.c b/tools/perf/arch/riscv/util/tsc.c
new file mode 100644
index 000000000000..3dd419ce9d2a
--- /dev/null
+++ b/tools/perf/arch/riscv/util/tsc.c
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/types.h>
+
+#include "../../../util/tsc.h"
+
+/*
+ * RV32 is left to the weak stub: reading the counter whole there takes time
+ * and timeh in a loop, and no RV32 user in tools/perf needs it that much.
+ */
+#if defined(__riscv) && __riscv_xlen == 64
+
+u64 rdtsc(void)
+{
+ u64 val;
+
+ /*
+ * The time CSR ticks at a constant frequency and is the same counter
+ * the kernel feeds into the user page conversion fields through
+ * sched_clock(), so it is a TSC equivalent here.
+ */
+ asm volatile("rdtime %0" : "=r" (val));
+
+ return val;
+}
+
+#endif
--
2.50.1
More information about the linux-riscv
mailing list