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 7 #include <scx/common.bpf.h> 8 9 char _license[] SEC("license") = "GPL"; 10 11 #include "exit_test.h" 12 13 const volatile int exit_point; 14 UEI_DEFINE(uei); 15 16 #define EXIT_CLEANLY() scx_bpf_exit(exit_point, "%d", exit_point) 17 18 s32 BPF_STRUCT_OPS(exit_select_cpu, struct task_struct *p, 19 s32 prev_cpu, u64 wake_flags) 20 { 21 bool found; 22 23 if (exit_point == EXIT_SELECT_CPU) 24 EXIT_CLEANLY(); 25 26 return scx_bpf_select_cpu_dfl(p, prev_cpu, wake_flags, &found); 27 } 28 29 void BPF_STRUCT_OPS(exit_enqueue, struct task_struct *p, u64 enq_flags) 30 { 31 if (exit_point == EXIT_ENQUEUE) 32 EXIT_CLEANLY(); 33 34 scx_bpf_dispatch(p, SCX_DSQ_GLOBAL, SCX_SLICE_DFL, enq_flags); 35 } 36 37 void BPF_STRUCT_OPS(exit_dispatch, s32 cpu, struct task_struct *p) 38 { 39 if (exit_point == EXIT_DISPATCH) 40 EXIT_CLEANLY(); 41 42 scx_bpf_consume(SCX_DSQ_GLOBAL); 43 } 44 45 void BPF_STRUCT_OPS(exit_enable, struct task_struct *p) 46 { 47 if (exit_point == EXIT_ENABLE) 48 EXIT_CLEANLY(); 49 } 50 51 s32 BPF_STRUCT_OPS(exit_init_task, struct task_struct *p, 52 struct scx_init_task_args *args) 53 { 54 if (exit_point == EXIT_INIT_TASK) 55 EXIT_CLEANLY(); 56 57 return 0; 58 } 59 60 void BPF_STRUCT_OPS(exit_exit, struct scx_exit_info *ei) 61 { 62 UEI_RECORD(uei, ei); 63 } 64 65 s32 BPF_STRUCT_OPS_SLEEPABLE(exit_init) 66 { 67 if (exit_point == EXIT_INIT) 68 EXIT_CLEANLY(); 69 70 return 0; 71 } 72 73 SEC(".struct_ops.link") 74 struct sched_ext_ops exit_ops = { 75 .select_cpu = exit_select_cpu, 76 .enqueue = exit_enqueue, 77 .dispatch = exit_dispatch, 78 .init_task = exit_init_task, 79 .enable = exit_enable, 80 .exit = exit_exit, 81 .init = exit_init, 82 .name = "exit", 83 .timeout_ms = 1000U, 84 }; 85