Skip to content
This repository has been archived by the owner on Jun 18, 2024. It is now read-only.

Commit

Permalink
scx: Add selftests for scx_bpf_exit()
Browse files Browse the repository at this point in the history
Let's add a selftest that verifies us using scx_bpf_exit() to exit from
various callbacks in the program.

Signed-off-by: David Vernet <[email protected]>
  • Loading branch information
Byte-Lab committed Mar 28, 2024
1 parent 3b6687f commit ae74764
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 2 deletions.
1 change: 1 addition & 0 deletions tools/testing/selftests/sched_ext/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ auto-test-targets := \
enq_select_cpu_fails \
ddsp_bogus_dsq_fail \
ddsp_vtimelocal_fail \
exit \
init_enable_count \
maximal \
maybe_null \
Expand Down
84 changes: 84 additions & 0 deletions tools/testing/selftests/sched_ext/exit.bpf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2024 Meta Platforms, Inc. and affiliates.
* Copyright (c) 2024 David Vernet <[email protected]>
*/

#include <scx/common.bpf.h>

char _license[] SEC("license") = "GPL";

#include "exit_test.h"

const volatile int exit_point;
UEI_DEFINE(uei);

#define EXIT_CLEANLY() scx_bpf_exit(exit_point, "%d", exit_point)

s32 BPF_STRUCT_OPS(exit_select_cpu, struct task_struct *p,
s32 prev_cpu, u64 wake_flags)
{
bool found;

if (exit_point == EXIT_SELECT_CPU)
EXIT_CLEANLY();

return scx_bpf_select_cpu_dfl(p, prev_cpu, wake_flags, &found);
}

void BPF_STRUCT_OPS(exit_enqueue, struct task_struct *p, u64 enq_flags)
{
if (exit_point == EXIT_ENQUEUE)
EXIT_CLEANLY();

scx_bpf_dispatch(p, SCX_DSQ_GLOBAL, SCX_SLICE_DFL, enq_flags);
}

void BPF_STRUCT_OPS(exit_dispatch, s32 cpu, struct task_struct *p)
{
if (exit_point == EXIT_DISPATCH)
EXIT_CLEANLY();

scx_bpf_consume(SCX_DSQ_GLOBAL);
}

void BPF_STRUCT_OPS(exit_enable, struct task_struct *p)
{
if (exit_point == EXIT_ENABLE)
EXIT_CLEANLY();
}

s32 BPF_STRUCT_OPS(exit_init_task, struct task_struct *p,
struct scx_init_task_args *args)
{
if (exit_point == EXIT_INIT_TASK)
EXIT_CLEANLY();

return 0;
}

void BPF_STRUCT_OPS(exit_exit, struct scx_exit_info *ei)
{
UEI_RECORD(uei, ei);
}

s32 BPF_STRUCT_OPS_SLEEPABLE(exit_init)
{
if (exit_point == EXIT_INIT)
EXIT_CLEANLY();

return 0;
}

SEC(".struct_ops.link")
struct sched_ext_ops exit_ops = {
.select_cpu = exit_select_cpu,
.enqueue = exit_enqueue,
.dispatch = exit_dispatch,
.init_task = exit_init_task,
.enable = exit_enable,
.exit = exit_exit,
.init = exit_init,
.name = "exit",
.timeout_ms = 1000U,
};
55 changes: 55 additions & 0 deletions tools/testing/selftests/sched_ext/exit.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2024 Meta Platforms, Inc. and affiliates.
* Copyright (c) 2024 David Vernet <[email protected]>
*/
#include <bpf/bpf.h>
#include <sched.h>
#include <scx/common.h>
#include <sys/wait.h>
#include <unistd.h>
#include "exit.bpf.skel.h"
#include "scx_test.h"

#include "exit_test.h"

static enum scx_test_status run(void *ctx)
{
enum exit_test_case tc;

for (tc = 0; tc < NUM_EXITS; tc++) {
struct exit *skel;
struct bpf_link *link;
char buf[16];

skel = exit__open();
skel->rodata->exit_point = tc;
exit__load(skel);
link = bpf_map__attach_struct_ops(skel->maps.exit_ops);
if (!link) {
SCX_ERR("Failed to attach scheduler");
exit__destroy(skel);
return SCX_TEST_FAIL;
}

/* Assumes uei.kind is written last */
while (skel->data->uei.kind == SCX_EXIT_NONE)
sched_yield();

SCX_EQ(skel->data->uei.kind, SCX_EXIT_UNREG_BPF);
SCX_EQ(skel->data->uei.exit_code, tc);
sprintf(buf, "%d", tc);
SCX_ASSERT(!strcmp(skel->data->uei.msg, buf));
bpf_link__destroy(link);
exit__destroy(skel);
}

return SCX_TEST_PASS;
}

struct scx_test exit_test = {
.name = "exit",
.description = "Verify we can cleanly exit a scheduler in multiple places",
.run = run,
};
REGISTER_SCX_TEST(&exit_test)
20 changes: 20 additions & 0 deletions tools/testing/selftests/sched_ext/exit_test.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2024 Meta Platforms, Inc. and affiliates.
* Copyright (c) 2024 David Vernet <[email protected]>
*/

#ifndef __EXIT_TEST_H__
#define __EXIT_TEST_H__

enum exit_test_case {
EXIT_SELECT_CPU,
EXIT_ENQUEUE,
EXIT_DISPATCH,
EXIT_ENABLE,
EXIT_INIT_TASK,
EXIT_INIT,
NUM_EXITS,
};

#endif // # __EXIT_TEST_H__
5 changes: 3 additions & 2 deletions tools/testing/selftests/sched_ext/scx_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ enum scx_test_exit_kind {
SCX_EXIT_NONE,
SCX_EXIT_DONE,

SCX_EXIT_UNREG = 64, /* BPF unregistration */
SCX_EXIT_SYSRQ, /* requested by 'S' sysrq */
SCX_EXIT_UNREG = 64, /* User-space initiated unregistration */
SCX_EXIT_UNREG_BPF, /* BPF-initiated unregistration */
SCX_EXIT_SYSRQ, /* requested by 'S' sysrq */

SCX_EXIT_ERROR = 1024, /* runtime error, error msg contains details */
SCX_EXIT_ERROR_BPF, /* ERROR but triggered through scx_bpf_error() */
Expand Down

0 comments on commit ae74764

Please sign in to comment.