1mod bpf_skel;
6
7use crate::bpf_skel::BpfSkelBuilder;
8
9use std::mem::MaybeUninit;
10
11use anyhow::Result;
12use libbpf_rs::skel::{OpenSkel, SkelBuilder};
13use libbpf_rs::ProgramType;
14use once_cell::sync::OnceCell;
15use scx_utils::compat::ksym_exists;
16
17pub fn kfuncs_supported_in_syscall() -> Result<bool> {
21 static MEMO: OnceCell<bool> = OnceCell::new();
22
23 MEMO.get_or_try_init(|| {
24 if !ProgramType::Syscall.is_supported()? {
25 return Ok(false);
26 }
27 if !ksym_exists("bpf_cpumask_create")? {
28 return Ok(false);
29 }
30 if !ksym_exists("bpf_cpumask_release")? {
31 return Ok(false);
32 }
33
34 let skel_builder = BpfSkelBuilder::default();
35 let mut open_object = MaybeUninit::uninit();
36
37 let mut open_skel = skel_builder.open(&mut open_object)?;
38 for mut prog in open_skel.open_object_mut().progs_mut() {
39 prog.set_autoload(prog.name() == "kfuncs_test_syscall");
40 }
41
42 let ret = match open_skel.load() {
43 Ok(_) => true,
44 Err(e) => {
45 log::trace!("rejecting program for `kfuncs_supported_in_syscall` with error: {e}");
46 false
47 }
48 };
49
50 Ok(ret)
51 })
52 .copied()
53}