2022-11-09 18:03:48

by Namhyung Kim

[permalink] [raw]
Subject: [PATCHSET 00/12] perf test: Add test workloads (v1)

Hello,

In the shell tests, it needs to run a custom test workload to verify
the behaviors. This requires a working compiler when it runs the
tests. However it's not available in some test environments, making
hard to run those tests.

So I've added the test workload to the perf binary directly, so that
we can run them simply like:

$ perf test -w noploop

And convert most of the shell tests need compilers with this workloads.
The buildid test still requires a compiler since it needs to check
different build options to generate different kind of build-IDs.

I've checked perf test result after the changes but could not verify
architecture-specific ones (e.g. for arm64). It'd be nice if anyone
can check it out.

You can find it in 'perf/test-workload-v1' branch in

git://git.kernel.org/pub/scm/linux/kernel/git/namhyung/linux-perf.git

Thanks,
Namhyung


Namhyung Kim (12):
perf test: Add -w/--workload option
perf test: Replace pipe test workload with noploop
perf test: Add 'thloop' test workload
perf test: Replace record test workload with thloop
perf test: Add 'leafloop' test workload
perf test: Replace arm callgraph fp test workload with leafloop
perf test: Add 'sqrtloop' test workload
perf test: Replace arm spe fork test workload with sqrtloop
perf test: Add 'brstack' test workload
perf test: Replace brstack test workload
perf test: Add 'datasym' test workload
perf test: Replace data symbol test workload with datasym

tools/perf/tests/Build | 2 +
tools/perf/tests/builtin-test.c | 29 ++++++++
tools/perf/tests/shell/pipe_test.sh | 55 +++-------------
tools/perf/tests/shell/record.sh | 59 +----------------
.../perf/tests/shell/test_arm_callgraph_fp.sh | 30 +--------
tools/perf/tests/shell/test_arm_spe_fork.sh | 44 +------------
tools/perf/tests/shell/test_brstack.sh | 66 ++++---------------
tools/perf/tests/shell/test_data_symbol.sh | 29 +-------
tools/perf/tests/tests.h | 27 ++++++++
tools/perf/tests/workloads/Build | 12 ++++
tools/perf/tests/workloads/brstack.c | 39 +++++++++++
tools/perf/tests/workloads/datasym.c | 24 +++++++
tools/perf/tests/workloads/leafloop.c | 34 ++++++++++
tools/perf/tests/workloads/noploop.c | 32 +++++++++
tools/perf/tests/workloads/sqrtloop.c | 44 +++++++++++++
tools/perf/tests/workloads/thloop.c | 53 +++++++++++++++
16 files changed, 324 insertions(+), 255 deletions(-)
create mode 100644 tools/perf/tests/workloads/Build
create mode 100644 tools/perf/tests/workloads/brstack.c
create mode 100644 tools/perf/tests/workloads/datasym.c
create mode 100644 tools/perf/tests/workloads/leafloop.c
create mode 100644 tools/perf/tests/workloads/noploop.c
create mode 100644 tools/perf/tests/workloads/sqrtloop.c
create mode 100644 tools/perf/tests/workloads/thloop.c


base-commit: 816815b852216f3aa3a43e2ce91c5510927cd61b
--
2.38.1.431.g37b22c650d-goog



2022-11-09 18:03:49

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 11/12] perf test: Add 'datasym' test workload

The datasym workload is to check if perf mem command gets the data
addresses precisely. This is needed for data symbol test.

$ perf test -w datasym

I had to keep the buf1 in the data section, otherwise it could end
up in the BSS and was mmaped as a separate //anon region, then it
was not symbolized at all. It needs to be fixed separately.

Signed-off-by: Namhyung Kim <[email protected]>
---
tools/perf/tests/builtin-test.c | 1 +
tools/perf/tests/tests.h | 1 +
tools/perf/tests/workloads/Build | 2 ++
tools/perf/tests/workloads/datasym.c | 24 ++++++++++++++++++++++++
4 files changed, 28 insertions(+)
create mode 100644 tools/perf/tests/workloads/datasym.c

diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 69fa56939309..4c6ae59a4dfd 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -124,6 +124,7 @@ static struct test_workload *workloads[] = {
&workload__leafloop,
&workload__sqrtloop,
&workload__brstack,
+ &workload__datasym,
};

static int num_subtests(const struct test_suite *t)
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index dc96f59cac2e..e15f24cfc909 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -205,5 +205,6 @@ DECLARE_WORKLOAD(thloop);
DECLARE_WORKLOAD(leafloop);
DECLARE_WORKLOAD(sqrtloop);
DECLARE_WORKLOAD(brstack);
+DECLARE_WORKLOAD(datasym);

#endif /* TESTS_H */
diff --git a/tools/perf/tests/workloads/Build b/tools/perf/tests/workloads/Build
index c933cdcf91d1..ec3cb10c52ae 100644
--- a/tools/perf/tests/workloads/Build
+++ b/tools/perf/tests/workloads/Build
@@ -5,6 +5,8 @@ perf-y += thloop.o
perf-y += leafloop.o
perf-y += sqrtloop.o
perf-y += brstack.o
+perf-y += datasym.o

CFLAGS_leafloop.o = -g -O0 -fno-inline -fno-omit-frame-pointer
CFLAGS_brstack.o = -g -O0 -fno-inline
+CFLAGS_datasym.o = -g -O0 -fno-inline
diff --git a/tools/perf/tests/workloads/datasym.c b/tools/perf/tests/workloads/datasym.c
new file mode 100644
index 000000000000..ddd40bc63448
--- /dev/null
+++ b/tools/perf/tests/workloads/datasym.c
@@ -0,0 +1,24 @@
+#include <linux/compiler.h>
+#include "../tests.h"
+
+typedef struct _buf {
+ char data1;
+ char reserved[55];
+ char data2;
+} buf __attribute__((aligned(64)));
+
+static buf buf1 = {
+ /* to have this in the data section */
+ .reserved[0] = 1,
+};
+
+static int datasym(int argc __maybe_unused, const char **argv __maybe_unused)
+{
+ for (;;) {
+ buf1.data1++;
+ buf1.data2 += buf1.data1;
+ }
+ return 0;
+}
+
+DEFINE_WORKLOAD(datasym);
--
2.38.1.431.g37b22c650d-goog


2022-11-09 18:04:31

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 10/12] perf test: Replace brstack test workload

