Merge pull request #289 from sched-ext/rusty_hot_plug

Add remaining hotplug pieces
This commit is contained in:
David Vernet 2024-05-16 13:42:11 -06:00 committed by GitHub
commit c1f1411c7a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 61 additions and 23 deletions

View File

@ -151,9 +151,47 @@ pub fn is_sched_ext_enabled() -> io::Result<bool> {
}
}
/// struct sched_ext_ops can change over time. If
/// compat.bpf.h::SCX_OPS_DEFINE() is used to define ops and scx_ops_load!()
/// and scx_ops_attach!() are used to load and attach it, backward
/// struct sched_ext_ops can change over time. If compat.bpf.h::SCX_OPS_DEFINE()
/// is used to define ops, and scx_ops_open!(), scx_ops_load!(), and
/// scx_ops_attach!() are used to open, load and attach it, backward
/// compatibility is automatically maintained where reasonable.
///
/// - sched_ext_ops.hotplug_seq was added later. On kernels which support it,
/// set the value to a nonzero value to trigger an exit in the scheduler when
/// a hotplug event occurs between opening and attaching the scheduler.
#[macro_export]
macro_rules! scx_ops_open {
($builder: expr, $ops: ident) => {{
scx_utils::paste! {
let mut skel = $builder.open().context("Failed to open BPF program")?;
let ops = skel.struct_ops.[<$ops _mut>]();
let has_field = scx_utils::compat::struct_has_field("sched_ext_ops", "hotplug_seq")?;
if has_field {
let path = std::path::Path::new("/sys/kernel/sched_ext/hotplug_seq");
let val = match std::fs::read_to_string(&path) {
Ok(val) => val,
Err(_) => {
return Err(anyhow::anyhow!("Failed to open or read file {:?}", path));
}
};
ops.hotplug_seq = match val.trim().parse::<u64>() {
Ok(parsed) => parsed,
Err(_) => {
return Err(anyhow::anyhow!("Failed to parse hotplug seq {}", val));
}
};
}
let result : Result<OpenBpfSkel<'_>, anyhow::Error> = Ok(skel);
result
}
}};
}
/// struct sched_ext_ops can change over time. If compat.bpf.h::SCX_OPS_DEFINE()
/// is used to define ops, and scx_ops_open!(), scx_ops_load!(), and
/// scx_ops_attach!() are used to open, load and attach it, backward
/// compatibility is automatically maintained where reasonable.
///
/// - sched_ext_ops.exit_dump_len was added later. On kernels which don't

View File

@ -44,6 +44,8 @@ pub use builder::Builder;
mod user_exit_info;
pub use user_exit_info::ScxExitKind;
pub use user_exit_info::ScxConsts;
pub use user_exit_info::SCX_ECODE_RSN_HOTPLUG;
pub use user_exit_info::SCX_ECODE_ACT_RESTART;
pub use user_exit_info::UeiDumpPtr;
pub use user_exit_info::UserExitInfo;
pub use user_exit_info::UEI_DUMP_PTR_MUTEX;

View File

