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

selftests, sched/membarrier: Add multi-threaded test

membarrier commands cover very different code paths if they are in
a single-threaded vs multi-threaded process. Therefore, exercise both
scenarios in the kernel selftests to increase coverage of this selftest.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Chris Metcalf <cmetcalf@ezchip.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Eric W. Biederman <ebiederm@xmission.com>
Cc: Kirill Tkhai <tkhai@yandex.ru>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Paul E. McKenney <paulmck@linux.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Russell King - ARM Linux admin <linux@armlinux.org.uk>
Cc: Shuah Khan <shuahkh@osg.samsung.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: https://lkml.kernel.org/r/20190919173705.2181-6-mathieu.desnoyers@efficios.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Mathieu Desnoyers and committed by
Ingo Molnar
19a4ff53 227a4aad

+124 -21
+2 -1
tools/testing/selftests/membarrier/.gitignore
··· 1 - membarrier_test 1 + membarrier_test_multi_thread 2 + membarrier_test_single_thread
+3 -2
tools/testing/selftests/membarrier/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 CFLAGS += -g -I../../../../usr/include/ 3 + LDLIBS += -lpthread 3 4 4 - TEST_GEN_PROGS := membarrier_test 5 + TEST_GEN_PROGS := membarrier_test_single_thread \ 6 + membarrier_test_multi_thread 5 7 6 8 include ../lib.mk 7 -
+22 -18
tools/testing/selftests/membarrier/membarrier_test.c tools/testing/selftests/membarrier/membarrier_test_impl.h
··· 1 - // SPDX-License-Identifier: GPL-2.0 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 2 #define _GNU_SOURCE 3 3 #include <linux/membarrier.h> 4 4 #include <syscall.h> 5 5 #include <stdio.h> 6 6 #include <errno.h> 7 7 #include <string.h> 8 + #include <pthread.h> 8 9 9 10 #include "../kselftest.h" 10 11 ··· 224 223 return 0; 225 224 } 226 225 227 - static int test_membarrier(void) 226 + static int test_membarrier_fail(void) 228 227 { 229 228 int status; 230 229 ··· 234 233 status = test_membarrier_flags_fail(); 235 234 if (status) 236 235 return status; 237 - status = test_membarrier_global_success(); 236 + status = test_membarrier_private_expedited_fail(); 238 237 if (status) 239 238 return status; 240 - status = test_membarrier_private_expedited_fail(); 239 + status = sys_membarrier(MEMBARRIER_CMD_QUERY, 0); 240 + if (status < 0) { 241 + ksft_test_result_fail("sys_membarrier() failed\n"); 242 + return status; 243 + } 244 + if (status & MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE) { 245 + status = test_membarrier_private_expedited_sync_core_fail(); 246 + if (status) 247 + return status; 248 + } 249 + return 0; 250 + } 251 + 252 + static int test_membarrier_success(void) 253 + { 254 + int status; 255 + 256 + status = test_membarrier_global_success(); 241 257 if (status) 242 258 return status; 243 259 status = test_membarrier_register_private_expedited_success(); ··· 269 251 return status; 270 252 } 271 253 if (status & MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE) { 272 - status = test_membarrier_private_expedited_sync_core_fail(); 273 - if (status) 274 - return status; 275 254 status = test_membarrier_register_private_expedited_sync_core_success(); 276 255 if (status) 277 256 return status; ··· 314 299 315 300 ksft_test_result_pass("sys_membarrier available\n"); 316 301 return 0; 317 - } 318 - 319 - int main(int argc, char **argv) 320 - { 321 - ksft_print_header(); 322 - ksft_set_plan(13); 323 - 324 - test_membarrier_query(); 325 - test_membarrier(); 326 - 327 - return ksft_exit_pass(); 328 302 }
+73
tools/testing/selftests/membarrier/membarrier_test_multi_thread.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #define _GNU_SOURCE 3 + #include <linux/membarrier.h> 4 + #include <syscall.h> 5 + #include <stdio.h> 6 + #include <errno.h> 7 + #include <string.h> 8 + #include <pthread.h> 9 + 10 + #include "membarrier_test_impl.h" 11 + 12 + static int thread_ready, thread_quit; 13 + static pthread_mutex_t test_membarrier_thread_mutex = 14 + PTHREAD_MUTEX_INITIALIZER; 15 + static pthread_cond_t test_membarrier_thread_cond = 16 + PTHREAD_COND_INITIALIZER; 17 + 18 + void *test_membarrier_thread(void *arg) 19 + { 20 + pthread_mutex_lock(&test_membarrier_thread_mutex); 21 + thread_ready = 1; 22 + pthread_cond_broadcast(&test_membarrier_thread_cond); 23 + pthread_mutex_unlock(&test_membarrier_thread_mutex); 24 + 25 + pthread_mutex_lock(&test_membarrier_thread_mutex); 26 + while (!thread_quit) 27 + pthread_cond_wait(&test_membarrier_thread_cond, 28 + &test_membarrier_thread_mutex); 29 + pthread_mutex_unlock(&test_membarrier_thread_mutex); 30 + 31 + return NULL; 32 + } 33 + 34 + static int test_mt_membarrier(void) 35 + { 36 + int i; 37 + pthread_t test_thread; 38 + 39 + pthread_create(&test_thread, NULL, 40 + test_membarrier_thread, NULL); 41 + 42 + pthread_mutex_lock(&test_membarrier_thread_mutex); 43 + while (!thread_ready) 44 + pthread_cond_wait(&test_membarrier_thread_cond, 45 + &test_membarrier_thread_mutex); 46 + pthread_mutex_unlock(&test_membarrier_thread_mutex); 47 + 48 + test_membarrier_fail(); 49 + 50 + test_membarrier_success(); 51 + 52 + pthread_mutex_lock(&test_membarrier_thread_mutex); 53 + thread_quit = 1; 54 + pthread_cond_broadcast(&test_membarrier_thread_cond); 55 + pthread_mutex_unlock(&test_membarrier_thread_mutex); 56 + 57 + pthread_join(test_thread, NULL); 58 + 59 + return 0; 60 + } 61 + 62 + int main(int argc, char **argv) 63 + { 64 + ksft_print_header(); 65 + ksft_set_plan(13); 66 + 67 + test_membarrier_query(); 68 + 69 + /* Multi-threaded */ 70 + test_mt_membarrier(); 71 + 72 + return ksft_exit_pass(); 73 + }
+24
tools/testing/selftests/membarrier/membarrier_test_single_thread.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #define _GNU_SOURCE 3 + #include <linux/membarrier.h> 4 + #include <syscall.h> 5 + #include <stdio.h> 6 + #include <errno.h> 7 + #include <string.h> 8 + #include <pthread.h> 9 + 10 + #include "membarrier_test_impl.h" 11 + 12 + int main(int argc, char **argv) 13 + { 14 + ksft_print_header(); 15 + ksft_set_plan(13); 16 + 17 + test_membarrier_query(); 18 + 19 + test_membarrier_fail(); 20 + 21 + test_membarrier_success(); 22 + 23 + return ksft_exit_pass(); 24 + }