1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright (c) 2024 Meta Platforms, Inc. and affiliates. 4 * Copyright (c) 2024 David Vernet <dvernet@meta.com> 5 */ 6 #include <bpf/bpf.h> 7 #include <sched.h> 8 #include <scx/common.h> 9 #include <sys/wait.h> 10 #include <unistd.h> 11 #include "prog_run.bpf.skel.h" 12 #include "scx_test.h" 13 14 static enum scx_test_status setup(void **ctx) 15 { 16 struct prog_run *skel; 17 18 skel = prog_run__open(); 19 SCX_FAIL_IF(!skel, "Failed to open"); 20 SCX_ENUM_INIT(skel); 21 SCX_FAIL_IF(prog_run__load(skel), "Failed to load skel"); 22 23 *ctx = skel; 24 25 return SCX_TEST_PASS; 26 } 27 28 static enum scx_test_status run(void *ctx) 29 { 30 struct prog_run *skel = ctx; 31 struct bpf_link *link = NULL; 32 enum scx_test_status status = SCX_TEST_PASS; 33 int prog_fd, err = 0; 34 35 prog_fd = bpf_program__fd(skel->progs.prog_run_syscall); 36 if (prog_fd < 0) { 37 SCX_ERR("Failed to get BPF_PROG_RUN prog"); 38 return SCX_TEST_FAIL; 39 } 40 41 LIBBPF_OPTS(bpf_test_run_opts, topts); 42 43 link = bpf_map__attach_struct_ops(skel->maps.prog_run_ops); 44 if (!link) { 45 SCX_ERR("Failed to attach scheduler"); 46 status = SCX_TEST_FAIL; 47 goto out; 48 } 49 50 err = bpf_prog_test_run_opts(prog_fd, &topts); 51 if (err) { 52 SCX_ERR("BPF_PROG_RUN failed (%d)", err); 53 status = SCX_TEST_FAIL; 54 goto out; 55 } 56 57 /* Assumes uei.kind is written last */ 58 while (skel->data->uei.kind == EXIT_KIND(SCX_EXIT_NONE)) 59 sched_yield(); 60 61 if (skel->data->uei.kind != EXIT_KIND(SCX_EXIT_UNREG_BPF)) { 62 SCX_ERR("Unexpected exit kind: %llu", 63 (unsigned long long)skel->data->uei.kind); 64 status = SCX_TEST_FAIL; 65 goto out; 66 } 67 if (skel->data->uei.exit_code != 0xdeadbeef) { 68 SCX_ERR("Unexpected exit code: %lld", 69 (long long)skel->data->uei.exit_code); 70 status = SCX_TEST_FAIL; 71 goto out; 72 } 73 74 out: 75 close(prog_fd); 76 if (link) 77 bpf_link__destroy(link); 78 79 return status; 80 } 81 82 static void cleanup(void *ctx) 83 { 84 struct prog_run *skel = ctx; 85 86 prog_run__destroy(skel); 87 } 88 89 struct scx_test prog_run = { 90 .name = "prog_run", 91 .description = "Verify we can call into a scheduler with BPF_PROG_RUN, and invoke kfuncs", 92 .setup = setup, 93 .run = run, 94 .cleanup = cleanup, 95 }; 96 REGISTER_SCX_TEST(&prog_run) 97