Re: [PATCH] tools/testing/selftests/powerpc: Add Anton's null_syscall benchmark to the selftests

2019-01-23 Thread Christophe Leroy




Le 27/09/2016 à 16:10, Rui Teng a écrit :

From: Anton Blanchard 

Pull in a version of Anton's null_syscall benchmark:
http://ozlabs.org/~anton/junkcode/null_syscall.c
Into tools/testing/selftests/powerpc/benchmarks.

Suggested-by: Michael Ellerman 
Signed-off-by: Anton Blanchard 
Signed-off-by: Rui Teng 
---
  .../testing/selftests/powerpc/benchmarks/Makefile  |   2 +-
  .../selftests/powerpc/benchmarks/null_syscall.c| 157 +
  2 files changed, 158 insertions(+), 1 deletion(-)
  create mode 100644 tools/testing/selftests/powerpc/benchmarks/null_syscall.c



[...]


+
+static void do_null_syscall(unsigned long nr)
+{
+   unsigned long i;
+
+   for (i = 0; i < nr; i++)
+   getppid();
+}
+


Looks like getppid() performs a rcu_read_lock(). Is that what we want ?

Shouldn't we use getpid() instead for a lighter syscall ?

Christophe


[PATCH] tools/testing/selftests/powerpc: Add Anton's null_syscall benchmark to the selftests

2016-09-27 Thread Rui Teng
From: Anton Blanchard 

Pull in a version of Anton's null_syscall benchmark:
http://ozlabs.org/~anton/junkcode/null_syscall.c
Into tools/testing/selftests/powerpc/benchmarks.

Suggested-by: Michael Ellerman 
Signed-off-by: Anton Blanchard 
Signed-off-by: Rui Teng 
---
 .../testing/selftests/powerpc/benchmarks/Makefile  |   2 +-
 .../selftests/powerpc/benchmarks/null_syscall.c| 157 +
 2 files changed, 158 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/powerpc/benchmarks/null_syscall.c

diff --git a/tools/testing/selftests/powerpc/benchmarks/Makefile 
b/tools/testing/selftests/powerpc/benchmarks/Makefile
index a9adfb7..545077f 100644
--- a/tools/testing/selftests/powerpc/benchmarks/Makefile
+++ b/tools/testing/selftests/powerpc/benchmarks/Makefile
@@ -1,4 +1,4 @@
-TEST_PROGS := gettimeofday context_switch mmap_bench futex_bench
+TEST_PROGS := gettimeofday context_switch mmap_bench futex_bench null_syscall
 
 CFLAGS += -O2
 
diff --git a/tools/testing/selftests/powerpc/benchmarks/null_syscall.c 
b/tools/testing/selftests/powerpc/benchmarks/null_syscall.c
new file mode 100644
index 000..59c2f45
--- /dev/null
+++ b/tools/testing/selftests/powerpc/benchmarks/null_syscall.c
@@ -0,0 +1,157 @@
+/*
+ * Test null syscall performance
+ *
+ * Copyright (C) 2009-2015 Anton Blanchard , IBM
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define NR_LOOPS 1000
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static volatile int soak_done;
+unsigned long long clock_frequency;
+unsigned long long timebase_frequency;
+double timebase_multiplier;
+
+static inline unsigned long long mftb(void)
+{
+   unsigned long low;
+
+   asm volatile("mftb %0" : "=r" (low));
+
+   return low;
+}
+
+static void sigalrm_handler(int unused)
+{
+   soak_done = 1;
+}
+
+/*
+ * Use a timer instead of busy looping on clock_gettime() so we don't
+ * pollute profiles with glibc and VDSO hits.
+ */
+static void cpu_soak_usecs(unsigned long usecs)
+{
+   struct itimerval val;
+
+   memset(, 0, sizeof(val));
+   val.it_value.tv_usec = usecs;
+
+   signal(SIGALRM, sigalrm_handler);
+   setitimer(ITIMER_REAL, , NULL);
+
+   while (1) {
+   if (soak_done)
+   break;
+   }
+
+   signal(SIGALRM, SIG_DFL);
+}
+
+/*
+ * This only works with recent kernels where cpufreq modifies
+ * /proc/cpuinfo dynamically.
+ */
+static void get_proc_frequency(void)
+{
+   FILE *f;
+   char line[128];
+   char *p, *end;
+   unsigned long v;
+   double d;
+   char *override;
+
+   /* Try to get out of low power/low frequency mode */
+   cpu_soak_usecs(0.25 * 100);
+
+   f = fopen("/proc/cpuinfo", "r");
+   if (f == NULL)
+   return;
+
+   timebase_frequency = 0;
+
+   while (fgets(line, sizeof(line), f) != NULL) {
+   if (strncmp(line, "timebase", 8) == 0) {
+   p = strchr(line, ':');
+   if (p != NULL) {
+   v = strtoull(p + 1, , 0);
+   if (end != p + 1)
+   timebase_frequency = v;
+   }
+   }
+
+   if (((strncmp(line, "clock", 5) == 0) ||
+(strncmp(line, "cpu MHz", 7) == 0))) {
+   p = strchr(line, ':');
+   if (p != NULL) {
+   d = strtod(p + 1, );
+   if (end != p + 1) {
+   /* Find fastest clock frequency */
+   if ((d * 100ULL) > clock_frequency)
+   clock_frequency = d * 
100ULL;
+   }
+   }
+   }
+   }
+
+   fclose(f);
+
+   override = getenv("FREQUENCY");
+   if (override)
+   clock_frequency = strtoull(override, NULL, 10);
+
+   if (timebase_frequency)
+   timebase_multiplier = (double)clock_frequency
+   / timebase_frequency;
+   else
+   timebase_multiplier = 1;
+}
+
+static void do_null_syscall(unsigned long nr)
+{
+   unsigned long i;
+
+   for (i = 0; i < nr; i++)
+   getppid();
+}
+
+#define TIME(A, STR) \
+
+int main(void)
+{
+   unsigned long tb_start, tb_now;
+   struct timespec tv_start, tv_now;
+   unsigned long long elapsed_ns, elapsed_tb;
+
+   get_proc_frequency();
+
+