diff mbox series

[1/1] rt-tests: oslat: Add riscv support

Message ID 20241211173832.1517196-1-ende.tan@starfivetech.com
State New
Headers show
Series [1/1] rt-tests: oslat: Add riscv support | expand

Commit Message

EnDe Tan Dec. 11, 2024, 5:38 p.m. UTC
From: Tan En De <ende.tan@starfivetech.com>

This commit is to support running oslat on riscv.
Ported frc() to use rdcycle instruction to get CPU cycles.

NOTE: Run this before running oslat on riscv.
echo 2 > /proc/sys/kernel/perf_user_access

See https://docs.kernel.org/admin-guide/sysctl/kernel.html#riscv

Signed-off-by: Tan En De <ende.tan@starfivetech.com>
---
 src/oslat/oslat.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)
diff mbox series

Patch

diff --git a/src/oslat/oslat.c b/src/oslat/oslat.c
index 0863297..460f102 100644
--- a/src/oslat/oslat.c
+++ b/src/oslat/oslat.c
@@ -43,6 +43,11 @@ 
 
 #include <linux/unistd.h>
 
+#ifdef __riscv
+#include <linux/perf_event.h>
+#include <sys/ioctl.h>
+#endif
+
 #include "rt-utils.h"
 #include "rt-numa.h"
 #include "rt-error.h"
@@ -101,6 +106,24 @@  static inline void frc(uint64_t *pval)
 	__asm__ __volatile__("isb" : : : "memory");
 
 }
+#elif defined(__riscv)
+#define relax()          __asm__ __volatile__("nop")
+
+static long perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu,
+		int group_fd, unsigned long flags)
+{
+	return syscall(__NR_perf_event_open, attr, pid, cpu, group_fd, flags);
+}
+
+/*
+ * NOTE: Due to the use of rdcycle instruction, before running oslat,
+ * Please run this command first:
+ * echo 2 > /proc/sys/kernel/perf_user_access
+ */
+static inline void frc(uint64_t *pval)
+{
+	asm volatile("rdcycle %0" : "=r" (*pval));
+}
 # else
 #  define relax()          do { } while (0)
 #  define frc(x)
@@ -176,6 +199,11 @@  struct thread {
 
 	/* These variables are calculated after the test */
 	double               average;
+
+#ifdef __riscv
+	/* File descriptor for cycles perf event */
+	int		     fd_cycles;
+#endif
 };
 
 struct global {
@@ -299,6 +327,26 @@  static unsigned int measure_counter_mhz(void)
 
 static void thread_init(struct thread *t)
 {
+#ifdef __riscv
+	struct perf_event_attr pe_cycles;
+	int fd_cycles;
+
+	memset(&pe_cycles, 0, sizeof(pe_cycles));
+	pe_cycles.type = PERF_TYPE_HARDWARE;
+	pe_cycles.size = sizeof(pe_cycles);
+	pe_cycles.config = PERF_COUNT_HW_CPU_CYCLES;
+	pe_cycles.disabled = 1;
+
+	fd_cycles = perf_event_open(&pe_cycles, 0, -1, -1, 0);
+	if (fd_cycles == -1) {
+		fprintf(stderr, "Error opening leader %#llx\n", pe_cycles.config);
+		exit(EXIT_FAILURE);
+	}
+	t->fd_cycles = fd_cycles;
+
+	ioctl(fd_cycles, PERF_EVENT_IOC_ENABLE, 0);
+#endif
+
 	t->counter_mhz = measure_counter_mhz();
 	t->maxlat = 0;
 	t->overflow_sum = 0;
@@ -449,6 +497,11 @@  static void *thread_main(void *arg)
 	while (g.n_threads_finished != g.n_threads)
 		relax();
 
+#ifdef __riscv
+	ioctl(t->fd_cycles, PERF_EVENT_IOC_DISABLE, 0);
+	close(t->fd_cycles);
+#endif
+
 	return NULL;
 }