Skip to content

Commit 36adf6f

Browse files
arighihtejun
authored andcommitted
selftests/sched_ext: Update test enq_select_cpu_fails
With commit 08699d20467b6 ("sched_ext: idle: Consolidate default idle CPU selection kfuncs") allowing scx_bpf_select_cpu_dfl() to be invoked from multiple contexts, update the test to validate that the kfunc behaves correctly when used from ops.enqueue() and via BPF test_run. Additionally, rename the test to enq_select_cpu, dropping "fails" from the name, as the logic has now been inverted. Signed-off-by: Andrea Righi <arighi@nvidia.com> Signed-off-by: Tejun Heo <tj@kernel.org>
1 parent a730e3f commit 36adf6f

5 files changed

Lines changed: 163 additions & 105 deletions

File tree

tools/testing/selftests/sched_ext/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,10 @@ all_test_bpfprogs := $(foreach prog,$(wildcard *.bpf.c),$(INCLUDE_DIR)/$(patsubs
162162
auto-test-targets := \
163163
create_dsq \
164164
enq_last_no_enq_fails \
165-
enq_select_cpu_fails \
166165
ddsp_bogus_dsq_fail \
167166
ddsp_vtimelocal_fail \
168167
dsp_local_on \
168+
enq_select_cpu \
169169
exit \
170170
hotplug \
171171
init_enable_count \
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
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+
8+
#include <scx/common.bpf.h>
9+
10+
char _license[] SEC("license") = "GPL";
11+
12+
UEI_DEFINE(uei);
13+
14+
s32 BPF_STRUCT_OPS(enq_select_cpu_select_cpu, struct task_struct *p,
15+
s32 prev_cpu, u64 wake_flags)
16+
{
17+
/* Bounce all tasks to ops.enqueue() */
18+
return prev_cpu;
19+
}
20+
21+
void BPF_STRUCT_OPS(enq_select_cpu_enqueue, struct task_struct *p,
22+
u64 enq_flags)
23+
{
24+
s32 cpu, prev_cpu = scx_bpf_task_cpu(p);
25+
bool found = false;
26+
27+
cpu = scx_bpf_select_cpu_dfl(p, prev_cpu, 0, &found);
28+
if (found) {
29+
scx_bpf_dsq_insert(p, SCX_DSQ_LOCAL_ON | cpu, SCX_SLICE_DFL, enq_flags);
30+
return;
31+
}
32+
33+
scx_bpf_dsq_insert(p, SCX_DSQ_GLOBAL, SCX_SLICE_DFL, enq_flags);
34+
}
35+
36+
void BPF_STRUCT_OPS(enq_select_cpu_exit, struct scx_exit_info *ei)
37+
{
38+
UEI_RECORD(uei, ei);
39+
}
40+
41+
struct task_cpu_arg {
42+
pid_t pid;
43+
};
44+
45+
SEC("syscall")
46+
int select_cpu_from_user(struct task_cpu_arg *input)
47+
{
48+
struct task_struct *p;
49+
bool found = false;
50+
s32 cpu;
51+
52+
p = bpf_task_from_pid(input->pid);
53+
if (!p)
54+
return -EINVAL;
55+
56+
bpf_rcu_read_lock();
57+
cpu = scx_bpf_select_cpu_dfl(p, bpf_get_smp_processor_id(), 0, &found);
58+
if (!found)
59+
cpu = -EBUSY;
60+
bpf_rcu_read_unlock();
61+
62+
bpf_task_release(p);
63+
64+
return cpu;
65+
}
66+
67+
SEC(".struct_ops.link")
68+
struct sched_ext_ops enq_select_cpu_ops = {
69+
.select_cpu = (void *)enq_select_cpu_select_cpu,
70+
.enqueue = (void *)enq_select_cpu_enqueue,
71+
.exit = (void *)enq_select_cpu_exit,
72+
.name = "enq_select_cpu",
73+
.timeout_ms = 1000U,
74+
};
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
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 <sys/wait.h>
10+
#include <unistd.h>
11+
#include "enq_select_cpu.bpf.skel.h"
12+
#include "scx_test.h"
13+
14+
static enum scx_test_status setup(void **ctx)
15+
{
16+
struct enq_select_cpu *skel;
17+
18+
skel = enq_select_cpu__open();
19+
SCX_FAIL_IF(!skel, "Failed to open");
20+
SCX_ENUM_INIT(skel);
21+
SCX_FAIL_IF(enq_select_cpu__load(skel), "Failed to load skel");
22+
23+
*ctx = skel;
24+
25+
return SCX_TEST_PASS;
26+
}
27+
28+
static int test_select_cpu_from_user(const struct enq_select_cpu *skel)
29+
{
30+
int fd, ret;
31+
__u64 args[1];
32+
33+
LIBBPF_OPTS(bpf_test_run_opts, attr,
34+
.ctx_in = args,
35+
.ctx_size_in = sizeof(args),
36+
);
37+
38+
args[0] = getpid();
39+
fd = bpf_program__fd(skel->progs.select_cpu_from_user);
40+
if (fd < 0)
41+
return fd;
42+
43+
ret = bpf_prog_test_run_opts(fd, &attr);
44+
if (ret < 0)
45+
return ret;
46+
47+
fprintf(stderr, "%s: CPU %d\n", __func__, attr.retval);
48+
49+
return 0;
50+
}
51+
52+
static enum scx_test_status run(void *ctx)
53+
{
54+
struct enq_select_cpu *skel = ctx;
55+
struct bpf_link *link;
56+
57+
link = bpf_map__attach_struct_ops(skel->maps.enq_select_cpu_ops);
58+
if (!link) {
59+
SCX_ERR("Failed to attach scheduler");
60+
return SCX_TEST_FAIL;
61+
}
62+
63+
/* Pick an idle CPU from user-space */
64+
SCX_FAIL_IF(test_select_cpu_from_user(skel), "Failed to pick idle CPU");
65+
66+
sleep(1);
67+
68+
SCX_EQ(skel->data->uei.kind, EXIT_KIND(SCX_EXIT_NONE));
69+
bpf_link__destroy(link);
70+
71+
return SCX_TEST_PASS;
72+
}
73+
74+
static void cleanup(void *ctx)
75+
{
76+
struct enq_select_cpu *skel = ctx;
77+
78+
enq_select_cpu__destroy(skel);
79+
}
80+
81+
struct scx_test enq_select_cpu = {
82+
.name = "enq_select_cpu",
83+
.description = "Verify scx_bpf_select_cpu_dfl() from multiple contexts",
84+
.setup = setup,
85+
.run = run,
86+
.cleanup = cleanup,
87+
};
88+
REGISTER_SCX_TEST(&enq_select_cpu)

tools/testing/selftests/sched_ext/enq_select_cpu_fails.bpf.c

Lines changed: 0 additions & 43 deletions
This file was deleted.

tools/testing/selftests/sched_ext/enq_select_cpu_fails.c

Lines changed: 0 additions & 61 deletions
This file was deleted.

0 commit comments

Comments
 (0)