scx_rustland_core: introduce RustLandBuilder()

Introduce a wrapper to scx_utils::BpfBuilder that can be used to build
the BPF component provided by scx_rustland_core.

The source of the BPF components (main.bpf.c) is included in the crate
as an array of bytes, the content is then unpacked in a temporary file
to perform the build.

The RustLandBuilder() helper is also used to generate bpf.rs (that
implements the low-level user-space Rust connector to the BPF
commponent).

Schedulers based on scx_rustland_core can simply use RustLandBuilder(),
to build the backend provided by scx_rustland_core.

Signed-off-by: Andrea Righi <andrea.righi@canonical.com>
This commit is contained in:
Andrea Righi 2024-02-27 17:54:54 +01:00
parent e23426e299
commit 2ac1a5924f
11 changed files with 84 additions and 31 deletions

View File

@ -7,26 +7,20 @@ license = "GPL-2.0-only"
repository = "https://github.com/sched-ext/scx"
description = "Framework to implement sched_ext schedulers running in user space"
include = [
"src/bpf/intf.h",
"src/bpf/main.bpf.c",
]
[dependencies]
anyhow = "1.0"
bitvec = { version = "1.0", features = ["serde"] }
# FIXME - We need to allow both 0.68 and 0.69 to accommodate fedora. See the
# comment in BpfBuilder::bindgen_bpf_intf() for details.
bindgen = ">=0.68, <0.70"
glob = "0.3"
hex = "0.4.3"
lazy_static = "1.4"
libbpf-cargo = "0.22"
libbpf-rs = "0.22.0"
libc = "0.2.137"
buddy-alloc = "0.5.1"
log = "0.4.17"
regex = "1.10"
sscanf = "0.4"
tar = "0.4"
version-compare = "0.1"
tempfile = "3.10.1"
scx_utils = { path = "../scx_utils", version = "0.6" }
[build-dependencies]
bindgen = ">=0.68, <0.70"
tar = "0.4"
walkdir = "2.4"
scx_utils = { path = "../scx_utils", version = "0.6" }

View File

@ -2,3 +2,6 @@ mod bindings;
mod alloc;
pub use alloc::ALLOCATOR;
mod rustland_builder;
pub use rustland_builder::RustLandBuilder;

View File

@ -0,0 +1,67 @@
// Copyright (c) Andrea Righi <andrea.righi@canonical.com>
// This software may be used and distributed according to the terms of the
// GNU General Public License version 2.
use anyhow::Result;
use std::error::Error;
use std::fs::File;
use std::io::Write;
use std::path::{Path, PathBuf};
use tempfile::tempdir;
use scx_utils::BpfBuilder;
pub struct RustLandBuilder {
inner_builder: BpfBuilder,
temp_dir: tempfile::TempDir,
}
impl RustLandBuilder {
pub fn new() -> Result<Self> {
Ok(Self {
inner_builder: BpfBuilder::new()?,
temp_dir: tempdir()?,
})
}
fn create_temp_file(
&mut self,
file_name: &str,
content: &[u8],
) -> Result<PathBuf, Box<dyn Error>> {
let mut temp_file = self.temp_dir.as_ref().to_path_buf();
temp_file.push(file_name);
let mut file = File::create(&temp_file)?;
file.write_all(content)?;
Ok(temp_file)
}
fn get_bpf_rs_content(&self) -> &'static str {
include_str!("bpf.rs")
}
pub fn build(&mut self) -> Result<()> {
// Embed the BPF source files in the crate.
let intf = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/bpf/intf.h"));
let skel = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/bpf/main.bpf.c"));
let intf_path = self.create_temp_file("intf.h", intf).unwrap();
let skel_path = self.create_temp_file("main.bpf.c", skel).unwrap();
self.inner_builder
.enable_intf(intf_path.to_str().unwrap(), "bpf_intf.rs");
self.inner_builder
.enable_skel(skel_path.to_str().unwrap(), "bpf");
let content = self.get_bpf_rs_content();
let path = Path::new("src/bpf.rs");
let mut file = File::create(&path).expect("Unable to create file");
file.write_all(content.as_bytes()).expect("Unable to write to file");
self.inner_builder.build()
}
}

View File

@ -1,3 +1,4 @@
src/bpf/.output
bpf.rs
Cargo.lock
target

View File

@ -9,7 +9,6 @@ license = "GPL-2.0-only"
[dependencies]
anyhow = "1.0.65"
ctrlc = { version = "3.1", features = ["termination"] }
hex = "0.4.3"
libbpf-rs = "0.22.0"
libc = "0.2.137"
scx_utils = { path = "../../../rust/scx_utils", version = "0.6" }
@ -17,6 +16,7 @@ scx_rustland_core = { path = "../../../rust/scx_rustland_core", version = "0.1"
[build-dependencies]
scx_utils = { path = "../../../rust/scx_utils", version = "0.6" }
scx_rustland_core = { path = "../../../rust/scx_rustland_core", version = "0.1" }
[features]
enable_backtrace = []

View File

@ -2,10 +2,8 @@
// GNU General Public License version 2.
fn main() {
scx_utils::BpfBuilder::new()
scx_rustland_core::RustLandBuilder::new()
.unwrap()
.enable_intf("../../../rust/scx_rustland_core/src/bpf/intf.h", "bpf_intf.rs")
.enable_skel("../../../rust/scx_rustland_core/src/bpf/main.bpf.c", "bpf")
.build()
.unwrap();
}

View File

@ -1,4 +0,0 @@
// This software may be used and distributed according to the terms of the
// GNU General Public License version 2.
include!("../../../../rust/scx_rustland_core/src/bpf.rs");

View File

@ -1,3 +1,4 @@
src/bpf/.output
bpf.rs
Cargo.lock
target

View File

@ -8,11 +8,9 @@ license = "GPL-2.0-only"
[dependencies]
anyhow = "1.0.65"
bitvec = { version = "1.0", features = ["serde"] }
clap = { version = "4.1", features = ["derive", "env", "unicode", "wrap_help"] }
ctrlc = { version = "3.1", features = ["termination"] }
fb_procfs = "0.7.0"
hex = "0.4.3"
libbpf-rs = "0.22.0"
libc = "0.2.137"
log = "0.4.17"
@ -23,6 +21,7 @@ simplelog = "0.12.0"
[build-dependencies]
scx_utils = { path = "../../../rust/scx_utils", version = "0.6" }
scx_rustland_core = { path = "../../../rust/scx_rustland_core", version = "0.1" }
[features]
enable_backtrace = []

View File

@ -2,10 +2,8 @@
// GNU General Public License version 2.
fn main() {
scx_utils::BpfBuilder::new()
scx_rustland_core::RustLandBuilder::new()
.unwrap()
.enable_intf("../../../rust/scx_rustland_core/src/bpf/intf.h", "bpf_intf.rs")
.enable_skel("../../../rust/scx_rustland_core/src/bpf/main.bpf.c", "bpf")
.build()
.unwrap();
}

View File

@ -1,4 +0,0 @@
// This software may be used and distributed according to the terms of the
// GNU General Public License version 2.
include!("../../../../rust/scx_rustland_core/src/bpf.rs");