So that it can get rid of requirement of a compiler. Also rename the
symbols to match with the perf test workload.

Cc: German Gomez <[email protected]>
Signed-off-by: Namhyung Kim <[email protected]>
---
tools/perf/tests/shell/test_brstack.sh | 66 +++++---------------------
1 file changed, 12 insertions(+), 54 deletions(-)

diff --git a/tools/perf/tests/shell/test_brstack.sh b/tools/perf/tests/shell/test_brstack.sh
index ec801cffae6b..a8a182dea25f 100755
--- a/tools/perf/tests/shell/test_brstack.sh
+++ b/tools/perf/tests/shell/test_brstack.sh
@@ -4,18 +4,12 @@
# SPDX-License-Identifier: GPL-2.0
# German Gomez <[email protected]>, 2022

-# we need a C compiler to build the test programs
-# so bail if none is found
-if ! [ -x "$(command -v cc)" ]; then
- echo "failed: no compiler, install gcc"
- exit 2
-fi
-
# skip the test if the hardware doesn't support branch stack sampling
# and if the architecture doesn't support filter types: any,save_type,u
perf record -b -o- -B --branch-filter any,save_type,u true > /dev/null 2>&1 || exit 2

TMPDIR=$(mktemp -d /tmp/__perf_test.program.XXXXX)
+TESTPROG="perf test -w brstack"

