xref: /linux/tools/testing/selftests/sched_ext/dequeue_iter.c (revision ff9b465ddb95d7842282998348df88ff55f62c4a)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2026 fangqiurong <fangqiurong@kylinos.cn>
4  */
5 #include <bpf/bpf.h>
6 #include <scx/common.h>
7 #include <time.h>
8 #include <unistd.h>
9 #include "dequeue_iter.bpf.skel.h"
10 #include "scx_test.h"
11 
12 #define DQ_TARGET	10
13 #define DQ_DEADLINE_MS	3000
14 
15 static unsigned long long now_ms(void)
16 {
17 	struct timespec ts;
18 
19 	clock_gettime(CLOCK_MONOTONIC, &ts);
20 
21 	return ts.tv_sec * 1000ULL + ts.tv_nsec / 1000000;
22 }
23 
24 static enum scx_test_status setup(void **ctx)
25 {
26 	struct dequeue_iter *skel;
27 
28 	skel = dequeue_iter__open();
29 	SCX_FAIL_IF(!skel, "Failed to open");
30 	SCX_ENUM_INIT(skel);
31 	SCX_FAIL_IF(dequeue_iter__load(skel), "Failed to load skel");
32 
33 	*ctx = skel;
34 
35 	return SCX_TEST_PASS;
36 }
37 
38 static enum scx_test_status run(void *ctx)
39 {
40 	struct dequeue_iter *skel = ctx;
41 	struct bpf_link *link;
42 	unsigned long long end;
43 
44 	link = bpf_map__attach_struct_ops(skel->maps.dequeue_iter_ops);
45 	SCX_FAIL_IF(!link, "Failed to attach scheduler");
46 
47 	end = now_ms() + DQ_DEADLINE_MS;
48 	while (skel->bss->dq_count < DQ_TARGET && !UEI_EXITED(skel, uei) &&
49 	       now_ms() < end)
50 		usleep(100);
51 
52 	bpf_link__destroy(link);
53 
54 	SCX_EQ(skel->data->uei.kind, EXIT_KIND(SCX_EXIT_UNREG));
55 
56 	if (skel->bss->dq_count < DQ_TARGET) {
57 		SCX_ERR("ops.dequeue() fired only %llu times",
58 			(unsigned long long)skel->bss->dq_count);
59 		return SCX_TEST_FAIL;
60 	}
61 
62 	return SCX_TEST_PASS;
63 }
64 
65 static void cleanup(void *ctx)
66 {
67 	struct dequeue_iter *skel = ctx;
68 
69 	dequeue_iter__destroy(skel);
70 }
71 
72 struct scx_test dequeue_iter = {
73 	.name = "dequeue_iter",
74 	.description = "Verify ops.dequeue() can iterate its source user DSQ",
75 	.setup = setup,
76 	.run = run,
77 	.cleanup = cleanup,
78 };
79 REGISTER_SCX_TEST(&dequeue_iter)
80