[PATCH 2/2] perf tsc: Replace the compile-time TSC support check with a weak hook
Chen Pei
cp0613 at linux.alibaba.com
Mon Sep 28 02:47:39 PDT 2026
The "TSC support" subtest of the "Convert perf time to TSC" test decides
whether the architecture is covered by matching compiler macros for
x86_64, i386 and arm64. That list has to be edited for every new
architecture, and it can drift apart from the set of architectures that
really provide a counter: util/tsc.c already ships a weak rdtsc() which
an architecture overrides with a strong definition when it has one.
Add a weak arch__rdtsc_supported() next to the weak rdtsc(), let the
test query it instead of the macros, and have x86, arm64 and riscv
override it in the file where they implement rdtsc(). Support is then
declared next to the counter it describes, and a caller can tell a stub
apart from a real counter without keeping its own copy of the macro
list. This follows the pattern of the other optional per-architecture
hooks in util/ such as get_cpuid_str().
x86 and arm64 keep the same behaviour, and riscv starts running the
subtest because it gained rdtsc() in the previous patch.
Signed-off-by: Chen Pei <cp0613 at linux.alibaba.com>
---
tools/perf/arch/arm64/util/tsc.c | 5 +++++
tools/perf/arch/riscv/util/tsc.c | 5 +++++
tools/perf/arch/x86/util/tsc.c | 5 +++++
tools/perf/tests/perf-time-to-tsc.c | 12 +-----------
tools/perf/util/tsc.c | 9 +++++++++
tools/perf/util/tsc.h | 1 +
6 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/tools/perf/arch/arm64/util/tsc.c b/tools/perf/arch/arm64/util/tsc.c
index cc85bd9e73f1..fd7fba50d0a6 100644
--- a/tools/perf/arch/arm64/util/tsc.c
+++ b/tools/perf/arch/arm64/util/tsc.c
@@ -19,3 +19,8 @@ u64 rdtsc(void)
return val;
}
+
+bool arch__rdtsc_supported(void)
+{
+ return true;
+}
diff --git a/tools/perf/arch/riscv/util/tsc.c b/tools/perf/arch/riscv/util/tsc.c
index 7cc4710ac38c..312b0c755439 100644
--- a/tools/perf/arch/riscv/util/tsc.c
+++ b/tools/perf/arch/riscv/util/tsc.c
@@ -17,3 +17,8 @@ u64 rdtsc(void)
return val;
}
+
+bool arch__rdtsc_supported(void)
+{
+ return true;
+}
diff --git a/tools/perf/arch/x86/util/tsc.c b/tools/perf/arch/x86/util/tsc.c
index 3a439e4b12d2..6c01e96b5c2e 100644
--- a/tools/perf/arch/x86/util/tsc.c
+++ b/tools/perf/arch/x86/util/tsc.c
@@ -17,6 +17,11 @@ u64 rdtsc(void)
return low | ((u64)high) << 32;
}
+bool arch__rdtsc_supported(void)
+{
+ return true;
+}
+
/*
* Derive the TSC frequency in Hz from the /proc/cpuinfo, for example:
* ...
diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c
index f8f71fdd32b1..c91e22d93b53 100644
--- a/tools/perf/tests/perf-time-to-tsc.c
+++ b/tools/perf/tests/perf-time-to-tsc.c
@@ -22,16 +22,6 @@
#include "tests.h"
#include "util/sample.h"
-/*
- * Except x86_64/i386 and Arm64, other archs don't support TSC in perf. Just
- * enable the test for x86_64/i386 and Arm64 archs.
- */
-#if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__)
-#define TSC_IS_SUPPORTED 1
-#else
-#define TSC_IS_SUPPORTED 0
-#endif
-
#define CHECK__(x) { \
while ((x) < 0) { \
pr_debug(#x " failed!\n"); \
@@ -49,7 +39,7 @@
static int test__tsc_is_supported(struct test_suite *test __maybe_unused,
int subtest __maybe_unused)
{
- if (!TSC_IS_SUPPORTED) {
+ if (!arch__rdtsc_supported()) {
pr_debug("Test not supported on this architecture\n");
return TEST_SKIP;
}
diff --git a/tools/perf/util/tsc.c b/tools/perf/util/tsc.c
index ebf289bf6b9d..815621b1d112 100644
--- a/tools/perf/util/tsc.c
+++ b/tools/perf/util/tsc.c
@@ -113,6 +113,15 @@ u64 __weak rdtsc(void)
return 0;
}
+/*
+ * An architecture that implements rdtsc() with a real counter should override
+ * this, so that users of the counter can tell a stub apart from support.
+ */
+bool __weak arch__rdtsc_supported(void)
+{
+ return false;
+}
+
size_t perf_event__fprintf_time_conv(union perf_event *event, FILE *fp)
{
struct perf_record_time_conv *tc = (struct perf_record_time_conv *)event;
diff --git a/tools/perf/util/tsc.h b/tools/perf/util/tsc.h
index 57ce8449647f..83e76b207365 100644
--- a/tools/perf/util/tsc.h
+++ b/tools/perf/util/tsc.h
@@ -25,6 +25,7 @@ int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
u64 perf_time_to_tsc(u64 ns, struct perf_tsc_conversion *tc);
u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc);
u64 rdtsc(void);
+bool arch__rdtsc_supported(void);
u64 arch_get_tsc_freq(void);
size_t perf_event__fprintf_time_conv(union perf_event *event, FILE *fp);
--
2.50.1
More information about the linux-riscv
mailing list