cleanup() {
rm -rf $TMPDIR
@@ -23,57 +17,24 @@ cleanup() {

trap cleanup exit term int

-gen_test_program() {
- # generate test program
- cat << EOF > $1
-#define BENCH_RUNS 999999
-int cnt;
-void bar(void) {
-} /* return */
-void foo(void) {
- bar(); /* call */
-} /* return */
-void bench(void) {
- void (*foo_ind)(void) = foo;
- if ((cnt++) % 3) /* branch (cond) */
- foo(); /* call */
- bar(); /* call */
- foo_ind(); /* call (ind) */
-}
-int main(void)
-{
- int cnt = 0;
- while (1) {
- if ((cnt++) > BENCH_RUNS)
- break;
- bench(); /* call */
- } /* branch (uncond) */
- return 0;
-}
-EOF
-}
-
test_user_branches() {
echo "Testing user branch stack sampling"

- gen_test_program "$TEMPDIR/program.c"
- cc -fno-inline -g "$TEMPDIR/program.c" -o $TMPDIR/a.out
-
- perf record -o $TMPDIR/perf.data --branch-filter any,save_type,u -- $TMPDIR/a.out > /dev/null 2>&1
+ perf record -o $TMPDIR/perf.data --branch-filter any,save_type,u -- ${TESTPROG} > /dev/null 2>&1
perf script -i $TMPDIR/perf.data --fields brstacksym | xargs -n1 > $TMPDIR/perf.script

# example of branch entries:
- # foo+0x14/bar+0x40/P/-/-/0/CALL
+ # brstack_foo+0x14/brstack_bar+0x40/P/-/-/0/CALL

set -x
- egrep -m1 "^bench\+[^ ]*/foo\+[^ ]*/IND_CALL$" $TMPDIR/perf.script
- egrep -m1 "^foo\+[^ ]*/bar\+[^ ]*/CALL$" $TMPDIR/perf.script
- egrep -m1 "^bench\+[^ ]*/foo\+[^ ]*/CALL$" $TMPDIR/perf.script
- egrep -m1 "^bench\+[^ ]*/bar\+[^ ]*/CALL$" $TMPDIR/perf.script
- egrep -m1 "^bar\+[^ ]*/foo\+[^ ]*/RET$" $TMPDIR/perf.script
- egrep -m1 "^foo\+[^ ]*/bench\+[^ ]*/RET$" $TMPDIR/perf.script
- egrep -m1 "^bench\+[^ ]*/bench\+[^ ]*/COND$" $TMPDIR/perf.script
- egrep -m1 "^main\+[^ ]*/main\+[^ ]*/UNCOND$" $TMPDIR/perf.script
+ egrep -m1 "^brstack_bench\+[^ ]*/brstack_foo\+[^ ]*/IND_CALL$" $TMPDIR/perf.script
+ egrep -m1 "^brstack_foo\+[^ ]*/brstack_bar\+[^ ]*/CALL$" $TMPDIR/perf.script
+ egrep -m1 "^brstack_bench\+[^ ]*/brstack_foo\+[^ ]*/CALL$" $TMPDIR/perf.script
+ egrep -m1 "^brstack_bench\+[^ ]*/brstack_bar\+[^ ]*/CALL$" $TMPDIR/perf.script
+ egrep -m1 "^brstack_bar\+[^ ]*/brstack_foo\+[^ ]*/RET$" $TMPDIR/perf.script
+ egrep -m1 "^brstack_foo\+[^ ]*/brstsack_bench\+[^ ]*/RET$" $TMPDIR/perf.script
+ egrep -m1 "^brstack_bench\+[^ ]*/brstack_bench\+[^ ]*/COND$" $TMPDIR/perf.script
+ egrep -m1 "^brstack\+[^ ]*/brstack\+[^ ]*/UNCOND$" $TMPDIR/perf.script
set +x

# some branch types are still not being tested:
@@ -88,10 +49,7 @@ test_filter() {

echo "Testing branch stack filtering permutation ($filter,$expect)"

- gen_test_program "$TEMPDIR/program.c"
- cc -fno-inline -g "$TEMPDIR/program.c" -o $TMPDIR/a.out
-
- perf record -o $TMPDIR/perf.data --branch-filter $filter,save_type,u -- $TMPDIR/a.out > /dev/null 2>&1
+ perf record -o $TMPDIR/perf.data --branch-filter $filter,save_type,u -- ${TESTPROG} > /dev/null 2>&1
perf script -i $TMPDIR/perf.data --fields brstack | xargs -n1 > $TMPDIR/perf.script

# fail if we find any branch type that doesn't match any of the expected ones
--
2.38.1.431.g37b22c650d-goog


2022-11-09 18:04:57

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 03/12] perf test: Add 'thloop' test workload

The thloop is similar to noploop but runs in two threads. This is
needed to verify perf record --per-thread to handle multi-threaded
programs properly.

$ perf test -w thloop

It also takes an optional argument to specify runtime in seconds
(default: 1).

Signed-off-by: Namhyung Kim <[email protected]>
---
tools/perf/tests/builtin-test.c | 1 +
tools/perf/tests/tests.h | 1 +
tools/perf/tests/workloads/Build | 1 +
tools/perf/tests/workloads/thloop.c | 53 +++++++++++++++++++++++++++++
4 files changed, 56 insertions(+)
create mode 100644 tools/perf/tests/workloads/thloop.c

diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index ce641ccfcf81..161f38476e77 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -120,6 +120,7 @@ static struct test_suite **tests[] = {

static struct test_workload *workloads[] = {
&workload__noploop,
+ &workload__thloop,
};

static int num_subtests(const struct test_suite *t)
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index d315d0d6fc97..e6edfeeadaeb 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -201,5 +201,6 @@ struct test_workload workload__##work = { \

/* The list of test workloads */
DECLARE_WORKLOAD(noploop);
+DECLARE_WORKLOAD(thloop);

#endif /* TESTS_H */
diff --git a/tools/perf/tests/workloads/Build b/tools/perf/tests/workloads/Build
index f98e968d4633..b8964b1099c0 100644
--- a/tools/perf/tests/workloads/Build
+++ b/tools/perf/tests/workloads/Build
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0

perf-y += noploop.o
+perf-y += thloop.o
diff --git a/tools/perf/tests/workloads/thloop.c b/tools/perf/tests/workloads/thloop.c
new file mode 100644
index 000000000000..7fd3ac79e732
--- /dev/null
+++ b/tools/perf/tests/workloads/thloop.c
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <pthread.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <unistd.h>
+#include <linux/compiler.h>
+#include "../tests.h"
+
+static volatile int done;
+static volatile unsigned count;
+
+/* We want to check this symbol in perf report */
+noinline void test_loop(void);
+
+static void sighandler(int sig __maybe_unused)
+{
+ done = 1;
+}
+
+noinline void test_loop(void)
+{
+ while (!done)
+ count++;
+}
+
+static void *thfunc(void *arg)
+{
+ void (*loop_fn)(void) = arg;
+
+ loop_fn();
+ return NULL;
+}
+
+static int thloop(int argc, const char **argv)
+{
+ int sec = 1;
+ pthread_t th;
+
+ if (argc > 0)
+ sec = atoi(argv[0]);
+
+ signal(SIGINT, sighandler);
+ signal(SIGALRM, sighandler);
+ alarm(sec);
+
+ pthread_create(&th, NULL, thfunc, test_loop);
+ test_loop();
+ pthread_join(th, NULL);
+
+ return 0;
+}
+
+DEFINE_WORKLOAD(thloop);
--
2.38.1.431.g37b22c650d-goog


2022-11-09 18:05:13

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 12/12] perf test: Replace data symbol test workload with datasym

So that it can get rid of requirement of a compiler.

$ sudo ./perf test -v 109
109: Test data symbol :
--- start ---
test child forked, pid 844526
Recording workload...
[ perf record: Woken up 2 times to write data ]
[ perf record: Captured and wrote 0.354 MB /tmp/__perf_test.perf.data.GFeZO (4847 samples) ]
Cleaning up files...
test child finished with 0
---- end ----
Test data symbol: Ok

Cc: Leo Yan <[email protected]>
Signed-off-by: Namhyung Kim <[email protected]>
---
tools/perf/tests/shell/test_data_symbol.sh | 29 +---------------------
1 file changed, 1 insertion(+), 28 deletions(-)

diff --git a/tools/perf/tests/shell/test_data_symbol.sh b/tools/perf/tests/shell/test_data_symbol.sh
index cd6eb54d235d..d871e6c743ef 100755
--- a/tools/perf/tests/shell/test_data_symbol.sh
+++ b/tools/perf/tests/shell/test_data_symbol.sh
@@ -11,13 +11,7 @@ skip_if_no_mem_event() {

skip_if_no_mem_event || exit 2

-# skip if there's no compiler
-if ! [ -x "$(command -v cc)" ]; then
- echo "skip: no compiler, install gcc"
- exit 2
-fi
-
-TEST_PROGRAM=$(mktemp /tmp/__perf_test.program.XXXXX)
+TEST_PROGRAM="perf test -w datasym"
PERF_DATA=$(mktemp /tmp/__perf_test.perf.data.XXXXX)

check_result() {
@@ -45,31 +39,10 @@ cleanup_files()
{
echo "Cleaning up files..."
rm -f ${PERF_DATA}
- rm -f ${TEST_PROGRAM}
}

trap cleanup_files exit term int

-# compile test program
-echo "Compiling test program..."
-cat << EOF | cc -o ${TEST_PROGRAM} -x c -
-typedef struct _buf {
- char data1;
- char reserved[55];
- char data2;
-} buf __attribute__((aligned(64)));
-
-static buf buf1;
-
-int main(void) {
- for (;;) {
- buf1.data1++;
- buf1.data2 += buf1.data1;
- }
- return 0;
-}
-EOF
-
echo "Recording workload..."

# perf mem/c2c internally uses IBS PMU on AMD CPU which doesn't support
--
2.38.1.431.g37b22c650d-goog


2022-11-09 18:05:38

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 01/12] 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 <[email protected]>
---
tools/perf/tests/Build | 2 ++
tools/perf/tests/builtin-test.c | 24 +++++++++++++++++++++
tools/perf/tests/tests.h | 22 +++++++++++++++++++
tools/perf/tests/workloads/Build | 3 +++
tools/perf/tests/workloads/noploop.c | 32 ++++++++++++++++++++++++++++
5 files changed, 83 insertions(+)
create mode 100644 tools/perf/tests/workloads/Build
create mode 100644 tools/perf/tests/workloads/noploop.c

diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 2064a640facb..11b69023011b 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -103,3 +103,5 @@ endif
CFLAGS_attr.o += -DBINDIR="BUILD_STR($(bindir_SQ))" -DPYTHON="BUILD_STR($(PYTHON_WORD))"
CFLAGS_python-use.o += -DPYTHONPATH="BUILD_STR($(OUTPUT)python)" -DPYTHON="BUILD_STR($(PYTHON_WORD))"
CFLAGS_dwarf-unwind.o += -fno-optimize-sibling-calls
+
+perf-y += workloads/
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 7122eae1d98d..ce641ccfcf81 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -118,6 +118,10 @@ static struct test_suite **tests[] = {
arch_tests,
};

+static struct test_workload *workloads[] = {
+ &workload__noploop,
+};
+
static int num_subtests(const struct test_suite *t)
{
int num;
@@ -475,6 +479,21 @@ static int perf_test__list(int argc, const char **argv)
return 0;
}

+static int run_workload(const char *work, int argc, const char **argv)
+{
+ unsigned int i = 0;
+ struct test_workload *twl;
+
+ for (i = 0; i < ARRAY_SIZE(workloads); i++) {
+ twl = workloads[i];
+ if (!strcmp(twl->name, work))
+ return twl->func(argc, argv);
+ }
+
+ pr_info("No workload found: %s\n", work);
+ return -1;
+}
+
int cmd_test(int argc, const char **argv)
{
const char *test_usage[] = {
@@ -482,12 +501,14 @@ int cmd_test(int argc, const char **argv)
NULL,
};
const char *skip = NULL;
+ const char *workload = NULL;
const struct option test_options[] = {
OPT_STRING('s', "skip", &skip, "tests", "tests to skip"),
OPT_INCR('v', "verbose", &verbose,
"be more verbose (show symbol address, etc)"),
OPT_BOOLEAN('F', "dont-fork", &dont_fork,
"Do not fork for testcase"),
+ OPT_STRING('w', "workload", &workload, "work", "workload to run for testing"),
OPT_END()
};
const char * const test_subcommands[] = { "list", NULL };
@@ -504,6 +525,9 @@ int cmd_test(int argc, const char **argv)
if (argc >= 1 && !strcmp(argv[0], "list"))
return perf_test__list(argc - 1, argv + 1);

+ if (workload)
+ return run_workload(workload, argc, argv);
+
symbol_conf.priv_size = sizeof(int);
symbol_conf.sort_by_name = true;
symbol_conf.try_vmlinux_path = true;
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 5bbb8f6a48fc..d315d0d6fc97 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -180,4 +180,26 @@ int test__arch_unwind_sample(struct perf_sample *sample,
DECLARE_SUITE(vectors_page);
#endif

+/*
+ * Define test workloads to be used in test suites.
+ */
+typedef int (*workload_fnptr)(int argc, const char **argv);
+
+struct test_workload {
+ const char *name;
+ workload_fnptr func;
+};
+
+#define DECLARE_WORKLOAD(work) \
+ extern struct test_workload workload__##work
+
+#define DEFINE_WORKLOAD(work) \
+struct test_workload workload__##work = { \
+ .name = #work, \
+ .func = work, \
+}
+
+/* The list of test workloads */
+DECLARE_WORKLOAD(noploop);
+
#endif /* TESTS_H */
diff --git a/tools/perf/tests/workloads/Build b/tools/perf/tests/workloads/Build
new file mode 100644
index 000000000000..f98e968d4633
--- /dev/null
+++ b/tools/perf/tests/workloads/Build
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+perf-y += noploop.o
diff --git a/tools/perf/tests/workloads/noploop.c b/tools/perf/tests/workloads/noploop.c
new file mode 100644
index 000000000000..9e4d8d024259
--- /dev/null
+++ b/tools/perf/tests/workloads/noploop.c
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <stdlib.h>
+#include <signal.h>
+#include <unistd.h>
+#include <linux/compiler.h>
+#include "../tests.h"
+
+static volatile int done;
+
+static void sighandler(int sig __maybe_unused)
+{
+ done = 1;
+}
+
+static int noploop(int argc, const char **argv)
+{
+ int sec = 1;
+
+ if (argc > 0)
+ sec = atoi(argv[0]);
+
+ signal(SIGINT, sighandler);
+ signal(SIGALRM, sighandler);
+ alarm(sec);
+
+ while (!done)
+ continue;
+
+ return 0;
+}
+
+DEFINE_WORKLOAD(noploop);
--
2.38.1.431.g37b22c650d-goog


2022-11-09 18:05:59

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 07/12] perf test: Add 'sqrtloop' test workload

The sqrtloop creates a child process to run an infinite loop calling
sqrt() with rand(). This is needed for ARM SPE fork test.

$ perf test -w sqrtloop

It can take an optional argument to specify how long it will run in
seconds (default: 1).

Signed-off-by: Namhyung Kim <[email protected]>
---
tools/perf/tests/builtin-test.c | 1 +
tools/perf/tests/tests.h | 1 +
tools/perf/tests/workloads/Build | 1 +
tools/perf/tests/workloads/sqrtloop.c | 44 +++++++++++++++++++++++++++
4 files changed, 47 insertions(+)
create mode 100644 tools/perf/tests/workloads/sqrtloop.c

diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 0ed5ac452f6e..9acb7a93eeb9 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -122,6 +122,7 @@ static struct test_workload *workloads[] = {
&workload__noploop,
&workload__thloop,
&workload__leafloop,
+ &workload__sqrtloop,
};

static int num_subtests(const struct test_suite *t)
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 86804dd6452b..18c40319e67c 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -203,5 +203,6 @@ struct test_workload workload__##work = { \
DECLARE_WORKLOAD(noploop);
DECLARE_WORKLOAD(thloop);
DECLARE_WORKLOAD(leafloop);
+DECLARE_WORKLOAD(sqrtloop);

#endif /* TESTS_H */
diff --git a/tools/perf/tests/workloads/Build b/tools/perf/tests/workloads/Build
index 631596bdb2b3..1ca95cb0fdb5 100644
--- a/tools/perf/tests/workloads/Build
+++ b/tools/perf/tests/workloads/Build
@@ -3,5 +3,6 @@
perf-y += noploop.o
perf-y += thloop.o
perf-y += leafloop.o
+perf-y += sqrtloop.o

CFLAGS_leafloop.o = -g -O0 -fno-inline -fno-omit-frame-pointer
diff --git a/tools/perf/tests/workloads/sqrtloop.c b/tools/perf/tests/workloads/sqrtloop.c
new file mode 100644
index 000000000000..f7d1f8d4867b
--- /dev/null
+++ b/tools/perf/tests/workloads/sqrtloop.c
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <math.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <linux/compiler.h>
+#include <sys/wait.h>
+#include "../tests.h"
+
+static volatile int done;
+
+static void sighandler(int sig __maybe_unused)
+{
+ done = 1;
+}
+
+static int __sqrtloop(int sec)
+{
+ signal(SIGALRM, sighandler);
+ alarm(sec);
+
+ while (!done)
+ sqrt(rand());
+ return 0;
+}
+
+static int sqrtloop(int argc, const char **argv)
+{
+ int sec = 1;
+
+ if (argc > 0)
+ sec = atoi(argv[0]);
+
+ switch (fork()) {
+ case 0:
+ return __sqrtloop(sec);
+ case -1:
+ return -1;
+ default:
+ wait(NULL);
+ }
+ return 0;
+}
+
+DEFINE_WORKLOAD(sqrtloop);
--
2.38.1.431.g37b22c650d-goog


2022-11-09 18:14:04

by Namhyung Kim

[permalink] [raw]
Subject: [PATCH 05/12] perf test: Add 'leafloop' test workload

The leafloop workload is to run an infinite loop in the test_leaf
function. This is needed for the ARM fp callgraph test to verify if it
gets the correct callchains.

$ perf test -w leafloop

Signed-off-by: Namhyung Kim <[email protected]>
---
tools/perf/tests/builtin-test.c | 1 +
tools/perf/tests/tests.h | 1 +
tools/perf/tests/workloads/Build | 3 +++
tools/perf/tests/workloads/leafloop.c | 34 +++++++++++++++++++++++++++
4 files changed, 39 insertions(+)
create mode 100644 tools/perf/tests/workloads/leafloop.c

diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 161f38476e77..0ed5ac452f6e 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -121,6 +121,7 @@ static struct test_suite **tests[] = {
static struct test_workload *workloads[] = {
&workload__noploop,
&workload__thloop,
+ &workload__leafloop,
};

static int num_subtests(const struct test_suite *t)
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index e6edfeeadaeb..86804dd6452b 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -202,5 +202,6 @@ struct test_workload workload__##work = { \
/* The list of test workloads */
DECLARE_WORKLOAD(noploop);
DECLARE_WORKLOAD(thloop);
+DECLARE_WORKLOAD(leafloop);

#endif /* TESTS_H */
diff --git a/tools/perf/tests/workloads/Build b/tools/perf/tests/workloads/Build
index b8964b1099c0..631596bdb2b3 100644
--- a/tools/perf/tests/workloads/Build
+++ b/tools/perf/tests/workloads/Build
@@ -2,3 +2,6 @@

perf-y += noploop.o
perf-y += thloop.o
+perf-y += leafloop.o
+
+CFLAGS_leafloop.o = -g -O0 -fno-inline -fno-omit-frame-pointer
diff --git a/tools/perf/tests/workloads/leafloop.c b/tools/perf/tests/workloads/leafloop.c
new file mode 100644
index 000000000000..1bf5cc97649b
--- /dev/null
+++ b/tools/perf/tests/workloads/leafloop.c
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <stdlib.h>
+#include <linux/compiler.h>
+#include "../tests.h"
+
+/* We want to check these symbols in perf script */
+noinline void leaf(volatile int b);
+noinline void parent(volatile int b);
+
+static volatile int a;
+
+noinline void leaf(volatile int b)
+{
+ for (;;)
+ a += b;
+}
+
+noinline void parent(volatile int b)
+{
+ leaf(b);
+}
+
+static int leafloop(int argc, const char **argv)
+{
+ int c = 1;
+
+ if (argc > 0)
+ c = atoi(argv[0]);
+
+ parent(c);
+ return 0;
+}
+
+DEFINE_WORKLOAD(leafloop);
--
2.38.1.431.g37b22c650d-goog


2022-11-09 18:49:07

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: [PATCH 01/12] perf test: Add -w/--workload option

Em Wed, Nov 09, 2022 at 09:46:24AM -0800, Namhyung Kim escreveu:
> --- /dev/null
> +++ b/tools/perf/tests/workloads/noploop.c
> @@ -0,0 +1,32 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#include <stdlib.h>
> +#include <signal.h>
> +#include <unistd.h>
> +#include <linux/compiler.h>
> +#include "../tests.h"
> +
> +static volatile int done;
> +
> +static void sighandler(int sig __maybe_unused)
> +{
> + done = 1;
> +}

You forgot to do what was done in:

92ea0720ba9cf7f0 perf trace: Use sig_atomic_t to avoid undefined behaviour in a signal handler
691768968f2a13eb perf top: Use sig_atomic_t to avoid undefined behaviour in a signal handler
01513fdc18f395db perf stat: Use sig_atomic_t to avoid undefined behaviour in a signal handler
057929f9d083e80c perf session: Change type to avoid undefined behaviour in a signal handler
853596fb71f7c2f7 perf ftrace: Use sig_atomic_t to avoid UB
7f3374299f9762ba perf daemon: Use sig_atomic_t to avoid UB
8ed28c2b56b78442 perf record: Use sig_atomic_t for signal handlers
f3c9bd4e16a503cb perf build: Update to C standard to gnu11

To speed up the process here is one of those csets:

⬢[acme@toolbox perf]$ git show 01513fdc18f395db
commit 01513fdc18f395dbcc924bc5e9962b12f86f947a
Author: Ian Rogers <[email protected]>
Date: Mon Oct 24 11:19:11 2022 -0700

perf stat: Use sig_atomic_t to avoid undefined behaviour in a signal handler

Use sig_atomic_t for variables written/accessed in signal
handlers. This is undefined behavior as per:

https://wiki.sei.cmu.edu/confluence/display/c/SIG31-C.+Do+not+access+shared+objects+in+signal+handlers

Signed-off-by: Ian Rogers <[email protected]>
Cc: Adrian Hunter <[email protected]>
Cc: Alexander Shishkin <[email protected]>
Cc: Alexey Bayduraev <[email protected]>
Cc: German Gomez <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Leo Yan <[email protected]>
Cc: Mark Rutland <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Stephane Eranian <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index e52601a54b26d669..d5e1670bca204450 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -173,7 +173,7 @@ static struct target target = {

#define METRIC_ONLY_LEN 20

-static volatile pid_t child_pid = -1;
+static volatile sig_atomic_t child_pid = -1;
static int detailed_run = 0;
static bool transaction_run;
static bool topdown_run = false;
@@ -208,7 +208,7 @@ struct perf_stat {
static struct perf_stat perf_stat;
#define STAT_RECORD perf_stat.record

-static volatile int done = 0;
+static volatile sig_atomic_t done = 0;

static struct perf_stat_config stat_config = {
.aggr_mode = AGGR_GLOBAL,
@@ -580,7 +580,7 @@ static void disable_counters(void)
}
}

-static volatile int workload_exec_errno;
+static volatile sig_atomic_t workload_exec_errno;

/*
* evlist__prepare_workload will send a SIGUSR1
@@ -1039,7 +1039,7 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)
evlist__print_counters(evsel_list, &stat_config, &target, ts, argc, argv);
}

-static volatile int signr = -1;
+static volatile sig_atomic_t signr = -1;

static void skip_signal(int signo)
{
⬢[acme@toolbox perf]$

> +
> +static int noploop(int argc, const char **argv)
> +{
> + int sec = 1;
> +
> + if (argc > 0)
> + sec = atoi(argv[0]);
> +
> + signal(SIGINT, sighandler);
> + signal(SIGALRM, sighandler);
> + alarm(sec);
> +
> + while (!done)
> + continue;
> +
> + return 0;
> +}
> +
> +DEFINE_WORKLOAD(noploop);
> --
> 2.38.1.431.g37b22c650d-goog

--

- Arnaldo

2022-11-09 19:01:26

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: [PATCH 03/12] perf test: Add 'thloop' test workload

Em Wed, Nov 09, 2022 at 09:46:26AM -0800, Namhyung Kim escreveu:
> The thloop is similar to noploop but runs in two threads. This is
> needed to verify perf record --per-thread to handle multi-threaded
> programs properly.
>
> $ perf test -w thloop
>
> It also takes an optional argument to specify runtime in seconds
> (default: 1).
>
> Signed-off-by: Namhyung Kim <[email protected]>
> ---
> tools/perf/tests/builtin-test.c | 1 +
> tools/perf/tests/tests.h | 1 +
> tools/perf/tests/workloads/Build | 1 +
> tools/perf/tests/workloads/thloop.c | 53 +++++++++++++++++++++++++++++
> 4 files changed, 56 insertions(+)
> create mode 100644 tools/perf/tests/workloads/thloop.c
>
> diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
> index ce641ccfcf81..161f38476e77 100644
> --- a/tools/perf/tests/builtin-test.c
> +++ b/tools/perf/tests/builtin-test.c
> @@ -120,6 +120,7 @@ static struct test_suite **tests[] = {
>
> static struct test_workload *workloads[] = {
> &workload__noploop,
> + &workload__thloop,
> };
>
> static int num_subtests(const struct test_suite *t)
> diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
> index d315d0d6fc97..e6edfeeadaeb 100644
> --- a/tools/perf/tests/tests.h
> +++ b/tools/perf/tests/tests.h
> @@ -201,5 +201,6 @@ struct test_workload workload__##work = { \
>
> /* The list of test workloads */
> DECLARE_WORKLOAD(noploop);
> +DECLARE_WORKLOAD(thloop);
>
> #endif /* TESTS_H */
> diff --git a/tools/perf/tests/workloads/Build b/tools/perf/tests/workloads/Build
> index f98e968d4633..b8964b1099c0 100644
> --- a/tools/perf/tests/workloads/Build
> +++ b/tools/perf/tests/workloads/Build
> @@ -1,3 +1,4 @@
> # SPDX-License-Identifier: GPL-2.0
>
> perf-y += noploop.o
> +perf-y += thloop.o
> diff --git a/tools/perf/tests/workloads/thloop.c b/tools/perf/tests/workloads/thloop.c
> new file mode 100644
> index 000000000000..7fd3ac79e732
> --- /dev/null
> +++ b/tools/perf/tests/workloads/thloop.c
> @@ -0,0 +1,53 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#include <pthread.h>
> +#include <stdlib.h>
> +#include <signal.h>
> +#include <unistd.h>
> +#include <linux/compiler.h>
> +#include "../tests.h"
> +
> +static volatile int done;
> +static volatile unsigned count;

sig_atomic_t

> +/* We want to check this symbol in perf report */
> +noinline void test_loop(void);
> +
> +static void sighandler(int sig __maybe_unused)
> +{
> + done = 1;
> +}
> +
> +noinline void test_loop(void)
> +{
> + while (!done)
> + count++;
> +}
> +
> +static void *thfunc(void *arg)
> +{
> + void (*loop_fn)(void) = arg;
> +
> + loop_fn();
> + return NULL;
> +}
> +
> +static int thloop(int argc, const char **argv)
> +{
> + int sec = 1;
> + pthread_t th;
> +
> + if (argc > 0)
> + sec = atoi(argv[0]);
> +
> + signal(SIGINT, sighandler);
> + signal(SIGALRM, sighandler);
> + alarm(sec);
> +
> + pthread_create(&th, NULL, thfunc, test_loop);
> + test_loop();
> + pthread_join(th, NULL);
> +
> + return 0;
> +}
> +
> +DEFINE_WORKLOAD(thloop);
> --
> 2.38.1.431.g37b22c650d-goog

--

- Arnaldo

2022-11-09 20:07:02

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH 01/12] perf test: Add -w/--workload option

Hi Arnaldo,

On Wed, Nov 9, 2022 at 10:39 AM Arnaldo Carvalho de Melo
<[email protected]> wrote:
>
> Em Wed, Nov 09, 2022 at 09:46:24AM -0800, Namhyung Kim escreveu:
> > --- /dev/null
> > +++ b/tools/perf/tests/workloads/noploop.c
> > @@ -0,0 +1,32 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#include <stdlib.h>
> > +#include <signal.h>
> > +#include <unistd.h>
> > +#include <linux/compiler.h>
> > +#include "../tests.h"
> > +
> > +static volatile int done;
> > +
> > +static void sighandler(int sig __maybe_unused)
> > +{
> > + done = 1;
> > +}
>
> You forgot to do what was done in:

Oops, right. Will fix in v2.

Thanks,
Namhyung


>
> 92ea0720ba9cf7f0 perf trace: Use sig_atomic_t to avoid undefined behaviour in a signal handler
> 691768968f2a13eb perf top: Use sig_atomic_t to avoid undefined behaviour in a signal handler
> 01513fdc18f395db perf stat: Use sig_atomic_t to avoid undefined behaviour in a signal handler
> 057929f9d083e80c perf session: Change type to avoid undefined behaviour in a signal handler
> 853596fb71f7c2f7 perf ftrace: Use sig_atomic_t to avoid UB
> 7f3374299f9762ba perf daemon: Use sig_atomic_t to avoid UB
> 8ed28c2b56b78442 perf record: Use sig_atomic_t for signal handlers
> f3c9bd4e16a503cb perf build: Update to C standard to gnu11
>
> To speed up the process here is one of those csets:
>
> ⬢[acme@toolbox perf]$ git show 01513fdc18f395db
> commit 01513fdc18f395dbcc924bc5e9962b12f86f947a
> Author: Ian Rogers <[email protected]>
> Date: Mon Oct 24 11:19:11 2022 -0700
>
> perf stat: Use sig_atomic_t to avoid undefined behaviour in a signal handler
>
> Use sig_atomic_t for variables written/accessed in signal
> handlers. This is undefined behavior as per:
>
> https://wiki.sei.cmu.edu/confluence/display/c/SIG31-C.+Do+not+access+shared+objects+in+signal+handlers
>
> Signed-off-by: Ian Rogers <[email protected]>
> Cc: Adrian Hunter <[email protected]>
> Cc: Alexander Shishkin <[email protected]>
> Cc: Alexey Bayduraev <[email protected]>
> Cc: German Gomez <[email protected]>
> Cc: Ingo Molnar <[email protected]>
> Cc: Jiri Olsa <[email protected]>
> Cc: Leo Yan <[email protected]>
> Cc: Mark Rutland <[email protected]>
> Cc: Namhyung Kim <[email protected]>
> Cc: Peter Zijlstra <[email protected]>
> Cc: Stephane Eranian <[email protected]>
> Link: https://lore.kernel.org/r/[email protected]
> Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
>
> diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
> index e52601a54b26d669..d5e1670bca204450 100644
> --- a/tools/perf/builtin-stat.c
> +++ b/tools/perf/builtin-stat.c
> @@ -173,7 +173,7 @@ static struct target target = {
>
> #define METRIC_ONLY_LEN 20
>
> -static volatile pid_t child_pid = -1;
> +static volatile sig_atomic_t child_pid = -1;
> static int detailed_run = 0;
> static bool transaction_run;
> static bool topdown_run = false;
> @@ -208,7 +208,7 @@ struct perf_stat {
> static struct perf_stat perf_stat;
> #define STAT_RECORD perf_stat.record
>
> -static volatile int done = 0;
> +static volatile sig_atomic_t done = 0;
>
> static struct perf_stat_config stat_config = {
> .aggr_mode = AGGR_GLOBAL,
> @@ -580,7 +580,7 @@ static void disable_counters(void)
> }
> }
>
> -static volatile int workload_exec_errno;
> +static volatile sig_atomic_t workload_exec_errno;
>
> /*
> * evlist__prepare_workload will send a SIGUSR1
> @@ -1039,7 +1039,7 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)
> evlist__print_counters(evsel_list, &stat_config, &target, ts, argc, argv);
> }
>
> -static volatile int signr = -1;
> +static volatile sig_atomic_t signr = -1;
>
> static void skip_signal(int signo)
> {
> ⬢[acme@toolbox perf]$
>
> > +
> > +static int noploop(int argc, const char **argv)
> > +{
> > + int sec = 1;
> > +
> > + if (argc > 0)
> > + sec = atoi(argv[0]);
> > +
> > + signal(SIGINT, sighandler);
> > + signal(SIGALRM, sighandler);
> > + alarm(sec);
> > +
> > + while (!done)
> > + continue;
> > +
> > + return 0;
> > +}
> > +
> > +DEFINE_WORKLOAD(noploop);
> > --
> > 2.38.1.431.g37b22c650d-goog
>
> --
>
> - Arnaldo

2022-11-10 15:30:13

by German Gomez

[permalink] [raw]
Subject: Re: [PATCH 07/12] perf test: Add 'sqrtloop' test workload

On 09/11/2022 17:46, Namhyung Kim wrote:
> The sqrtloop creates a child process to run an infinite loop calling
> sqrt() with rand(). This is needed for ARM SPE fork test.
>
> $ perf test -w sqrtloop
>
> It can take an optional argument to specify how long it will run in
> seconds (default: 1).
>
> Signed-off-by: Namhyung Kim <[email protected]>
> ---
> tools/perf/tests/builtin-test.c | 1 +
> tools/perf/tests/tests.h | 1 +
> tools/perf/tests/workloads/Build | 1 +
> tools/perf/tests/workloads/sqrtloop.c | 44 +++++++++++++++++++++++++++
> 4 files changed, 47 insertions(+)
> create mode 100644 tools/perf/tests/workloads/sqrtloop.c
>
> diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
> index 0ed5ac452f6e..9acb7a93eeb9 100644
> --- a/tools/perf/tests/builtin-test.c
> +++ b/tools/perf/tests/builtin-test.c
> @@ -122,6 +122,7 @@ static struct test_workload *workloads[] = {
> &workload__noploop,
> &workload__thloop,
> &workload__leafloop,
> + &workload__sqrtloop,
> };
>
> static int num_subtests(const struct test_suite *t)
> diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
> index 86804dd6452b..18c40319e67c 100644
> --- a/tools/perf/tests/tests.h
> +++ b/tools/perf/tests/tests.h
> @@ -203,5 +203,6 @@ struct test_workload workload__##work = { \
> DECLARE_WORKLOAD(noploop);
> DECLARE_WORKLOAD(thloop);
> DECLARE_WORKLOAD(leafloop);
> +DECLARE_WORKLOAD(sqrtloop);
>
> #endif /* TESTS_H */
> diff --git a/tools/perf/tests/workloads/Build b/tools/perf/tests/workloads/Build
> index 631596bdb2b3..1ca95cb0fdb5 100644
> --- a/tools/perf/tests/workloads/Build
> +++ b/tools/perf/tests/workloads/Build
> @@ -3,5 +3,6 @@
> perf-y += noploop.o
> perf-y += thloop.o
> perf-y += leafloop.o
> +perf-y += sqrtloop.o
>
> CFLAGS_leafloop.o = -g -O0 -fno-inline -fno-omit-frame-pointer
> diff --git a/tools/perf/tests/workloads/sqrtloop.c b/tools/perf/tests/workloads/sqrtloop.c
> new file mode 100644
> index 000000000000..f7d1f8d4867b
> --- /dev/null
> +++ b/tools/perf/tests/workloads/sqrtloop.c
> @@ -0,0 +1,44 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#include <math.h>
> +#include <signal.h>
> +#include <stdlib.h>
> +#include <linux/compiler.h>
> +#include <sys/wait.h>
> +#include "../tests.h"
> +
> +static volatile int done;
> +
> +static void sighandler(int sig __maybe_unused)
> +{
> + done = 1;
> +}
> +
> +static int __sqrtloop(int sec)
> +{
> + signal(SIGALRM, sighandler);
> + alarm(sec);
> +
> + while (!done)
> + sqrt(rand());
> + return 0;
> +}

I get some implicit declaration errors on x86 build

(gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0)

.  CC      tests/workloads/sqrtloop.o
.tests/workloads/sqrtloop.c: In function ‘__sqrtloop’:
.tests/workloads/sqrtloop.c:19:2: error: implicit declaration of function ‘alarm’ [-Werror=implicit-function-declaration]
.   19 |  alarm(sec);
.      |  ^~~~~
.tests/workloads/sqrtloop.c: In function ‘sqrtloop’:
.tests/workloads/sqrtloop.c:33:10: error: implicit declaration of function ‘fork’ [-Werror=implicit-function-declaration]
.   33 |  switch (fork()) {
.      |          ^~~~

> +
> +static int sqrtloop(int argc, const char **argv)
> +{
> + int sec = 1;
> +
> + if (argc > 0)
> + sec = atoi(argv[0]);
> +
> + switch (fork()) {
> + case 0:
> + return __sqrtloop(sec);
> + case -1:
> + return -1;
> + default:
> + wait(NULL);
> + }
> + return 0;
> +}
> +
> +DEFINE_WORKLOAD(sqrtloop);

2022-11-10 18:33:49

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH 07/12] perf test: Add 'sqrtloop' test workload

Hello,

On Thu, Nov 10, 2022 at 6:49 AM German Gomez <[email protected]> wrote:
>
> On 09/11/2022 17:46, Namhyung Kim wrote:
> > The sqrtloop creates a child process to run an infinite loop calling
> > sqrt() with rand(). This is needed for ARM SPE fork test.
> >
> > $ perf test -w sqrtloop
> >
> > It can take an optional argument to specify how long it will run in
> > seconds (default: 1).
> >
> > Signed-off-by: Namhyung Kim <[email protected]>
> > ---
> > tools/perf/tests/builtin-test.c | 1 +
> > tools/perf/tests/tests.h | 1 +
> > tools/perf/tests/workloads/Build | 1 +
> > tools/perf/tests/workloads/sqrtloop.c | 44 +++++++++++++++++++++++++++
> > 4 files changed, 47 insertions(+)
> > create mode 100644 tools/perf/tests/workloads/sqrtloop.c
> >
> > diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
> > index 0ed5ac452f6e..9acb7a93eeb9 100644
> > --- a/tools/perf/tests/builtin-test.c
> > +++ b/tools/perf/tests/builtin-test.c
> > @@ -122,6 +122,7 @@ static struct test_workload *workloads[] = {
> > &workload__noploop,
> > &workload__thloop,
> > &workload__leafloop,
> > + &workload__sqrtloop,
> > };
> >
> > static int num_subtests(const struct test_suite *t)
> > diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
> > index 86804dd6452b..18c40319e67c 100644
> > --- a/tools/perf/tests/tests.h
> > +++ b/tools/perf/tests/tests.h
> > @@ -203,5 +203,6 @@ struct test_workload workload__##work = { \
> > DECLARE_WORKLOAD(noploop);
> > DECLARE_WORKLOAD(thloop);
> > DECLARE_WORKLOAD(leafloop);
> > +DECLARE_WORKLOAD(sqrtloop);
> >
> > #endif /* TESTS_H */
> > diff --git a/tools/perf/tests/workloads/Build b/tools/perf/tests/workloads/Build
> > index 631596bdb2b3..1ca95cb0fdb5 100644
> > --- a/tools/perf/tests/workloads/Build
> > +++ b/tools/perf/tests/workloads/Build
> > @@ -3,5 +3,6 @@
> > perf-y += noploop.o
> > perf-y += thloop.o
> > perf-y += leafloop.o
> > +perf-y += sqrtloop.o
> >
> > CFLAGS_leafloop.o = -g -O0 -fno-inline -fno-omit-frame-pointer
> > diff --git a/tools/perf/tests/workloads/sqrtloop.c b/tools/perf/tests/workloads/sqrtloop.c
> > new file mode 100644
> > index 000000000000..f7d1f8d4867b
> > --- /dev/null
> > +++ b/tools/perf/tests/workloads/sqrtloop.c
> > @@ -0,0 +1,44 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#include <math.h>
> > +#include <signal.h>
> > +#include <stdlib.h>
> > +#include <linux/compiler.h>
> > +#include <sys/wait.h>
> > +#include "../tests.h"
> > +
> > +static volatile int done;
> > +
> > +static void sighandler(int sig __maybe_unused)
> > +{
> > + done = 1;
> > +}
> > +
> > +static int __sqrtloop(int sec)
> > +{
> > + signal(SIGALRM, sighandler);
> > + alarm(sec);
> > +
> > + while (!done)
> > + sqrt(rand());
> > + return 0;
> > +}
>
> I get some implicit declaration errors on x86 build
>
> (gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0)
>
> . CC tests/workloads/sqrtloop.o
> .tests/workloads/sqrtloop.c: In function ‘__sqrtloop’:
> .tests/workloads/sqrtloop.c:19:2: error: implicit declaration of function ‘alarm’ [-Werror=implicit-function-declaration]
> . 19 | alarm(sec);
> . | ^~~~~
> .tests/workloads/sqrtloop.c: In function ‘sqrtloop’:
> .tests/workloads/sqrtloop.c:33:10: error: implicit declaration of function ‘fork’ [-Werror=implicit-function-declaration]
> . 33 | switch (fork()) {
> . | ^~~~

Oh, thanks for letting me know. I think it needs <unitstd.h>.
Will fix in v2.

Thanks,
Namhyung

>
> > +
> > +static int sqrtloop(int argc, const char **argv)
> > +{
> > + int sec = 1;
> > +
> > + if (argc > 0)
> > + sec = atoi(argv[0]);
> > +
> > + switch (fork()) {
> > + case 0:
> > + return __sqrtloop(sec);
> > + case -1:
> > + return -1;
> > + default:
> > + wait(NULL);
> > + }
> > + return 0;
> > +}
> > +
> > +DEFINE_WORKLOAD(sqrtloop);