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
setup(void ** ctx)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
do_reload_loop(void * arg)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
run(void * ctx)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
cleanup(void * ctx)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