xref: /linux/tools/testing/selftests/sched_ext/select_cpu_dfl.c (revision 3dc7c001169d112b3e514cacff6c93091c57af9a)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (c) 2023 Meta Platforms, Inc. and affiliates.
4  * Copyright (c) 2023 David Vernet <dvernet@meta.com>
5  * Copyright (c) 2023 Tejun Heo <tj@kernel.org>
6  */
7 #include <bpf/bpf.h>
8 #include <scx/common.h>
9 #include <stdlib.h>
10 #include <sys/wait.h>
11 #include <unistd.h>
12 #include "select_cpu_dfl.bpf.skel.h"
13 #include "scx_test.h"
14 
15 #define NUM_CHILDREN 1028
16 
17 struct select_cpu_dfl_ctx {
18 	struct select_cpu_dfl	*skel;
19 	struct bpf_link		*link;
20 };
21 
22 static enum scx_test_status setup(void **ctx)
23 {
24 	struct select_cpu_dfl_ctx *tctx;
25 
26 	tctx = malloc(sizeof(*tctx));
27 	SCX_FAIL_IF(!tctx, "Failed to allocate test context");
28 	tctx->link = NULL;
29 
30 	tctx->skel = select_cpu_dfl__open();
31 	if (!tctx->skel) {
32 		free(tctx);
33 		SCX_FAIL("Failed to open");
34 	}
35 	SCX_ENUM_INIT(tctx->skel);
36 	if (select_cpu_dfl__load(tctx->skel)) {
37 		select_cpu_dfl__destroy(tctx->skel);
38 		free(tctx);
39 		SCX_FAIL("Failed to load skel");
40 	}
41 
42 	*ctx = tctx;
43 
44 	return SCX_TEST_PASS;
45 }
46 
47 static enum scx_test_status run(void *ctx)
48 {
49 	struct select_cpu_dfl_ctx *tctx = ctx;
50 	pid_t pids[NUM_CHILDREN];
51 	int i, status, nforked = 0;
52 
53 	tctx->link = bpf_map__attach_struct_ops(tctx->skel->maps.select_cpu_dfl_ops);
54 	SCX_FAIL_IF(!tctx->link, "Failed to attach scheduler");
55 
56 	for (i = 0; i < NUM_CHILDREN; i++) {
57 		pids[i] = fork();
58 		if (pids[i] == 0) {
59 			sleep(1);
60 			exit(0);
61 		}
62 		if (pids[i] > 0)
63 			nforked++;
64 	}
65 
66 	for (i = 0; i < NUM_CHILDREN; i++) {
67 		if (pids[i] <= 0)
68 			continue;
69 		SCX_EQ(waitpid(pids[i], &status, 0), pids[i]);
70 		SCX_EQ(status, 0);
71 	}
72 
73 	SCX_GT(nforked, 0);
74 	SCX_ASSERT(!tctx->skel->bss->saw_local);
75 
76 	return SCX_TEST_PASS;
77 }
78 
79 static void cleanup(void *ctx)
80 {
81 	struct select_cpu_dfl_ctx *tctx = ctx;
82 
83 	if (tctx->link)
84 		bpf_link__destroy(tctx->link);
85 	select_cpu_dfl__destroy(tctx->skel);
86 	free(tctx);
87 }
88 
89 struct scx_test select_cpu_dfl = {
90 	.name = "select_cpu_dfl",
91 	.description = "Verify the default ops.select_cpu() dispatches tasks "
92 		       "when idles cores are found, and skips ops.enqueue()",
93 	.setup = setup,
94 	.run = run,
95 	.cleanup = cleanup,
96 };
97 REGISTER_SCX_TEST(&select_cpu_dfl)
98