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

perf test: Add -w/--workload option

The -w/--workload option is to run a simple workload used by testing.
This adds a basic framework to run the workloads and 'noploop' workload
as an example.

$ perf test -w noploop

The noploop does a loop doing nothing (NOP) for a second by default.
It can have an optional argument to specify the time in seconds.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Athira Jajeev <atrajeev@linux.vnet.ibm.com>
Cc: German Gomez <german.gomez@arm.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Zhengjun Xing <zhengjun.xing@linux.intel.com>
Link: https://lore.kernel.org/r/20221116233854.1596378-2-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Namhyung Kim and committed by
Arnaldo Carvalho de Melo
f215054d e664f31e

+83
+2
tools/perf/tests/Build
··· 103 103 CFLAGS_attr.o += -DBINDIR="BUILD_STR($(bindir_SQ))" -DPYTHON="BUILD_STR($(PYTHON_WORD))" 104 104 CFLAGS_python-use.o += -DPYTHONPATH="BUILD_STR($(OUTPUT)python)" -DPYTHON="BUILD_STR($(PYTHON_WORD))" 105 105 CFLAGS_dwarf-unwind.o += -fno-optimize-sibling-calls 106 + 107 + perf-y += workloads/
+24
tools/perf/tests/builtin-test.c
··· 118 118 arch_tests, 119 119 }; 120 120 121 + static struct test_workload *workloads[] = { 122 + &workload__noploop, 123 + }; 124 + 121 125 static int num_subtests(const struct test_suite *t) 122 126 { 123 127 int num; ··· 479 475 return 0; 480 476 } 481 477 478 + static int run_workload(const char *work, int argc, const char **argv) 479 + { 480 + unsigned int i = 0; 481 + struct test_workload *twl; 482 + 483 + for (i = 0; i < ARRAY_SIZE(workloads); i++) { 484 + twl = workloads[i]; 485 + if (!strcmp(twl->name, work)) 486 + return twl->func(argc, argv); 487 + } 488 + 489 + pr_info("No workload found: %s\n", work); 490 + return -1; 491 + } 492 + 482 493 int cmd_test(int argc, const char **argv) 483 494 { 484 495 const char *test_usage[] = { ··· 501 482 NULL, 502 483 }; 503 484 const char *skip = NULL; 485 + const char *workload = NULL; 504 486 const struct option test_options[] = { 505 487 OPT_STRING('s', "skip", &skip, "tests", "tests to skip"), 506 488 OPT_INCR('v', "verbose", &verbose, 507 489 "be more verbose (show symbol address, etc)"), 508 490 OPT_BOOLEAN('F', "dont-fork", &dont_fork, 509 491 "Do not fork for testcase"), 492 + OPT_STRING('w', "workload", &workload, "work", "workload to run for testing"), 510 493 OPT_END() 511 494 }; 512 495 const char * const test_subcommands[] = { "list", NULL }; ··· 524 503 argc = parse_options_subcommand(argc, argv, test_options, test_subcommands, test_usage, 0); 525 504 if (argc >= 1 && !strcmp(argv[0], "list")) 526 505 return perf_test__list(argc - 1, argv + 1); 506 + 507 + if (workload) 508 + return run_workload(workload, argc, argv); 527 509 528 510 symbol_conf.priv_size = sizeof(int); 529 511 symbol_conf.sort_by_name = true;
+22
tools/perf/tests/tests.h
··· 180 180 DECLARE_SUITE(vectors_page); 181 181 #endif 182 182 183 + /* 184 + * Define test workloads to be used in test suites. 185 + */ 186 + typedef int (*workload_fnptr)(int argc, const char **argv); 187 + 188 + struct test_workload { 189 + const char *name; 190 + workload_fnptr func; 191 + }; 192 + 193 + #define DECLARE_WORKLOAD(work) \ 194 + extern struct test_workload workload__##work 195 + 196 + #define DEFINE_WORKLOAD(work) \ 197 + struct test_workload workload__##work = { \ 198 + .name = #work, \ 199 + .func = work, \ 200 + } 201 + 202 + /* The list of test workloads */ 203 + DECLARE_WORKLOAD(noploop); 204 + 183 205 #endif /* TESTS_H */
+3
tools/perf/tests/workloads/Build
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + 3 + perf-y += noploop.o
+32
tools/perf/tests/workloads/noploop.c
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #include <stdlib.h> 3 + #include <signal.h> 4 + #include <unistd.h> 5 + #include <linux/compiler.h> 6 + #include "../tests.h" 7 + 8 + static volatile sig_atomic_t done; 9 + 10 + static void sighandler(int sig __maybe_unused) 11 + { 12 + done = 1; 13 + } 14 + 15 + static int noploop(int argc, const char **argv) 16 + { 17 + int sec = 1; 18 + 19 + if (argc > 0) 20 + sec = atoi(argv[0]); 21 + 22 + signal(SIGINT, sighandler); 23 + signal(SIGALRM, sighandler); 24 + alarm(sec); 25 + 26 + while (!done) 27 + continue; 28 + 29 + return 0; 30 + } 31 + 32 + DEFINE_WORKLOAD(noploop);