1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright (c) 2024 Meta Platforms, Inc. and affiliates. 4 * Copyright (c) 2024 David Vernet <dvernet@meta.com> 5 */ 6 #include <bpf/bpf.h> 7 #include <pthread.h> 8 #include <scx/common.h> 9 #include <sys/wait.h> 10 #include <unistd.h> 11 #include "maximal.bpf.skel.h" 12 #include "scx_test.h" 13 14 static struct maximal *skel; 15 static pthread_t threads[2]; 16 17 bool force_exit = false; 18 19 static enum scx_test_status setup(void **ctx) 20 { 21 skel = maximal__open_and_load(); 22 if (!skel) { 23 SCX_ERR("Failed to open and load skel"); 24 return SCX_TEST_FAIL; 25 } 26 27 return SCX_TEST_PASS; 28 } 29 30 static void *do_reload_loop(void *arg) 31 { 32 u32 i; 33 34 for (i = 0; i < 1024 && !force_exit; i++) { 35 struct bpf_link *link; 36 37 link = bpf_map__attach_struct_ops(skel->maps.maximal_ops); 38 if (link) 39 bpf_link__destroy(link); 40 } 41 42 return NULL; 43 } 44 45 static enum scx_test_status run(void *ctx) 46 { 47 int err; 48 void *ret; 49 50 err = pthread_create(&threads[0], NULL, do_reload_loop, NULL); 51 SCX_FAIL_IF(err, "Failed to create thread 0"); 52 53 err = pthread_create(&threads[1], NULL, do_reload_loop, NULL); 54 SCX_FAIL_IF(err, "Failed to create thread 1"); 55 56 SCX_FAIL_IF(pthread_join(threads[0], &ret), "thread 0 failed"); 57 SCX_FAIL_IF(pthread_join(threads[1], &ret), "thread 1 failed"); 58 59 return SCX_TEST_PASS; 60 } 61 62 static void cleanup(void *ctx) 63 { 64 force_exit = true; 65 maximal__destroy(skel); 66 } 67 68 struct scx_test reload_loop = { 69 .name = "reload_loop", 70 .description = "Stress test loading and unloading schedulers repeatedly in a tight loop", 71 .setup = setup, 72 .run = run, 73 .cleanup = cleanup, 74 }; 75 REGISTER_SCX_TEST(&reload_loop) 76