mirror of
https://github.com/sched-ext/scx.git
synced 2024-11-25 04:00:24 +00:00
Merge pull request #289 from sched-ext/rusty_hot_plug
Add remaining hotplug pieces
This commit is contained in:
commit
c1f1411c7a
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user