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