Re: [PATCH V5 12/13] selftests, powerpc: Add thread based stress test for DSCR sysfs interfaces
On 05/21/2015 12:13 PM, Anshuman Khandual wrote: This patch adds a test to update the system wide DSCR value repeatedly and then verifies that any thread on any given CPU on the system must be able to see the same DSCR value whether its is being read through the problem state based SPR or the privilege state based SPR. This test can fail on a system if some kind of cpu hotplug activity is happening when this test is being run at the same time. Then call to sched_setaffinity() might fail as the test does not check for the CPU availability/online every time before changing the affinity of the thread. Here is one changed version of this test which achieves similar test objective. Michael, Please let me know if the patch here would be okay or I need to re-spin the patch series for this change. Thank you. -- [PATCH] selftests, powerpc: Add thread based stress test for DSCR sysfs interfaces This patch adds a test to update the system wide DSCR value repeatedly and then verifies that any thread on any given CPU on the system must be able to see the same DSCR value whether its is being read through the problem state based SPR or the privilege state based SPR. Acked-by: Shuah Khan shua...@osg.samsung.com Signed-off-by: Anshuman Khandual khand...@linux.vnet.ibm.com --- tools/testing/selftests/powerpc/dscr/Makefile | 2 +- .../powerpc/dscr/dscr_sysfs_thread_test.c | 81 ++ 2 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_sysfs_thread_test.c diff --git a/tools/testing/selftests/powerpc/dscr/Makefile b/tools/testing/selftests/powerpc/dscr/Makefile index fada526..834ef88 100644 --- a/tools/testing/selftests/powerpc/dscr/Makefile +++ b/tools/testing/selftests/powerpc/dscr/Makefile @@ -1,6 +1,6 @@ PROGS := dscr_default_test dscr_explicit_test dscr_user_test \ dscr_inherit_test dscr_inherit_exec_test \ -dscr_sysfs_test +dscr_sysfs_test dscr_sysfs_thread_test CFLAGS := $(CFLAGS) -lpthread diff --git a/tools/testing/selftests/powerpc/dscr/dscr_sysfs_thread_test.c b/tools/testing/selftests/powerpc/dscr/dscr_sysfs_thread_test.c new file mode 100644 index 000..9671d52 --- /dev/null +++ b/tools/testing/selftests/powerpc/dscr/dscr_sysfs_thread_test.c @@ -0,0 +1,81 @@ +/* + * POWER Data Stream Control Register (DSCR) sysfs thread test + * + * This test updates the system wide DSCR default value through + * sysfs interface which should then update all the CPU specific + * DSCR default values which must also be then visible to threads + * executing on individual CPUs on the system. + * + * Copyright (C) 2015 Anshuman Khandual khand...@linux.vnet.ibm.com, IBM + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#define _GNU_SOURCE +#include dscr.h + +static int test_thread_dscr(unsigned long val) +{ + unsigned long cur_dscr, cur_dscr_usr; + + cur_dscr = get_dscr(); + cur_dscr_usr = get_dscr_usr(); + + if (val != cur_dscr) { + printf([cpu %d] Kernel DSCR should be %ld but is %ld\n, + sched_getcpu(), val, cur_dscr); + return 1; + } + + if (val != cur_dscr_usr) { + printf([cpu %d] User DSCR should be %ld but is %ld\n, + sched_getcpu(), val, cur_dscr_usr); + return 1; + } + return 0; +} + +static int check_cpu_dscr_thread(unsigned long val) +{ + cpu_set_t mask; + int cpu; + + for (cpu = 0; cpu CPU_SETSIZE; cpu++) { + CPU_ZERO(mask); + CPU_SET(cpu, mask); + if (sched_setaffinity(0, sizeof(mask), mask)) + continue; + + if (test_thread_dscr(val)) + return 1; + } + return 0; + +} + +int dscr_sysfs_thread(void) +{ + unsigned long orig_dscr_default; + int i, j; + + 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_cpu_dscr_thread(j)) + goto fail; + } + } + 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_sysfs_thread, dscr_sysfs_thread_test); +} -- 2.1.0 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH V5 12/13] selftests, powerpc: Add thread based stress test for DSCR sysfs interfaces
This patch adds a test to update the system wide DSCR value repeatedly and then verifies that any thread on any given CPU on the system must be able to see the same DSCR value whether its is being read through the problem state based SPR or the privilege state based SPR. Acked-by: Shuah Khan shua...@osg.samsung.com Signed-off-by: Anshuman Khandual khand...@linux.vnet.ibm.com --- tools/testing/selftests/powerpc/dscr/Makefile | 2 +- .../powerpc/dscr/dscr_sysfs_thread_test.c | 123 + 2 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_sysfs_thread_test.c diff --git a/tools/testing/selftests/powerpc/dscr/Makefile b/tools/testing/selftests/powerpc/dscr/Makefile index fada526..834ef88 100644 --- a/tools/testing/selftests/powerpc/dscr/Makefile +++ b/tools/testing/selftests/powerpc/dscr/Makefile @@ -1,6 +1,6 @@ PROGS := dscr_default_test dscr_explicit_test dscr_user_test \ dscr_inherit_test dscr_inherit_exec_test \ -dscr_sysfs_test +dscr_sysfs_test dscr_sysfs_thread_test CFLAGS := $(CFLAGS) -lpthread diff --git a/tools/testing/selftests/powerpc/dscr/dscr_sysfs_thread_test.c b/tools/testing/selftests/powerpc/dscr/dscr_sysfs_thread_test.c new file mode 100644 index 000..bf4a8a6 --- /dev/null +++ b/tools/testing/selftests/powerpc/dscr/dscr_sysfs_thread_test.c @@ -0,0 +1,123 @@ +/* + * POWER Data Stream Control Register (DSCR) sysfs thread test + * + * This test updates the system wide DSCR default value through + * sysfs interface which should then update all the CPU specific + * DSCR default values which must also be then visible to threads + * executing on individual CPUs on the system. + * + * Copyright (C) 2015 Anshuman Khandual khand...@linux.vnet.ibm.com, IBM + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#define _GNU_SOURCE +#include dscr.h + +static pthread_mutex_t lock; /* Pthread lock */ +static cpu_set_t cpuset; /* Thread cpu set */ +static int target; /* Thread target cpu */ +static unsigned long *result; /* Thread exit status array */ + +#define NR_ONLN sysconf(_SC_NPROCESSORS_ONLN) + +static void *test_thread_dscr(void *in) +{ + unsigned long cur_dscr, cur_dscr_usr; + unsigned long val = (unsigned long)in; + + pthread_mutex_lock(lock); + target++; + if (target == NR_ONLN) + target = 0; + CPU_ZERO(cpuset); + CPU_SET(target, cpuset); + + if (sched_setaffinity(0, sizeof(cpuset), cpuset)) { + perror(sched_setaffinity() failed); + pthread_mutex_unlock(lock); + result[target] = 1; + pthread_exit(result[target]); + } + pthread_mutex_unlock(lock); + + cur_dscr = get_dscr(); + cur_dscr_usr = get_dscr_usr(); + + if (val != cur_dscr) { + printf([cpu %d] Kernel DSCR should be %ld but is %ld\n, + sched_getcpu(), val, cur_dscr); + result[target] = 1; + pthread_exit(result[target]); + } + + if (val != cur_dscr_usr) { + printf([cpu %d] User DSCR should be %ld but is %ld\n, + sched_getcpu(), val, cur_dscr_usr); + result[target] = 1; + pthread_exit(result[target]); + } + result[target] = 0; + pthread_exit(result[target]); +} + +static int check_cpu_dscr_thread(unsigned long val) +{ + pthread_t threads[NR_ONLN]; + unsigned long *status[NR_ONLN]; + unsigned long i; + + for (i = 0; i NR_ONLN; i++) { + if (pthread_create(threads[i], NULL, + test_thread_dscr, (void *)val)) { + perror(pthread_create() failed); + return 1; + } + } + + for (i = 0; i NR_ONLN; i++) { + if (pthread_join(threads[i], (void **)(status[i]))) { + perror(pthread_join() failed); + return 1; + } + + if (*status[i]) { + printf( %ldth thread join failed with %ld\n, + i, *status[i]); + return 1; + } + } + return 0; +} + +int dscr_sysfs_thread(void) +{ + unsigned long orig_dscr_default; + int i, j; + + result = malloc(sizeof(unsigned long) * NR_ONLN); + pthread_mutex_init(lock, NULL); + target = 0; + orig_dscr_default = get_default_dscr(); + for (i = 0; i COUNT; i++) { + for (j = 0; j DSCR_MAX; j++) { +