Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf bench syscall: Add execve syscall benchmark

This commit adds the execve syscall benchmark, more syscall benchmarks
can be added in the future.

Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/1668052208-14047-5-git-send-email-yangtiezhu@loongson.cn
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Tiezhu Yang and committed by
Arnaldo Carvalho de Melo
540f8b56 391f84e5

+44
+3
tools/arch/x86/include/uapi/asm/unistd_32.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef __NR_execve 3 + #define __NR_execve 11 4 + #endif 2 5 #ifndef __NR_getppid 3 6 #define __NR_getppid 64 4 7 #endif
+3
tools/arch/x86/include/uapi/asm/unistd_64.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef __NR_execve 3 + #define __NR_execve 59 4 + #endif 2 5 #ifndef __NR_getppid 3 6 #define __NR_getppid 110 4 7 #endif
+1
tools/perf/bench/bench.h
··· 23 23 int bench_sched_pipe(int argc, const char **argv); 24 24 int bench_syscall_basic(int argc, const char **argv); 25 25 int bench_syscall_getpgid(int argc, const char **argv); 26 + int bench_syscall_execve(int argc, const char **argv); 26 27 int bench_mem_memcpy(int argc, const char **argv); 27 28 int bench_mem_memset(int argc, const char **argv); 28 29 int bench_mem_find_bit(int argc, const char **argv);
+36
tools/perf/bench/syscall.c
··· 14 14 #include <sys/time.h> 15 15 #include <sys/syscall.h> 16 16 #include <sys/types.h> 17 + #include <sys/wait.h> 17 18 #include <unistd.h> 18 19 #include <stdlib.h> 19 20 ··· 30 29 "perf bench syscall <options>", 31 30 NULL 32 31 }; 32 + 33 + static void test_execve(void) 34 + { 35 + const char *pathname = "/bin/true"; 36 + char *const argv[] = { (char *)pathname, NULL }; 37 + pid_t pid = fork(); 38 + 39 + if (pid < 0) { 40 + fprintf(stderr, "fork failed\n"); 41 + exit(1); 42 + } else if (pid == 0) { 43 + execve(pathname, argv, NULL); 44 + fprintf(stderr, "execve /bin/true failed\n"); 45 + exit(1); 46 + } else { 47 + if (waitpid(pid, NULL, 0) < 0) { 48 + fprintf(stderr, "waitpid failed\n"); 49 + exit(1); 50 + } 51 + } 52 + } 33 53 34 54 static int bench_syscall_common(int argc, const char **argv, int syscall) 35 55 { ··· 71 49 case __NR_getpgid: 72 50 getpgid(0); 73 51 break; 52 + case __NR_execve: 53 + test_execve(); 54 + /* Only loop 10000 times to save time */ 55 + if (i == 10000) 56 + loops = 10000; 57 + break; 74 58 default: 75 59 break; 76 60 } ··· 91 63 break; 92 64 case __NR_getpgid: 93 65 name = "getpgid()"; 66 + break; 67 + case __NR_execve: 68 + name = "execve()"; 94 69 break; 95 70 default: 96 71 break; ··· 141 110 int bench_syscall_getpgid(int argc, const char **argv) 142 111 { 143 112 return bench_syscall_common(argc, argv, __NR_getpgid); 113 + } 114 + 115 + int bench_syscall_execve(int argc, const char **argv) 116 + { 117 + return bench_syscall_common(argc, argv, __NR_execve); 144 118 }
+1
tools/perf/builtin-bench.c
··· 53 53 static struct bench syscall_benchmarks[] = { 54 54 { "basic", "Benchmark for basic getppid(2) calls", bench_syscall_basic }, 55 55 { "getpgid", "Benchmark for getpgid(2) calls", bench_syscall_getpgid }, 56 + { "execve", "Benchmark for execve(2) calls", bench_syscall_execve }, 56 57 { "all", "Run all syscall benchmarks", NULL }, 57 58 { NULL, NULL, NULL }, 58 59 };