1*a5db7817SDavid Vernet /* SPDX-License-Identifier: GPL-2.0 */ 2*a5db7817SDavid Vernet /* 3*a5db7817SDavid Vernet * Copyright (c) 2024 Meta Platforms, Inc. and affiliates. 4*a5db7817SDavid Vernet * Copyright (c) 2024 David Vernet <dvernet@meta.com> 5*a5db7817SDavid Vernet */ 6*a5db7817SDavid Vernet #include <bpf/bpf.h> 7*a5db7817SDavid Vernet #include <sched.h> 8*a5db7817SDavid Vernet #include <scx/common.h> 9*a5db7817SDavid Vernet #include <sys/wait.h> 10*a5db7817SDavid Vernet #include <unistd.h> 11*a5db7817SDavid Vernet #include "exit.bpf.skel.h" 12*a5db7817SDavid Vernet #include "scx_test.h" 13*a5db7817SDavid Vernet 14*a5db7817SDavid Vernet #include "exit_test.h" 15*a5db7817SDavid Vernet run(void * ctx)16*a5db7817SDavid Vernetstatic enum scx_test_status run(void *ctx) 17*a5db7817SDavid Vernet { 18*a5db7817SDavid Vernet enum exit_test_case tc; 19*a5db7817SDavid Vernet 20*a5db7817SDavid Vernet for (tc = 0; tc < NUM_EXITS; tc++) { 21*a5db7817SDavid Vernet struct exit *skel; 22*a5db7817SDavid Vernet struct bpf_link *link; 23*a5db7817SDavid Vernet char buf[16]; 24*a5db7817SDavid Vernet 25*a5db7817SDavid Vernet skel = exit__open(); 26*a5db7817SDavid Vernet skel->rodata->exit_point = tc; 27*a5db7817SDavid Vernet exit__load(skel); 28*a5db7817SDavid Vernet link = bpf_map__attach_struct_ops(skel->maps.exit_ops); 29*a5db7817SDavid Vernet if (!link) { 30*a5db7817SDavid Vernet SCX_ERR("Failed to attach scheduler"); 31*a5db7817SDavid Vernet exit__destroy(skel); 32*a5db7817SDavid Vernet return SCX_TEST_FAIL; 33*a5db7817SDavid Vernet } 34*a5db7817SDavid Vernet 35*a5db7817SDavid Vernet /* Assumes uei.kind is written last */ 36*a5db7817SDavid Vernet while (skel->data->uei.kind == EXIT_KIND(SCX_EXIT_NONE)) 37*a5db7817SDavid Vernet sched_yield(); 38*a5db7817SDavid Vernet 39*a5db7817SDavid Vernet SCX_EQ(skel->data->uei.kind, EXIT_KIND(SCX_EXIT_UNREG_BPF)); 40*a5db7817SDavid Vernet SCX_EQ(skel->data->uei.exit_code, tc); 41*a5db7817SDavid Vernet sprintf(buf, "%d", tc); 42*a5db7817SDavid Vernet SCX_ASSERT(!strcmp(skel->data->uei.msg, buf)); 43*a5db7817SDavid Vernet bpf_link__destroy(link); 44*a5db7817SDavid Vernet exit__destroy(skel); 45*a5db7817SDavid Vernet } 46*a5db7817SDavid Vernet 47*a5db7817SDavid Vernet return SCX_TEST_PASS; 48*a5db7817SDavid Vernet } 49*a5db7817SDavid Vernet 50*a5db7817SDavid Vernet struct scx_test exit_test = { 51*a5db7817SDavid Vernet .name = "exit", 52*a5db7817SDavid Vernet .description = "Verify we can cleanly exit a scheduler in multiple places", 53*a5db7817SDavid Vernet .run = run, 54*a5db7817SDavid Vernet }; 55*a5db7817SDavid Vernet REGISTER_SCX_TEST(&exit_test) 56