From 493648d6795f00b6dcd6295b2b4221871bc1b25b Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Wed, 8 Mar 2023 08:36:14 +1100 Subject: selftests/powerpc: Increase timeout for vsx_signal test On the max config P10 machine (1920 threads and 64TB) this test fails with a timeout: Sending signals to all threads 10 times...!! killing vmx_signal !! child died by signal 15 failure: vmx_signal The default timeout is 120sec so increase this 3x to 360sec. With this change the test passes on these large machines. Signed-off-by: Michael Neuling Signed-off-by: Michael Ellerman Link: https://msgid.link/20230307213614.2652059-1-mikey@neuling.org --- tools/testing/selftests/powerpc/math/vmx_signal.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/math/vmx_signal.c b/tools/testing/selftests/powerpc/math/vmx_signal.c index b340a5c4e79d..c307dff19c12 100644 --- a/tools/testing/selftests/powerpc/math/vmx_signal.c +++ b/tools/testing/selftests/powerpc/math/vmx_signal.c @@ -151,5 +151,6 @@ int test_signal_vmx(void) int main(int argc, char *argv[]) { + test_harness_set_timeout(360); return test_harness(test_signal_vmx, "vmx_signal"); } -- cgit v1.2.3 From 8a32341cf04ba05974931b4664683c2c9fb84e56 Mon Sep 17 00:00:00 2001 From: Kajol Jain Date: Wed, 1 Mar 2023 22:39:17 +0530 Subject: selftests/powerpc/pmu: Fix sample field check in the mmcra_thresh_marked_sample_test The testcase verifies the setting of different fields in Monitor Mode Control Register A (MMCRA). In the current code, EV_CODE_EXTRACT macro is used to extract the "sample" field, which then needs to be further processed to fetch rand_samp_elig and rand_samp_mode bits. But the current code is not passing valid sample field to EV_CODE_EXTRACT macro. Patch addresses this by fixing the input for EV_CODE_EXTRACT. Fixes: 29cf373c5766 ("selftests/powerpc/pmu: Add interface test for mmcra register fields") Reported-by: David Binderman Link: https://lore.kernel.org/r/DB6P189MB0568CF002762C6C43AF6DF169CA89@DB6P189MB0568.EURP189.PROD.OUTLOOK.COM Signed-off-by: Kajol Jain Signed-off-by: Michael Ellerman Link: https://msgid.link/20230301170918.69176-1-kjain@linux.ibm.com --- .../powerpc/pmu/sampling_tests/mmcra_thresh_marked_sample_test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_thresh_marked_sample_test.c b/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_thresh_marked_sample_test.c index 022cc1655eb5..75527876ad3c 100644 --- a/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_thresh_marked_sample_test.c +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_thresh_marked_sample_test.c @@ -63,9 +63,9 @@ static int mmcra_thresh_marked_sample(void) get_mmcra_thd_stop(get_reg_value(intr_regs, "MMCRA"), 4)); FAIL_IF(EV_CODE_EXTRACT(event.attr.config, marked) != get_mmcra_marked(get_reg_value(intr_regs, "MMCRA"), 4)); - FAIL_IF(EV_CODE_EXTRACT(event.attr.config, sample >> 2) != + FAIL_IF((EV_CODE_EXTRACT(event.attr.config, sample) >> 2) != get_mmcra_rand_samp_elig(get_reg_value(intr_regs, "MMCRA"), 4)); - FAIL_IF(EV_CODE_EXTRACT(event.attr.config, sample & 0x3) != + FAIL_IF((EV_CODE_EXTRACT(event.attr.config, sample) & 0x3) != get_mmcra_sample_mode(get_reg_value(intr_regs, "MMCRA"), 4)); FAIL_IF(EV_CODE_EXTRACT(event.attr.config, sm) != get_mmcra_sm(get_reg_value(intr_regs, "MMCRA"), 4)); -- cgit v1.2.3 From 69608683a65be5322ef44091eaeb9890472b2eea Mon Sep 17 00:00:00 2001 From: Benjamin Gray Date: Tue, 28 Feb 2023 11:07:07 +1100 Subject: selftests/powerpc: Use CLEAN macro to fix make warning The CLEAN macro was added in 337f1e36 to prevent the Makefile:50: warning: overriding recipe for target 'clean' ../../lib.mk:124: warning: ignoring old recipe for target 'clean' style warnings. Expand it's use to fix another case of redefining a target directly. Signed-off-by: Benjamin Gray Signed-off-by: Michael Ellerman Link: https://msgid.link/20230228000709.124727-2-bgray@linux.ibm.com --- tools/testing/selftests/powerpc/pmu/Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/pmu/Makefile b/tools/testing/selftests/powerpc/pmu/Makefile index 30803353bd7c..d2c1accc2e69 100644 --- a/tools/testing/selftests/powerpc/pmu/Makefile +++ b/tools/testing/selftests/powerpc/pmu/Makefile @@ -46,11 +46,14 @@ override define INSTALL_RULE TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install endef -clean: +DEFAULT_CLEAN := $(CLEAN) +override define CLEAN + $(DEFAULT_CLEAN) $(RM) $(TEST_GEN_PROGS) $(OUTPUT)/loop.o TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean +endef ebb: TARGET=$@; BUILD_TARGET=$$OUTPUT/$$TARGET; mkdir -p $$BUILD_TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -k -C $$TARGET all @@ -61,4 +64,4 @@ sampling_tests: event_code_tests: TARGET=$@; BUILD_TARGET=$$OUTPUT/$$TARGET; mkdir -p $$BUILD_TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -k -C $$TARGET all -.PHONY: all run_tests clean ebb sampling_tests event_code_tests +.PHONY: all run_tests ebb sampling_tests event_code_tests -- cgit v1.2.3 From 4ecd0868c5138238dec8a1549bb6ff8e5b48208b Mon Sep 17 00:00:00 2001 From: Benjamin Gray Date: Tue, 28 Feb 2023 11:07:08 +1100 Subject: selftests/powerpc: Pass make context to children Make supports passing the 'jobserver' (parallel make support) to child invocations of make when either 1. The target command uses $(MAKE) directly 2. The command starts with '+' This context is not passed through expansions that result in $(MAKE), so the macros used in several places fail to pass on the jobserver context. Warnings are also raised by the child mentioning this. Prepend macros lines that invoke $(MAKE) with '+' to allow passing the jobserver context to these children. Signed-off-by: Benjamin Gray Signed-off-by: Michael Ellerman Link: https://msgid.link/20230228000709.124727-3-bgray@linux.ibm.com --- tools/testing/selftests/powerpc/Makefile | 8 ++++---- tools/testing/selftests/powerpc/pmu/Makefile | 24 ++++++++++++------------ 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile index 6ba95cd19e42..ae2bfc0d822f 100644 --- a/tools/testing/selftests/powerpc/Makefile +++ b/tools/testing/selftests/powerpc/Makefile @@ -45,28 +45,28 @@ $(SUB_DIRS): include ../lib.mk override define RUN_TESTS - @for TARGET in $(SUB_DIRS); do \ + +@for TARGET in $(SUB_DIRS); do \ BUILD_TARGET=$(OUTPUT)/$$TARGET; \ $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests;\ done; endef override define INSTALL_RULE - @for TARGET in $(SUB_DIRS); do \ + +@for TARGET in $(SUB_DIRS); do \ BUILD_TARGET=$(OUTPUT)/$$TARGET; \ $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install;\ done; endef override define EMIT_TESTS - @for TARGET in $(SUB_DIRS); do \ + +@for TARGET in $(SUB_DIRS); do \ BUILD_TARGET=$(OUTPUT)/$$TARGET; \ $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests;\ done; endef override define CLEAN - @for TARGET in $(SUB_DIRS); do \ + +@for TARGET in $(SUB_DIRS); do \ BUILD_TARGET=$(OUTPUT)/$$TARGET; \ $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean; \ done; diff --git a/tools/testing/selftests/powerpc/pmu/Makefile b/tools/testing/selftests/powerpc/pmu/Makefile index d2c1accc2e69..2b95e44d20ff 100644 --- a/tools/testing/selftests/powerpc/pmu/Makefile +++ b/tools/testing/selftests/powerpc/pmu/Makefile @@ -25,34 +25,34 @@ $(OUTPUT)/per_event_excludes: ../utils.c DEFAULT_RUN_TESTS := $(RUN_TESTS) override define RUN_TESTS $(DEFAULT_RUN_TESTS) - TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests - TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests - TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests + +TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests + +TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests + +TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests endef DEFAULT_EMIT_TESTS := $(EMIT_TESTS) override define EMIT_TESTS $(DEFAULT_EMIT_TESTS) - TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests - TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests - TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests + +TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests + +TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests + +TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests endef DEFAULT_INSTALL_RULE := $(INSTALL_RULE) override define INSTALL_RULE $(DEFAULT_INSTALL_RULE) - TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install - TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install - TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install + +TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install + +TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install + +TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install endef DEFAULT_CLEAN := $(CLEAN) override define CLEAN $(DEFAULT_CLEAN) $(RM) $(TEST_GEN_PROGS) $(OUTPUT)/loop.o - TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean - TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean - TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean + +TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean + +TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean + +TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean endef ebb: -- cgit v1.2.3 From d3cf1662b665f20444a08bff52b6daae912e0d1d Mon Sep 17 00:00:00 2001 From: Benjamin Gray Date: Tue, 28 Feb 2023 11:07:09 +1100 Subject: selftests/powerpc: Make dd output quiet dd logs info to stderr by default. This info is pointless in the selftests and makes legitimate issues harder to spot. Pass the option to silence the info logs. Actual errors would still be printed. Signed-off-by: Benjamin Gray Signed-off-by: Michael Ellerman Link: https://msgid.link/20230228000709.124727-4-bgray@linux.ibm.com --- tools/testing/selftests/powerpc/mm/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/mm/Makefile b/tools/testing/selftests/powerpc/mm/Makefile index 19dd0b2ea397..4a6608beef0e 100644 --- a/tools/testing/selftests/powerpc/mm/Makefile +++ b/tools/testing/selftests/powerpc/mm/Makefile @@ -32,7 +32,7 @@ $(OUTPUT)/stack_expansion_ldst: CFLAGS += -fno-stack-protector $(OUTPUT)/stack_expansion_ldst: ../utils.c $(OUTPUT)/tempfile: - dd if=/dev/zero of=$@ bs=64k count=1 + dd if=/dev/zero of=$@ bs=64k count=1 status=none $(OUTPUT)/tlbie_test: LDLIBS += -lpthread $(OUTPUT)/pkey_siginfo: LDLIBS += -lpthread -- cgit v1.2.3 From 4e991e3c16a350d1eeffc100ce3fb25292596d03 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 8 Apr 2023 12:17:50 +1000 Subject: powerpc: add CFUNC assembly label annotation This macro is to be used in assembly where C functions are called. pcrel addressing mode requires branches to functions with a localentry value of 1 to have either a trailing nop or @notoc. This macro permits the latter without changing callers. Signed-off-by: Nicholas Piggin [mpe: Add dummy definitions to fix selftests build] Signed-off-by: Michael Ellerman Link: https://msgid.link/20230408021752.862660-5-npiggin@gmail.com --- tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h | 1 + tools/testing/selftests/powerpc/stringloops/asm/ppc_asm.h | 1 + 2 files changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h b/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h index 003e1b3d9300..a89f1fbf86ec 100644 --- a/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h +++ b/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h @@ -27,6 +27,7 @@ #define _GLOBAL_TOC(A) _GLOBAL(A) #define _GLOBAL_TOC_KASAN(A) _GLOBAL(A) #define _GLOBAL_KASAN(A) _GLOBAL(A) +#define CFUNC(name) name #define PPC_MTOCRF(A, B) mtocrf A, B diff --git a/tools/testing/selftests/powerpc/stringloops/asm/ppc_asm.h b/tools/testing/selftests/powerpc/stringloops/asm/ppc_asm.h index 2b488b78c4f2..e713b69d694a 100644 --- a/tools/testing/selftests/powerpc/stringloops/asm/ppc_asm.h +++ b/tools/testing/selftests/powerpc/stringloops/asm/ppc_asm.h @@ -9,6 +9,7 @@ #define _GLOBAL(A) FUNC_START(test_ ## A) #define _GLOBAL_TOC(A) FUNC_START(test_ ## A) +#define CFUNC(name) name #define CONFIG_ALTIVEC -- cgit v1.2.3 From 15f0c2601e141e3c01c8dc3368b81181bc1c9228 Mon Sep 17 00:00:00 2001 From: Benjamin Gray Date: Thu, 6 Apr 2023 14:33:14 +1000 Subject: selftests/powerpc/dscr: Correct typos Correct a couple of typos while working on other improvements to the DSCR tests. Signed-off-by: Benjamin Gray Signed-off-by: Michael Ellerman Link: https://msgid.link/20230406043320.125138-2-bgray@linux.ibm.com --- tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c | 4 ++-- tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c | 4 ++-- tools/testing/selftests/powerpc/dscr/dscr_user_test.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c b/tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c index 32fcf2b324b1..5659d98cf340 100644 --- a/tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c +++ b/tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c @@ -7,8 +7,8 @@ * privilege state SPR and the problem state SPR for this purpose. * * When using the privilege state SPR, the instructions such as - * mfspr or mtspr are priviledged and the kernel emulates them - * for us. Instructions using problem state SPR can be exuecuted + * mfspr or mtspr are privileged and the kernel emulates them + * for us. Instructions using problem state SPR can be executed * directly without any emulation if the HW supports them. Else * they also get emulated by the kernel. * diff --git a/tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c b/tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c index f9dfd3d3c2d5..68ce328e813e 100644 --- a/tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c +++ b/tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c @@ -7,8 +7,8 @@ * value using mfspr. * * When using the privilege state SPR, the instructions such as - * mfspr or mtspr are priviledged and the kernel emulates them - * for us. Instructions using problem state SPR can be exuecuted + * mfspr or mtspr are privileged and the kernel emulates them + * for us. Instructions using problem state SPR can be executed * directly without any emulation if the HW supports them. Else * they also get emulated by the kernel. * diff --git a/tools/testing/selftests/powerpc/dscr/dscr_user_test.c b/tools/testing/selftests/powerpc/dscr/dscr_user_test.c index e09072446dd3..67bb872a246a 100644 --- a/tools/testing/selftests/powerpc/dscr/dscr_user_test.c +++ b/tools/testing/selftests/powerpc/dscr/dscr_user_test.c @@ -8,8 +8,8 @@ * numbers. * * When using the privilege state SPR, the instructions such as - * mfspr or mtspr are priviledged and the kernel emulates them - * for us. Instructions using problem state SPR can be exuecuted + * mfspr or mtspr are privileged and the kernel emulates them + * for us. Instructions using problem state SPR can be executed * directly without any emulation if the HW supports them. Else * they also get emulated by the kernel. * -- cgit v1.2.3 From c97b2fc6627e1c26a3a84633e135322918a1e592 Mon Sep 17 00:00:00 2001 From: Benjamin Gray Date: Thu, 6 Apr 2023 14:33:15 +1000 Subject: selftests/powerpc: Move bind_to_cpu() to utils.h This function will be useful in the DSCR test patches later in this series, so promote it to be shared by all powerpc selftests. Signed-off-by: Benjamin Gray Signed-off-by: Michael Ellerman Link: https://msgid.link/20230406043320.125138-3-bgray@linux.ibm.com --- tools/testing/selftests/powerpc/include/utils.h | 1 + tools/testing/selftests/powerpc/pmu/lib.c | 13 ------------- tools/testing/selftests/powerpc/pmu/lib.h | 1 - tools/testing/selftests/powerpc/utils.c | 12 ++++++++++++ 4 files changed, 13 insertions(+), 14 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/include/utils.h b/tools/testing/selftests/powerpc/include/utils.h index eed7dd7582b2..d3589e16a20f 100644 --- a/tools/testing/selftests/powerpc/include/utils.h +++ b/tools/testing/selftests/powerpc/include/utils.h @@ -32,6 +32,7 @@ void *find_auxv_entry(int type, char *auxv); void *get_auxv_entry(int type); int pick_online_cpu(void); +int bind_to_cpu(int cpu); int parse_intmax(const char *buffer, size_t count, intmax_t *result, int base); int parse_uintmax(const char *buffer, size_t count, uintmax_t *result, int base); diff --git a/tools/testing/selftests/powerpc/pmu/lib.c b/tools/testing/selftests/powerpc/pmu/lib.c index 719f94f10d41..144f90a78d69 100644 --- a/tools/testing/selftests/powerpc/pmu/lib.c +++ b/tools/testing/selftests/powerpc/pmu/lib.c @@ -14,19 +14,6 @@ #include "utils.h" #include "lib.h" - -int bind_to_cpu(int cpu) -{ - cpu_set_t mask; - - printf("Binding to cpu %d\n", cpu); - - CPU_ZERO(&mask); - CPU_SET(cpu, &mask); - - return sched_setaffinity(0, sizeof(mask), &mask); -} - #define PARENT_TOKEN 0xAA #define CHILD_TOKEN 0x55 diff --git a/tools/testing/selftests/powerpc/pmu/lib.h b/tools/testing/selftests/powerpc/pmu/lib.h index bf1bec013bbb..1d62403ae6ea 100644 --- a/tools/testing/selftests/powerpc/pmu/lib.h +++ b/tools/testing/selftests/powerpc/pmu/lib.h @@ -20,7 +20,6 @@ union pipe { int fds[2]; }; -extern int bind_to_cpu(int cpu); extern int kill_child_and_wait(pid_t child_pid); extern int wait_for_child(pid_t child_pid); extern int sync_with_child(union pipe read_pipe, union pipe write_pipe); diff --git a/tools/testing/selftests/powerpc/utils.c b/tools/testing/selftests/powerpc/utils.c index 7c8cfedb012a..cdb996dba703 100644 --- a/tools/testing/selftests/powerpc/utils.c +++ b/tools/testing/selftests/powerpc/utils.c @@ -452,6 +452,18 @@ done: return cpu; } +int bind_to_cpu(int cpu) +{ + cpu_set_t mask; + + printf("Binding to cpu %d\n", cpu); + + CPU_ZERO(&mask); + CPU_SET(cpu, &mask); + + return sched_setaffinity(0, sizeof(mask), &mask); +} + bool is_ppc64le(void) { struct utsname uts; -- cgit v1.2.3 From 6ff4dc25483f3f49d1db48af28d4c485fc77bd21 Mon Sep 17 00:00:00 2001 From: Benjamin Gray Date: Thu, 6 Apr 2023 14:33:16 +1000 Subject: selftests/powerpc: Allow bind_to_cpu() to automatically pick CPU All current users of bind_to_cpu() don't care _which_ CPU they get, just that they are bound to a single free one. So alter the interface to 1. Accept a BIND_CPU_ANY value that tells it to automatically pick a CPU 2. Return the picked CPU And convert all these users to bind_to_cpu(BIND_CPU_ANY). Signed-off-by: Benjamin Gray Signed-off-by: Michael Ellerman Link: https://msgid.link/20230406043320.125138-4-bgray@linux.ibm.com --- tools/testing/selftests/powerpc/include/utils.h | 2 ++ .../powerpc/pmu/ebb/cpu_event_pinned_vs_ebb_test.c | 3 +-- .../selftests/powerpc/pmu/ebb/cpu_event_vs_ebb_test.c | 3 +-- .../selftests/powerpc/pmu/ebb/ebb_vs_cpu_event_test.c | 3 +-- .../selftests/powerpc/pmu/ebb/multi_ebb_procs_test.c | 6 ++---- tools/testing/selftests/powerpc/pmu/lib.c | 6 ++---- tools/testing/selftests/powerpc/utils.c | 13 ++++++++++++- 7 files changed, 21 insertions(+), 15 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/include/utils.h b/tools/testing/selftests/powerpc/include/utils.h index d3589e16a20f..44bfd48b93d6 100644 --- a/tools/testing/selftests/powerpc/include/utils.h +++ b/tools/testing/selftests/powerpc/include/utils.h @@ -31,6 +31,8 @@ int read_auxv(char *buf, ssize_t buf_size); void *find_auxv_entry(int type, char *auxv); void *get_auxv_entry(int type); +#define BIND_CPU_ANY (-1) + int pick_online_cpu(void); int bind_to_cpu(int cpu); diff --git a/tools/testing/selftests/powerpc/pmu/ebb/cpu_event_pinned_vs_ebb_test.c b/tools/testing/selftests/powerpc/pmu/ebb/cpu_event_pinned_vs_ebb_test.c index 3cd33eb51e5e..fab7f34d7ce1 100644 --- a/tools/testing/selftests/powerpc/pmu/ebb/cpu_event_pinned_vs_ebb_test.c +++ b/tools/testing/selftests/powerpc/pmu/ebb/cpu_event_pinned_vs_ebb_test.c @@ -45,9 +45,8 @@ int cpu_event_pinned_vs_ebb(void) SKIP_IF(!ebb_is_supported()); - cpu = pick_online_cpu(); + cpu = bind_to_cpu(BIND_CPU_ANY); FAIL_IF(cpu < 0); - FAIL_IF(bind_to_cpu(cpu)); FAIL_IF(pipe(read_pipe.fds) == -1); FAIL_IF(pipe(write_pipe.fds) == -1); diff --git a/tools/testing/selftests/powerpc/pmu/ebb/cpu_event_vs_ebb_test.c b/tools/testing/selftests/powerpc/pmu/ebb/cpu_event_vs_ebb_test.c index 8466ef9d7de8..7c54c262036e 100644 --- a/tools/testing/selftests/powerpc/pmu/ebb/cpu_event_vs_ebb_test.c +++ b/tools/testing/selftests/powerpc/pmu/ebb/cpu_event_vs_ebb_test.c @@ -43,9 +43,8 @@ int cpu_event_vs_ebb(void) SKIP_IF(!ebb_is_supported()); - cpu = pick_online_cpu(); + cpu = bind_to_cpu(BIND_CPU_ANY); FAIL_IF(cpu < 0); - FAIL_IF(bind_to_cpu(cpu)); FAIL_IF(pipe(read_pipe.fds) == -1); FAIL_IF(pipe(write_pipe.fds) == -1); diff --git a/tools/testing/selftests/powerpc/pmu/ebb/ebb_vs_cpu_event_test.c b/tools/testing/selftests/powerpc/pmu/ebb/ebb_vs_cpu_event_test.c index 4d822cb3589c..d7064b54c64f 100644 --- a/tools/testing/selftests/powerpc/pmu/ebb/ebb_vs_cpu_event_test.c +++ b/tools/testing/selftests/powerpc/pmu/ebb/ebb_vs_cpu_event_test.c @@ -43,9 +43,8 @@ int ebb_vs_cpu_event(void) SKIP_IF(!ebb_is_supported()); - cpu = pick_online_cpu(); + cpu = bind_to_cpu(BIND_CPU_ANY); FAIL_IF(cpu < 0); - FAIL_IF(bind_to_cpu(cpu)); FAIL_IF(pipe(read_pipe.fds) == -1); FAIL_IF(pipe(write_pipe.fds) == -1); diff --git a/tools/testing/selftests/powerpc/pmu/ebb/multi_ebb_procs_test.c b/tools/testing/selftests/powerpc/pmu/ebb/multi_ebb_procs_test.c index 9b0f70d59702..4ac22b2e774f 100644 --- a/tools/testing/selftests/powerpc/pmu/ebb/multi_ebb_procs_test.c +++ b/tools/testing/selftests/powerpc/pmu/ebb/multi_ebb_procs_test.c @@ -75,13 +75,11 @@ static int cycles_child(void) int multi_ebb_procs(void) { pid_t pids[NR_CHILDREN]; - int cpu, rc, i; + int rc, i; SKIP_IF(!ebb_is_supported()); - cpu = pick_online_cpu(); - FAIL_IF(cpu < 0); - FAIL_IF(bind_to_cpu(cpu)); + FAIL_IF(bind_to_cpu(BIND_CPU_ANY) < 0); for (i = 0; i < NR_CHILDREN; i++) { pids[i] = fork(); diff --git a/tools/testing/selftests/powerpc/pmu/lib.c b/tools/testing/selftests/powerpc/pmu/lib.c index 144f90a78d69..321357987408 100644 --- a/tools/testing/selftests/powerpc/pmu/lib.c +++ b/tools/testing/selftests/powerpc/pmu/lib.c @@ -103,12 +103,10 @@ static int eat_cpu_child(union pipe read_pipe, union pipe write_pipe) pid_t eat_cpu(int (test_function)(void)) { union pipe read_pipe, write_pipe; - int cpu, rc; + int rc; pid_t pid; - cpu = pick_online_cpu(); - FAIL_IF(cpu < 0); - FAIL_IF(bind_to_cpu(cpu)); + FAIL_IF(bind_to_cpu(BIND_CPU_ANY) < 0); if (pipe(read_pipe.fds) == -1) return -1; diff --git a/tools/testing/selftests/powerpc/utils.c b/tools/testing/selftests/powerpc/utils.c index cdb996dba703..252fb4a95e90 100644 --- a/tools/testing/selftests/powerpc/utils.c +++ b/tools/testing/selftests/powerpc/utils.c @@ -455,13 +455,24 @@ done: int bind_to_cpu(int cpu) { cpu_set_t mask; + int err; + + if (cpu == BIND_CPU_ANY) { + cpu = pick_online_cpu(); + if (cpu < 0) + return cpu; + } printf("Binding to cpu %d\n", cpu); CPU_ZERO(&mask); CPU_SET(cpu, &mask); - return sched_setaffinity(0, sizeof(mask), &mask); + err = sched_setaffinity(0, sizeof(mask), &mask); + if (err) + return err; + + return cpu; } bool is_ppc64le(void) -- cgit v1.2.3 From fda8158870063b99b88a0904bbb95188973b4297 Mon Sep 17 00:00:00 2001 From: Benjamin Gray Date: Thu, 6 Apr 2023 14:33:17 +1000 Subject: selftests/powerpc/dscr: Add lockstep test cases to DSCR explicit tests Add new cases to the relevant tests that use explicitly synchronized threads to test the behaviour across context switches with less randomness. By locking the participants to the same CPU we guarantee a context switch occurs each time they make progress, which is a likely failure point if the kernel is not tracking the thread local DSCR correctly. The random case is left in to keep exercising potential edge cases. Signed-off-by: Benjamin Gray Signed-off-by: Michael Ellerman Link: https://msgid.link/20230406043320.125138-5-bgray@linux.ibm.com --- tools/testing/selftests/powerpc/dscr/Makefile | 1 + .../selftests/powerpc/dscr/dscr_default_test.c | 87 +++++++++++++++++++--- .../selftests/powerpc/dscr/dscr_explicit_test.c | 85 ++++++++++++++++++++- 3 files changed, 159 insertions(+), 14 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/dscr/Makefile b/tools/testing/selftests/powerpc/dscr/Makefile index 845db6273a1b..b29a8863a734 100644 --- a/tools/testing/selftests/powerpc/dscr/Makefile +++ b/tools/testing/selftests/powerpc/dscr/Makefile @@ -9,5 +9,6 @@ top_srcdir = ../../../../.. include ../../lib.mk $(OUTPUT)/dscr_default_test: LDLIBS += -lpthread +$(OUTPUT)/dscr_explicit_test: LDLIBS += -lpthread $(TEST_GEN_PROGS): ../harness.c ../utils.c diff --git a/tools/testing/selftests/powerpc/dscr/dscr_default_test.c b/tools/testing/selftests/powerpc/dscr/dscr_default_test.c index e76611e608af..18e533d46c9a 100644 --- a/tools/testing/selftests/powerpc/dscr/dscr_default_test.c +++ b/tools/testing/selftests/powerpc/dscr/dscr_default_test.c @@ -9,8 +9,66 @@ * Copyright 2012, Anton Blanchard, IBM Corporation. * Copyright 2015, Anshuman Khandual, IBM Corporation. */ + +#define _GNU_SOURCE + #include "dscr.h" +#include +#include +#include + +static void *dscr_default_lockstep_writer(void *arg) +{ + sem_t *reader_sem = (sem_t *)arg; + sem_t *writer_sem = (sem_t *)arg + 1; + unsigned long expected_dscr = 0; + + for (int i = 0; i < COUNT; i++) { + FAIL_IF_EXIT(sem_wait(writer_sem)); + + set_default_dscr(expected_dscr); + expected_dscr = (expected_dscr + 1) % DSCR_MAX; + + FAIL_IF_EXIT(sem_post(reader_sem)); + } + + return NULL; +} + +int dscr_default_lockstep_test(void) +{ + pthread_t writer; + sem_t rw_semaphores[2]; + sem_t *reader_sem = &rw_semaphores[0]; + sem_t *writer_sem = &rw_semaphores[1]; + unsigned long expected_dscr = 0; + + SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR)); + + FAIL_IF(sem_init(reader_sem, 0, 0)); + FAIL_IF(sem_init(writer_sem, 0, 1)); /* writer starts first */ + FAIL_IF(bind_to_cpu(BIND_CPU_ANY) < 0); + FAIL_IF(pthread_create(&writer, NULL, dscr_default_lockstep_writer, (void *)rw_semaphores)); + + for (int i = 0; i < COUNT ; i++) { + FAIL_IF(sem_wait(reader_sem)); + + FAIL_IF(get_dscr() != expected_dscr); + FAIL_IF(get_dscr_usr() != expected_dscr); + + expected_dscr = (expected_dscr + 1) % DSCR_MAX; + + FAIL_IF(sem_post(writer_sem)); + } + + FAIL_IF(pthread_join(writer, NULL)); + FAIL_IF(sem_destroy(reader_sem)); + FAIL_IF(sem_destroy(writer_sem)); + + return 0; +} + static unsigned long dscr; /* System DSCR default */ static unsigned long sequence; static unsigned long result[THREADS]; @@ -57,16 +115,13 @@ static void *do_test(void *in) pthread_exit(&result[thread]); } -int dscr_default(void) +int dscr_default_random_test(void) { pthread_t threads[THREADS]; unsigned long i, *status[THREADS]; - unsigned long orig_dscr_default; SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR)); - orig_dscr_default = get_default_dscr(); - /* Initial DSCR default */ dscr = 1; set_default_dscr(dscr); @@ -75,7 +130,7 @@ int dscr_default(void) for (i = 0; i < THREADS; i++) { if (pthread_create(&threads[i], NULL, do_test, (void *)i)) { perror("pthread_create() failed"); - goto fail; + return 1; } } @@ -104,23 +159,31 @@ int dscr_default(void) for (i = 0; i < THREADS; i++) { if (pthread_join(threads[i], (void **)&(status[i]))) { perror("pthread_join() failed"); - goto fail; + return 1; } if (*status[i]) { printf("%ldth thread failed to join with %ld status\n", i, *status[i]); - goto fail; + return 1; } } - set_default_dscr(orig_dscr_default); return 0; -fail: - set_default_dscr(orig_dscr_default); - return 1; } int main(int argc, char *argv[]) { - return test_harness(dscr_default, "dscr_default_test"); + unsigned long orig_dscr_default = 0; + int err = 0; + + if (have_hwcap2(PPC_FEATURE2_DSCR)) + orig_dscr_default = get_default_dscr(); + + err |= test_harness(dscr_default_lockstep_test, "dscr_default_lockstep_test"); + err |= test_harness(dscr_default_random_test, "dscr_default_random_test"); + + if (have_hwcap2(PPC_FEATURE2_DSCR)) + set_default_dscr(orig_dscr_default); + + return err; } diff --git a/tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c b/tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c index 5659d98cf340..3b98b9a88207 100644 --- a/tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c +++ b/tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c @@ -15,9 +15,78 @@ * Copyright 2012, Anton Blanchard, IBM Corporation. * Copyright 2015, Anshuman Khandual, IBM Corporation. */ + +#define _GNU_SOURCE + #include "dscr.h" +#include "utils.h" + +#include +#include +#include + +void *dscr_explicit_lockstep_thread(void *args) +{ + sem_t *prev = (sem_t *)args; + sem_t *next = (sem_t *)args + 1; + unsigned long expected_dscr = 0; + + set_dscr(expected_dscr); + srand(gettid()); + + for (int i = 0; i < COUNT; i++) { + FAIL_IF_EXIT(sem_wait(prev)); + + FAIL_IF_EXIT(expected_dscr != get_dscr()); + FAIL_IF_EXIT(expected_dscr != get_dscr_usr()); + + expected_dscr = (expected_dscr + 1) % DSCR_MAX; + set_dscr(expected_dscr); + + FAIL_IF_EXIT(sem_post(next)); + } + + return NULL; +} + +int dscr_explicit_lockstep_test(void) +{ + pthread_t thread; + sem_t semaphores[2]; + sem_t *prev = &semaphores[1]; /* reversed prev/next than for the other thread */ + sem_t *next = &semaphores[0]; + unsigned long expected_dscr = 0; + + SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR)); + + srand(gettid()); + set_dscr(expected_dscr); + + FAIL_IF(sem_init(prev, 0, 0)); + FAIL_IF(sem_init(next, 0, 1)); /* other thread starts first */ + FAIL_IF(bind_to_cpu(BIND_CPU_ANY) < 0); + FAIL_IF(pthread_create(&thread, NULL, dscr_explicit_lockstep_thread, (void *)semaphores)); + + for (int i = 0; i < COUNT; i++) { + FAIL_IF(sem_wait(prev)); + + FAIL_IF(expected_dscr != get_dscr()); + FAIL_IF(expected_dscr != get_dscr_usr()); + + expected_dscr = (expected_dscr - 1) % DSCR_MAX; + set_dscr(expected_dscr); + + FAIL_IF(sem_post(next)); + } -int dscr_explicit(void) + FAIL_IF(pthread_join(thread, NULL)); + FAIL_IF(sem_destroy(prev)); + FAIL_IF(sem_destroy(next)); + + return 0; +} + +int dscr_explicit_random_test(void) { unsigned long i, dscr = 0; @@ -66,5 +135,17 @@ int dscr_explicit(void) int main(int argc, char *argv[]) { - return test_harness(dscr_explicit, "dscr_explicit_test"); + unsigned long orig_dscr_default = 0; + int err = 0; + + if (have_hwcap2(PPC_FEATURE2_DSCR)) + orig_dscr_default = get_default_dscr(); + + err |= test_harness(dscr_explicit_lockstep_test, "dscr_explicit_lockstep_test"); + err |= test_harness(dscr_explicit_random_test, "dscr_explicit_random_test"); + + if (have_hwcap2(PPC_FEATURE2_DSCR)) + set_default_dscr(orig_dscr_default); + + return err; } -- cgit v1.2.3 From 3067b89ab62305c54ec15b00a2c4dbaf64809c59 Mon Sep 17 00:00:00 2001 From: Benjamin Gray Date: Thu, 6 Apr 2023 14:33:18 +1000 Subject: selftests/powerpc/dscr: Improve DSCR explicit random test case The tests currently have a single writer thread updating the system DSCR with a 1/1000 chance looped only 100 times. So only around one in 10 runs actually do anything. * Add multiple threads to the dscr_explicit_random_test case. * Use a barrier to make all the threads start work as simultaneously as possible. * Use a rwlock and make all threads have a reasonable chance to write to the DSCR on each iteration. PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP is used to prevent writers from starving while all the other threads keep reading. Logging the reads/writes shows a decent mix across the whole test. * Allow all threads a chance to write. * Make the chance of writing more likely. Signed-off-by: Benjamin Gray Signed-off-by: Michael Ellerman Link: https://msgid.link/20230406043320.125138-6-bgray@linux.ibm.com --- tools/testing/selftests/powerpc/dscr/dscr.h | 4 - .../selftests/powerpc/dscr/dscr_default_test.c | 140 +++++++++------------ .../selftests/powerpc/dscr/dscr_explicit_test.c | 84 ++++++++----- 3 files changed, 113 insertions(+), 115 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/dscr/dscr.h b/tools/testing/selftests/powerpc/dscr/dscr.h index 2c54998d4715..b281659071e8 100644 --- a/tools/testing/selftests/powerpc/dscr/dscr.h +++ b/tools/testing/selftests/powerpc/dscr/dscr.h @@ -86,8 +86,4 @@ void set_default_dscr(unsigned long val) } } -double uniform_deviate(int seed) -{ - return seed * (1.0 / (RAND_MAX + 1.0)); -} #endif /* _SELFTESTS_POWERPC_DSCR_DSCR_H */ diff --git a/tools/testing/selftests/powerpc/dscr/dscr_default_test.c b/tools/testing/selftests/powerpc/dscr/dscr_default_test.c index 18e533d46c9a..60ab02525b79 100644 --- a/tools/testing/selftests/powerpc/dscr/dscr_default_test.c +++ b/tools/testing/selftests/powerpc/dscr/dscr_default_test.c @@ -69,105 +69,85 @@ int dscr_default_lockstep_test(void) return 0; } -static unsigned long dscr; /* System DSCR default */ -static unsigned long sequence; -static unsigned long result[THREADS]; - -static void *do_test(void *in) +struct random_thread_args { + pthread_t thread_id; + unsigned long *expected_system_dscr; + pthread_rwlock_t *rw_lock; + pthread_barrier_t *barrier; +}; + +static void *dscr_default_random_thread(void *in) { - unsigned long thread = (unsigned long)in; - unsigned long i; - - for (i = 0; i < COUNT; i++) { - unsigned long d, cur_dscr, cur_dscr_usr; - unsigned long s1, s2; - - s1 = READ_ONCE(sequence); - if (s1 & 1) - continue; - rmb(); - - d = dscr; - cur_dscr = get_dscr(); - cur_dscr_usr = get_dscr_usr(); - - rmb(); - s2 = sequence; + struct random_thread_args *args = (struct random_thread_args *)in; + unsigned long *expected_dscr_p = args->expected_system_dscr; + pthread_rwlock_t *rw_lock = args->rw_lock; + int err; - if (s1 != s2) - continue; + srand(gettid()); - if (cur_dscr != d) { - fprintf(stderr, "thread %ld kernel DSCR should be %ld " - "but is %ld\n", thread, d, cur_dscr); - result[thread] = 1; - pthread_exit(&result[thread]); - } + err = pthread_barrier_wait(args->barrier); + FAIL_IF_EXIT(err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD); - if (cur_dscr_usr != d) { - fprintf(stderr, "thread %ld user DSCR should be %ld " - "but is %ld\n", thread, d, cur_dscr_usr); - result[thread] = 1; - pthread_exit(&result[thread]); + for (int i = 0; i < COUNT; i++) { + unsigned long expected_dscr; + unsigned long current_dscr; + unsigned long current_dscr_usr; + + FAIL_IF_EXIT(pthread_rwlock_rdlock(rw_lock)); + expected_dscr = *expected_dscr_p; + current_dscr = get_dscr(); + current_dscr_usr = get_dscr_usr(); + FAIL_IF_EXIT(pthread_rwlock_unlock(rw_lock)); + + FAIL_IF_EXIT(current_dscr != expected_dscr); + FAIL_IF_EXIT(current_dscr_usr != expected_dscr); + + if (rand() % 10 == 0) { + unsigned long next_dscr; + + FAIL_IF_EXIT(pthread_rwlock_wrlock(rw_lock)); + next_dscr = (*expected_dscr_p + 1) % DSCR_MAX; + set_default_dscr(next_dscr); + *expected_dscr_p = next_dscr; + FAIL_IF_EXIT(pthread_rwlock_unlock(rw_lock)); } } - result[thread] = 0; - pthread_exit(&result[thread]); + + pthread_exit((void *)0); } int dscr_default_random_test(void) { - pthread_t threads[THREADS]; - unsigned long i, *status[THREADS]; + struct random_thread_args threads[THREADS]; + unsigned long expected_system_dscr = 0; + pthread_rwlockattr_t rwlock_attr; + pthread_rwlock_t rw_lock; + pthread_barrier_t barrier; SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR)); - /* Initial DSCR default */ - dscr = 1; - set_default_dscr(dscr); + FAIL_IF(pthread_rwlockattr_setkind_np(&rwlock_attr, + PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP)); + FAIL_IF(pthread_rwlock_init(&rw_lock, &rwlock_attr)); + FAIL_IF(pthread_barrier_init(&barrier, NULL, THREADS)); - /* Spawn all testing threads */ - for (i = 0; i < THREADS; i++) { - if (pthread_create(&threads[i], NULL, do_test, (void *)i)) { - perror("pthread_create() failed"); - return 1; - } - } + set_default_dscr(expected_system_dscr); - srand(getpid()); + for (int i = 0; i < THREADS; i++) { + threads[i].expected_system_dscr = &expected_system_dscr; + threads[i].rw_lock = &rw_lock; + threads[i].barrier = &barrier; - /* Keep changing the DSCR default */ - for (i = 0; i < COUNT; i++) { - double ret = uniform_deviate(rand()); - - if (ret < 0.0001) { - sequence++; - wmb(); - - dscr++; - if (dscr > DSCR_MAX) - dscr = 0; - - set_default_dscr(dscr); - - wmb(); - sequence++; - } + FAIL_IF(pthread_create(&threads[i].thread_id, NULL, + dscr_default_random_thread, (void *)&threads[i])); } - /* Individual testing thread exit status */ - for (i = 0; i < THREADS; i++) { - if (pthread_join(threads[i], (void **)&(status[i]))) { - perror("pthread_join() failed"); - return 1; - } + for (int i = 0; i < THREADS; i++) + FAIL_IF(pthread_join(threads[i].thread_id, NULL)); + + FAIL_IF(pthread_barrier_destroy(&barrier)); + FAIL_IF(pthread_rwlock_destroy(&rw_lock)); - if (*status[i]) { - printf("%ldth thread failed to join with %ld status\n", - i, *status[i]); - return 1; - } - } return 0; } diff --git a/tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c b/tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c index 3b98b9a88207..e2268e9183a8 100644 --- a/tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c +++ b/tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c @@ -86,50 +86,72 @@ int dscr_explicit_lockstep_test(void) return 0; } -int dscr_explicit_random_test(void) +struct random_thread_args { + pthread_t thread_id; + bool do_yields; + pthread_barrier_t *barrier; +}; + +void *dscr_explicit_random_thread(void *in) { - unsigned long i, dscr = 0; + struct random_thread_args *args = (struct random_thread_args *)in; + unsigned long expected_dscr = 0; + int err; - SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR)); + srand(gettid()); - srand(getpid()); - set_dscr(dscr); + err = pthread_barrier_wait(args->barrier); + FAIL_IF_EXIT(err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD); - for (i = 0; i < COUNT; i++) { - unsigned long cur_dscr, cur_dscr_usr; - double ret = uniform_deviate(rand()); + for (int i = 0; i < COUNT; i++) { + expected_dscr = rand() % DSCR_MAX; + set_dscr(expected_dscr); - if (ret < 0.001) { - dscr++; - if (dscr > DSCR_MAX) - dscr = 0; + for (int j = rand() % 5; j > 0; --j) { + FAIL_IF_EXIT(get_dscr() != expected_dscr); + FAIL_IF_EXIT(get_dscr_usr() != expected_dscr); - set_dscr(dscr); + if (args->do_yields && rand() % 2) + sched_yield(); } - cur_dscr = get_dscr(); - if (cur_dscr != dscr) { - fprintf(stderr, "Kernel DSCR should be %ld but " - "is %ld\n", dscr, cur_dscr); - return 1; - } + expected_dscr = rand() % DSCR_MAX; + set_dscr_usr(expected_dscr); - ret = uniform_deviate(rand()); - if (ret < 0.001) { - dscr++; - if (dscr > DSCR_MAX) - dscr = 0; + for (int j = rand() % 5; j > 0; --j) { + FAIL_IF_EXIT(get_dscr() != expected_dscr); + FAIL_IF_EXIT(get_dscr_usr() != expected_dscr); - set_dscr_usr(dscr); + if (args->do_yields && rand() % 2) + sched_yield(); } + } - cur_dscr_usr = get_dscr_usr(); - if (cur_dscr_usr != dscr) { - fprintf(stderr, "User DSCR should be %ld but " - "is %ld\n", dscr, cur_dscr_usr); - return 1; - } + return NULL; +} + +int dscr_explicit_random_test(void) +{ + struct random_thread_args threads[THREADS]; + pthread_barrier_t barrier; + + SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR)); + + FAIL_IF(pthread_barrier_init(&barrier, NULL, THREADS)); + + for (int i = 0; i < THREADS; i++) { + threads[i].do_yields = i % 2 == 0; + threads[i].barrier = &barrier; + + FAIL_IF(pthread_create(&threads[i].thread_id, NULL, + dscr_explicit_random_thread, (void *)&threads[i])); } + + for (int i = 0; i < THREADS; i++) + FAIL_IF(pthread_join(threads[i].thread_id, NULL)); + + FAIL_IF(pthread_barrier_destroy(&barrier)); + return 0; } -- cgit v1.2.3 From c14a9d0a79d4fb83c4e9e8cadc5cb094f41d01d0 Mon Sep 17 00:00:00 2001 From: Benjamin Gray Date: Thu, 6 Apr 2023 14:33:19 +1000 Subject: selftests/powerpc/dscr: Speed up DSCR sysfs tests This test case is extremely slow, taking around a minute compared to most of the other DSCR tests taking a second at most. Perf shows most time is spent by the kernel switching to each CPU it reads in /sys/devices/system/cpu. This switching is an unavoidable consequnce of reading all the .../cpuN/dscr values. Remove the outer iteration loop from this test case, reducing the reads from 1600 to 16. This still updates the DSCR 16 times and verifies on every CPU each time, so I do not expect the lower coverage to be meaningful. The speedup is significant: back down to ~1 second like the other tests. Signed-off-by: Benjamin Gray Signed-off-by: Michael Ellerman Link: https://msgid.link/20230406043320.125138-7-bgray@linux.ibm.com --- tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c b/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c index 4f1fef6198fc..e7cd0d6b1fad 100644 --- a/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c +++ b/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c @@ -67,17 +67,14 @@ static int check_all_cpu_dscr_defaults(unsigned long val) int dscr_sysfs(void) { unsigned long orig_dscr_default; - int i, j; SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR)); orig_dscr_default = get_default_dscr(); - for (i = 0; i < COUNT; i++) { - for (j = 0; j < DSCR_MAX; j++) { - set_default_dscr(j); - if (check_all_cpu_dscr_defaults(j)) - goto fail; - } + for (int i = 0; i < DSCR_MAX; i++) { + set_default_dscr(i); + if (check_all_cpu_dscr_defaults(i)) + goto fail; } set_default_dscr(orig_dscr_default); return 0; -- cgit v1.2.3 From ae7312c09014fceb782a92cfb934e973f08b338f Mon Sep 17 00:00:00 2001 From: Benjamin Gray Date: Thu, 6 Apr 2023 14:33:20 +1000 Subject: selftests/powerpc/dscr: Restore timeout to DSCR selftests Reducing the time taken by dscr_sysfs_test.c allows restoring the default timeout, which was removed in commit 850507f30c38 ("selftests/powerpc: Turn off timeout setting for benchmarks, dscr, signal, tm") because that test took too long. Signed-off-by: Benjamin Gray Signed-off-by: Michael Ellerman Link: https://msgid.link/20230406043320.125138-8-bgray@linux.ibm.com --- tools/testing/selftests/powerpc/dscr/Makefile | 2 -- tools/testing/selftests/powerpc/dscr/settings | 1 - 2 files changed, 3 deletions(-) delete mode 100644 tools/testing/selftests/powerpc/dscr/settings (limited to 'tools') diff --git a/tools/testing/selftests/powerpc/dscr/Makefile b/tools/testing/selftests/powerpc/dscr/Makefile index b29a8863a734..9289d5febe1e 100644 --- a/tools/testing/selftests/powerpc/dscr/Makefile +++ b/tools/testing/selftests/powerpc/dscr/Makefile @@ -3,8 +3,6 @@ TEST_GEN_PROGS := dscr_default_test dscr_explicit_test dscr_user_test \ dscr_inherit_test dscr_inherit_exec_test dscr_sysfs_test \ dscr_sysfs_thread_test -TEST_FILES := settings - top_srcdir = ../../../../.. include ../../lib.mk diff --git a/tools/testing/selftests/powerpc/dscr/settings b/tools/testing/selftests/powerpc/dscr/settings deleted file mode 100644 index e7b9417537fb..000000000000 --- a/tools/testing/selftests/powerpc/dscr/settings +++ /dev/null @@ -1 +0,0 @@ -timeout=0 -- cgit v1.2.3