From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933362AbcI0OK6 (ORCPT ); Tue, 27 Sep 2016 10:10:58 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:47854 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753865AbcI0OKt (ORCPT ); Tue, 27 Sep 2016 10:10:49 -0400 From: Rui Teng To: linuxppc-dev@lists.ozlabs.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Michael Ellerman , Shuah Khan , Anton Blanchard , Cyril Bur , Michael Neuling , Anton Blanchard , Rui Teng Subject: [PATCH] tools/testing/selftests/powerpc: Add Anton's null_syscall benchmark to the selftests Date: Tue, 27 Sep 2016 22:10:16 +0800 X-Mailer: git-send-email 2.9.0 X-TM-AS-GCONF: 00 X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16092714-0004-0000-0000-0000107A8A1A X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00005817; HX=3.00000240; KW=3.00000007; PH=3.00000004; SC=3.00000185; SDB=6.00761879; UDB=6.00362988; IPR=6.00536905; BA=6.00004761; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00012797; XFM=3.00000011; UTC=2016-09-27 14:10:46 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 16092714-0005-0000-0000-000079402B4E Message-Id: <20160927141016.6027-1-rui.teng@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2016-09-27_06:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=0 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1609020000 definitions=main-1609270260 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 0000000..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 10000000 + +#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(&val, 0, sizeof(val)); + val.it_value.tv_usec = usecs; + + signal(SIGALRM, sigalrm_handler); + setitimer(ITIMER_REAL, &val, 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 * 1000000); + + 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, &end, 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, &end); + if (end != p + 1) { + /* Find fastest clock frequency */ + if ((d * 1000000ULL) > clock_frequency) + clock_frequency = d * 1000000ULL; + } + } + } + } + + 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(); + + clock_gettime(CLOCK_MONOTONIC, &tv_start); + tb_start = mftb(); + + do_null_syscall(NR_LOOPS); + + clock_gettime(CLOCK_MONOTONIC, &tv_now); + tb_now = mftb(); + + elapsed_ns = (tv_now.tv_sec - tv_start.tv_sec) * 1000000000ULL + + (tv_now.tv_nsec - tv_start.tv_nsec); + elapsed_tb = tb_now - tb_start; + + printf("%10.2f ns %10.2f cycles\n", (float)elapsed_ns / NR_LOOPS, + (float)elapsed_tb * timebase_multiplier / NR_LOOPS); + + return 0; +} -- 2.7.4