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(); 22 SCX_FAIL_IF(!skel, "Failed to open"); 23 SCX_ENUM_INIT(skel); 24 SCX_FAIL_IF(maximal__load(skel), "Failed to load skel"); 25 26 return SCX_TEST_PASS; 27 } 28 29 static void *do_reload_loop(void *arg) 30 { 31 u32 i; 32 33 for (i = 0; i < 1024 && !force_exit; i++) { 34 struct bpf_link *link; 35 36 link = bpf_map__attach_struct_ops(skel->maps.maximal_ops); 37 if (link) 38 bpf_link__destroy(link); 39 } 40 41 return NULL; 42 } 43 44 static enum scx_test_status run(void *ctx) 45 { 46 int err; 47 void *ret; 48 49 err = pthread_create(&threads[0], NULL, do_reload_loop, NULL); 50 SCX_FAIL_IF(err, "Failed to create thread 0"); 51 52 err = pthread_create(&threads[1], NULL, do_reload_loop, NULL); 53 SCX_FAIL_IF(err, "Failed to create thread 1"); 54 55 SCX_FAIL_IF(pthread_join(threads[0], &ret), "thread 0 failed"); 56 SCX_FAIL_IF(pthread_join(threads[1], &ret), "thread 1 failed"); 57 58 return SCX_TEST_PASS; 59 } 60 61 static void cleanup(void *ctx) 62 { 63 force_exit = true; 64 maximal__destroy(skel); 65 } 66 67 struct scx_test reload_loop = { 68 .name = "reload_loop", 69 .description = "Stress test loading and unloading schedulers repeatedly in a tight loop", 70 .setup = setup, 71 .run = run, 72 .cleanup = cleanup, 73 }; 74 REGISTER_SCX_TEST(&reload_loop) 75