@ -3,6 +3,7 @@
// This software may be used and distributed according to the terms of the
// GNU General Public License version 2.
use crate::bindings;
use crate::compat;
use anyhow::bail;
use anyhow::Result;
use std::ffi::CStr;
@ -18,11 +19,22 @@ pub static UEI_DUMP_PTR_MUTEX: Mutex<UeiDumpPtr> = Mutex::new(UeiDumpPtr {
ptr: std::ptr::null(),
});
lazy_static::lazy_static! {
pub static ref SCX_ECODE_RSN_HOTPLUG: u64 =
compat::read_enum("scx_exit_code", "SCX_ECODE_RSN_HOTPLUG").unwrap_or(0);
}
lazy_static::lazy_static! {
pub static ref SCX_ECODE_ACT_RESTART: u64 =
compat::read_enum("scx_exit_code", "SCX_ECODE_ACT_RESTART").unwrap_or(0);
}
pub enum ScxExitKind {
None = bindings::scx_exit_kind_SCX_EXIT_NONE as isize,
Done = bindings::scx_exit_kind_SCX_EXIT_DONE as isize,
Unreg = bindings::scx_exit_kind_SCX_EXIT_UNREG as isize,
UnregBPF = bindings::scx_exit_kind_SCX_EXIT_UNREG_BPF as isize,
UnregKern = bindings::scx_exit_kind_SCX_EXIT_UNREG_KERN as isize,
SysRq = bindings::scx_exit_kind_SCX_EXIT_SYSRQ as isize,
Error = bindings::scx_exit_kind_SCX_EXIT_ERROR as isize,
ErrorBPF = bindings::scx_exit_kind_SCX_EXIT_ERROR_BPF as isize,
@ -194,7 +206,7 @@ impl UserExitInfo {
_ => "<UNKNOWN>".into(),
};
if self.kind <= ScxExitKind::UnregBPF as i32 {
if self.kind <= ScxExitKind::UnregKern as i32 {
eprintln!("{}", why);
Ok(())
} else {
@ -206,7 +218,7 @@ impl UserExitInfo {
/// only applies when the BPF scheduler exits with scx_bpf_exit(), i.e. kind
/// ScxExitKind::UnregBPF.
pub fn exit_code(&self) -> Option<i64> {
if self.kind == ScxExitKind::UnregBPF as i32 {
if self.kind == ScxExitKind::UnregBPF as i32 || self.kind == ScxExitKind::UnregKern as i32 {
Some(self.exit_code)
} else {
None

View File

@ -61,10 +61,6 @@ enum consts {
MAX_DOM_ACTIVE_PIDS = 1024,
};
enum rusty_exit_codes {
RUSTY_EXIT_HOTPLUG,
};
/* Statistics */
enum stat_idx {
/* The following fields add up to all dispatched tasks */

View File

@ -1743,16 +1743,6 @@ static s32 initialize_cpu(s32 cpu)
return 0;
}
void BPF_STRUCT_OPS(rusty_cpu_online, s32 cpu)
{
__COMPAT_scx_bpf_exit(RUSTY_EXIT_HOTPLUG, "CPU %d went online", cpu);
}
void BPF_STRUCT_OPS(rusty_cpu_offline, s32 cpu)
{
__COMPAT_scx_bpf_exit(RUSTY_EXIT_HOTPLUG, "CPU %d went offline", cpu);
}
s32 BPF_STRUCT_OPS_SLEEPABLE(rusty_init)
{
s32 i, ret;
@ -1812,8 +1802,6 @@ SCX_OPS_DEFINE(rusty,
.set_cpumask = (void *)rusty_set_cpumask,
.init_task = (void *)rusty_init_task,
.exit_task = (void *)rusty_exit_task,
.cpu_online = (void *)rusty_cpu_online,
.cpu_offline = (void *)rusty_cpu_offline,
.init = (void *)rusty_init,
.exit = (void *)rusty_exit,
.timeout_ms = 10000,

View File

@ -38,8 +38,10 @@ use scx_utils::compat;
use scx_utils::init_libbpf_logging;
use scx_utils::scx_ops_attach;
use scx_utils::scx_ops_load;
use scx_utils::scx_ops_open;
use scx_utils::uei_exited;
use scx_utils::uei_read;
use scx_utils::SCX_ECODE_ACT_RESTART;
use scx_utils::Cpumask;
use scx_utils::Topology;
use scx_utils::UserExitInfo;
@ -234,7 +236,7 @@ impl<'a> Scheduler<'a> {
let mut skel_builder = BpfSkelBuilder::default();
skel_builder.obj_builder.debug(opts.verbose > 0);
init_libbpf_logging(None);
let mut skel = skel_builder.open().context("Failed to open BPF program")?;
let mut skel = scx_ops_open!(skel_builder, rusty).unwrap();
// Initialize skel according to @opts.
let top = Arc::new(Topology::new()?);
@ -620,7 +622,7 @@ fn main() -> Result<()> {
let uei = sched.run(shutdown.clone())?;
if let Some(exit_code) = uei.exit_code() {
if exit_code == bpf_intf::rusty_exit_codes_RUSTY_EXIT_HOTPLUG as i64 {
if (exit_code & *SCX_ECODE_ACT_RESTART as i64) != 0 {
continue;
}
}