in src/samplers/scheduler/mod.rs [322:371]
fn initialize_bpf(&mut self) -> Result<(), anyhow::Error> {
#[cfg(feature = "bpf")]
{
if self.enabled() && self.bpf_enabled() {
debug!("initializing bpf");
// get info about the running kernel
let kernel_info = KernelInfo::new()?;
let kernel_major = kernel_info.release_major()?;
let kernel_minor = kernel_info.release_minor()?;
// load the code and compile
let code = include_str!("bpf.c");
let code = code.replace(
"VALUE_TO_INDEX2_FUNC",
include_str!("../../common/value_to_index2.c"),
);
// task_struct changes in kernel 5.14
let code = if kernel_major > 5 || (kernel_major == 5 && kernel_minor >= 14) {
code.replace("STATE_FIELD", "__state")
} else {
code.replace("STATE_FIELD", "state")
};
let mut bpf = bcc::BPF::new(&code)?;
// collect the set of probes required from the statistics enabled.
let mut probes = HashSet::new();
for statistic in &self.statistics {
for probe in statistic.bpf_probes_required() {
probes.insert(probe);
}
}
// load + attach the kernel probes that are required to the bpf instance.
for probe in probes {
if self.common.config.fault_tolerant() {
if let Err(e) = probe.try_attach_to_bpf(&mut bpf) {
warn!("skipping {} with error: {}", probe.name, e);
}
} else {
probe.try_attach_to_bpf(&mut bpf)?;
}
}
self.bpf = Some(Arc::new(Mutex::new(BPF { inner: bpf })));
}
}
Ok(())
}