1 /* SPDX-License-Identifier: GPL-2.0 */
3 * Copyright (c) 2024 Meta Platforms, Inc. and affiliates.
4 * Copyright (c) 2024 David Vernet <dvernet@meta.com>
8 #include <scx/common.h>
13 #include "hotplug_test.h"
14 #include "hotplug.bpf.skel.h"
18 const char *online_path
= "/sys/devices/system/cpu/cpu1/online";
20 static bool is_cpu_online(void)
22 return file_read_long(online_path
) > 0;
25 static void toggle_online_status(bool online
)
27 long val
= online
? 1 : 0;
30 ret
= file_write_long(online_path
, val
);
32 fprintf(stderr
, "Failed to bring CPU %s (%s)",
33 online
? "online" : "offline", strerror(errno
));
36 static enum scx_test_status
setup(void **ctx
)
44 static enum scx_test_status
test_hotplug(bool onlining
, bool cbs_defined
)
47 struct bpf_link
*link
;
50 SCX_ASSERT(is_cpu_online());
52 skel
= hotplug__open_and_load();
55 /* Testing the offline -> online path, so go offline before starting */
57 toggle_online_status(0);
60 kind
= SCX_KIND_VAL(SCX_EXIT_UNREG_BPF
);
61 code
= SCX_ECODE_VAL(SCX_ECODE_ACT_RESTART
) | HOTPLUG_EXIT_RSN
;
63 code
|= HOTPLUG_ONLINING
;
65 kind
= SCX_KIND_VAL(SCX_EXIT_UNREG_KERN
);
66 code
= SCX_ECODE_VAL(SCX_ECODE_ACT_RESTART
) |
67 SCX_ECODE_VAL(SCX_ECODE_RSN_HOTPLUG
);
71 link
= bpf_map__attach_struct_ops(skel
->maps
.hotplug_cb_ops
);
73 link
= bpf_map__attach_struct_ops(skel
->maps
.hotplug_nocb_ops
);
76 SCX_ERR("Failed to attach scheduler");
77 hotplug__destroy(skel
);
81 toggle_online_status(onlining
? 1 : 0);
83 while (!UEI_EXITED(skel
, uei
))
86 SCX_EQ(skel
->data
->uei
.kind
, kind
);
87 SCX_EQ(UEI_REPORT(skel
, uei
), code
);
90 toggle_online_status(1);
92 bpf_link__destroy(link
);
93 hotplug__destroy(skel
);
98 static enum scx_test_status
test_hotplug_attach(void)
100 struct hotplug
*skel
;
101 struct bpf_link
*link
;
102 enum scx_test_status status
= SCX_TEST_PASS
;
105 SCX_ASSERT(is_cpu_online());
106 SCX_ASSERT(scx_hotplug_seq() > 0);
108 skel
= SCX_OPS_OPEN(hotplug_nocb_ops
, hotplug
);
111 SCX_OPS_LOAD(skel
, hotplug_nocb_ops
, hotplug
, uei
);
114 * Take the CPU offline to increment the global hotplug seq, which
115 * should cause attach to fail due to us setting the hotplug seq above
117 toggle_online_status(0);
118 link
= bpf_map__attach_struct_ops(skel
->maps
.hotplug_nocb_ops
);
120 toggle_online_status(1);
123 while (!UEI_EXITED(skel
, uei
))
126 kind
= SCX_KIND_VAL(SCX_EXIT_UNREG_KERN
);
127 code
= SCX_ECODE_VAL(SCX_ECODE_ACT_RESTART
) |
128 SCX_ECODE_VAL(SCX_ECODE_RSN_HOTPLUG
);
129 SCX_EQ(skel
->data
->uei
.kind
, kind
);
130 SCX_EQ(UEI_REPORT(skel
, uei
), code
);
132 bpf_link__destroy(link
);
133 hotplug__destroy(skel
);
138 static enum scx_test_status
run(void *ctx
)
141 #define HP_TEST(__onlining, __cbs_defined) ({ \
142 if (test_hotplug(__onlining, __cbs_defined) != SCX_TEST_PASS) \
143 return SCX_TEST_FAIL; \
147 HP_TEST(false, true);
148 HP_TEST(true, false);
149 HP_TEST(false, false);
153 return test_hotplug_attach();
156 static void cleanup(void *ctx
)
158 toggle_online_status(1);
161 struct scx_test hotplug_test
= {
163 .description
= "Verify hotplug behavior",
168 REGISTER_SCX_TEST(&hotplug_test
)