Skip to content

Commit

Permalink
Merge pull request #363 from sched-ext/htejun/compat-strip
Browse files Browse the repository at this point in the history
Strip compat support
  • Loading branch information
htejun authored Jun 17, 2024
2 parents 3814190 + b6ebdc6 commit d18bb48
Show file tree
Hide file tree
Showing 16 changed files with 76 additions and 226 deletions.
1 change: 0 additions & 1 deletion rust/scx_rustland_core/assets/bpf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,6 @@ impl<'cb> BpfScheduler<'cb> {

skel.bss_mut().usersched_pid = std::process::id();
skel.rodata_mut().slice_ns = slice_us * 1000;
skel.rodata_mut().switch_partial = partial;
skel.rodata_mut().debug = debug;
skel.rodata_mut().full_user = full_user;
skel.rodata_mut().low_power = low_power;
Expand Down
6 changes: 2 additions & 4 deletions rust/scx_rustland_core/assets/bpf/main.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ dispatch_task(struct task_struct *p, u64 dsq_id,
p->pid, p->comm, dsq_id, enq_flags, slice);

/* Wake up the target CPU (only if idle) */
scx_bpf_kick_cpu(cpu, __COMPAT_SCX_KICK_IDLE);
scx_bpf_kick_cpu(cpu, SCX_KICK_IDLE);
break;
}
}
Expand Down Expand Up @@ -477,7 +477,7 @@ static void
dispatch_direct_cpu(struct task_struct *p, s32 cpu, u64 slice_ns, u64 enq_flags)
{
scx_bpf_dispatch(p, cpu_to_dsq(cpu), slice_ns, enq_flags);
scx_bpf_kick_cpu(cpu, __COMPAT_SCX_KICK_IDLE);
scx_bpf_kick_cpu(cpu, SCX_KICK_IDLE);

__sync_fetch_and_add(&nr_kernel_dispatches, 1);
}
Expand Down Expand Up @@ -1020,8 +1020,6 @@ s32 BPF_STRUCT_OPS_SLEEPABLE(rustland_init)
err = usersched_timer_init();
if (err)
return err;
if (!switch_partial)
__COMPAT_scx_bpf_switch_all();

return 0;
}
Expand Down
103 changes: 48 additions & 55 deletions rust/scx_utils/src/compat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,37 +151,57 @@ pub fn is_sched_ext_enabled() -> io::Result<bool> {
}
}

#[macro_export]
macro_rules! unwrap_or_break {
($expr: expr, $label: lifetime) => {{
match $expr {
Ok(val) => val,
Err(e) => break $label Err(e),
}
}};
}

pub fn check_min_requirements() -> Result<()> {
// ec7e3b0463e1 ("implement-ops") in https://github.com/sched-ext/sched_ext
// is the current minimum required kernel version.
if let Ok(false) | Err(_) = struct_has_field("sched_ext_ops", "dump") {
bail!("sched_ext_ops.dump() missing, kernel too old?");
}
Ok(())
}

/// 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.
#[rustfmt::skip]
#[macro_export]
macro_rules! scx_ops_open {
($builder: expr, $ops: ident) => {{
($builder: expr, $ops: ident) => { 'block: {
scx_utils::paste! {
let mut skel = $builder.open().context("Failed to open BPF program")?;
scx_utils::unwrap_or_break!(scx_utils::compat::check_min_requirements(), 'block);

let mut skel = match $builder.open().context("Failed to open BPF program") {
Ok(val) => val,
Err(e) => break 'block Err(e),
};

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 path = std::path::Path::new("/sys/kernel/sched_ext/hotplug_seq");

let val = match std::fs::read_to_string(&path) {
Ok(val) => val,
Err(_) => {
break 'block Err(anyhow::anyhow!("Failed to open or read file {:?}", path));
}
};

ops.hotplug_seq = match val.trim().parse::<u64>() {
Ok(parsed) => parsed,
Err(_) => {
break 'block Err(anyhow::anyhow!("Failed to parse hotplug seq {}", val));
}
};

let result : Result<OpenBpfSkel<'_>, anyhow::Error> = Ok(skel);
result
Expand All @@ -193,51 +213,24 @@ macro_rules! scx_ops_open {
/// 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
/// support it, the value is ignored and a warning is triggered if the value
/// is requested to be non-zero.
#[rustfmt::skip]
#[macro_export]
macro_rules! scx_ops_load {
($skel: expr, $ops: ident, $uei: ident) => {{
($skel: expr, $ops: ident, $uei: ident) => { 'block: {
scx_utils::paste! {
scx_utils::uei_set_size!($skel, $ops, $uei);

let ops = $skel.struct_ops.[<$ops _mut>]();

if !scx_utils::compat::struct_has_field("sched_ext_ops", "exit_dump_len")?
&& ops.exit_dump_len != 0 {
scx_utils::warn!("Kernel doesn't support setting exit dump len");
ops.exit_dump_len = 0;
}

if !scx_utils::compat::struct_has_field("sched_ext_ops", "tick")?
&& ops.tick != std::ptr::null_mut() {
scx_utils::warn!("Kernel doesn't support ops.tick()");
ops.tick = std::ptr::null_mut();
}

if !scx_utils::compat::struct_has_field("sched_ext_ops", "dump")?
&& (ops.dump != std::ptr::null_mut() ||
ops.dump_cpu != std::ptr::null_mut() ||
ops.dump_task != std::ptr::null_mut()) {
scx_utils::warn!("Kernel doesn't support ops.dump*()");
ops.dump = std::ptr::null_mut();
ops.dump_cpu = std::ptr::null_mut();
ops.dump_task = std::ptr::null_mut();
}

$skel.load().context("Failed to load BPF program")
}
}};
}

/// Must be used together with scx_ops_load!(). See there.
#[rustfmt::skip]
#[macro_export]
macro_rules! scx_ops_attach {
($skel: expr, $ops: ident) => {{
($skel: expr, $ops: ident) => { 'block: {
if scx_utils::compat::is_sched_ext_enabled().unwrap_or(false) {
return Err(anyhow::anyhow!(
break 'block Err(anyhow::anyhow!(
"another sched_ext scheduler is already running"
));
}
Expand Down
3 changes: 1 addition & 2 deletions scheds/c/scx_central.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ static bool dispatch_to_cpu(s32 cpu)
scx_bpf_dispatch(p, SCX_DSQ_LOCAL_ON | cpu, SCX_SLICE_INF, 0);

if (cpu != central_cpu)
scx_bpf_kick_cpu(cpu, __COMPAT_SCX_KICK_IDLE);
scx_bpf_kick_cpu(cpu, SCX_KICK_IDLE);

bpf_task_release(p);
return true;
Expand Down Expand Up @@ -305,7 +305,6 @@ int BPF_STRUCT_OPS_SLEEPABLE(central_init)
struct bpf_timer *timer;
int ret;

__COMPAT_scx_bpf_switch_all();
ret = scx_bpf_create_dsq(FALLBACK_DSQ_ID, -1);
if (ret)
return ret;
Expand Down
2 changes: 0 additions & 2 deletions scheds/c/scx_nest.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -582,8 +582,6 @@ s32 BPF_STRUCT_OPS_SLEEPABLE(nest_init)
struct bpf_timer *timer;
u32 key = 0;

__COMPAT_scx_bpf_switch_all();

err = scx_bpf_create_dsq(FALLBACK_DSQ_ID, NUMA_NO_NODE);
if (err) {
scx_bpf_error("Failed to create fallback DSQ");
Expand Down
28 changes: 9 additions & 19 deletions scheds/c/scx_qmap.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ const volatile bool print_shared_dsq;
const volatile char exp_prefix[17];
const volatile s32 disallow_tgid;
const volatile bool suppress_dump;
const volatile bool switch_partial;

u32 test_error_cnt;

Expand Down Expand Up @@ -222,7 +221,7 @@ void BPF_STRUCT_OPS(qmap_enqueue, struct task_struct *p, u64 enq_flags)
scx_bpf_dispatch(p, SHARED_DSQ, 0, enq_flags);
cpu = scx_bpf_pick_idle_cpu(p->cpus_ptr, 0);
if (cpu >= 0)
scx_bpf_kick_cpu(cpu, __COMPAT_SCX_KICK_IDLE);
scx_bpf_kick_cpu(cpu, SCX_KICK_IDLE);
return;
}

Expand Down Expand Up @@ -476,13 +475,13 @@ void BPF_STRUCT_OPS(qmap_dump, struct scx_dump_ctx *dctx)
if (!(fifo = bpf_map_lookup_elem(&queue_arr, &i)))
return;

__COMPAT_scx_bpf_dump("QMAP FIFO[%d]:", i);
scx_bpf_dump("QMAP FIFO[%d]:", i);
bpf_repeat(4096) {
if (bpf_map_pop_elem(fifo, &pid))
break;
__COMPAT_scx_bpf_dump(" %d", pid);
scx_bpf_dump(" %d", pid);
}
__COMPAT_scx_bpf_dump("\n");
scx_bpf_dump("\n");
}
}

Expand All @@ -496,9 +495,9 @@ void BPF_STRUCT_OPS(qmap_dump_cpu, struct scx_dump_ctx *dctx, s32 cpu, bool idle
if (!(cpuc = bpf_map_lookup_percpu_elem(&cpu_ctx_stor, &zero, cpu)))
return;

__COMPAT_scx_bpf_dump("QMAP: dsp_idx=%llu dsp_cnt=%llu avg_weight=%u cpuperf_target=%u",
cpuc->dsp_idx, cpuc->dsp_cnt, cpuc->avg_weight,
cpuc->cpuperf_target);
scx_bpf_dump("QMAP: dsp_idx=%llu dsp_cnt=%llu avg_weight=%u cpuperf_target=%u",
cpuc->dsp_idx, cpuc->dsp_cnt, cpuc->avg_weight,
cpuc->cpuperf_target);
}

void BPF_STRUCT_OPS(qmap_dump_task, struct scx_dump_ctx *dctx, struct task_struct *p)
Expand All @@ -510,8 +509,8 @@ void BPF_STRUCT_OPS(qmap_dump_task, struct scx_dump_ctx *dctx, struct task_struc
if (!(taskc = bpf_task_storage_get(&task_ctx_stor, p, 0, 0)))
return;

__COMPAT_scx_bpf_dump("QMAP: force_local=%d core_sched_seq=%llu",
taskc->force_local, taskc->core_sched_seq);
scx_bpf_dump("QMAP: force_local=%d core_sched_seq=%llu",
taskc->force_local, taskc->core_sched_seq);
}

/*
Expand All @@ -525,9 +524,6 @@ static void print_cpus(void)
char buf[128] = "", *p;
int idx;

if (!__COMPAT_HAS_CPUMASKS)
return;

possible = scx_bpf_get_possible_cpumask();
online = scx_bpf_get_online_cpumask();

Expand Down Expand Up @@ -593,9 +589,6 @@ static void monitor_cpuperf(void)
const struct cpumask *online;
int i, nr_online_cpus = 0;

if (!__COMPAT_HAS_CPUMASKS)
return;

nr_cpu_ids = scx_bpf_nr_cpu_ids();
online = scx_bpf_get_online_cpumask();

Expand Down Expand Up @@ -683,9 +676,6 @@ s32 BPF_STRUCT_OPS_SLEEPABLE(qmap_init)
struct bpf_timer *timer;
s32 ret;

if (!switch_partial)
__COMPAT_scx_bpf_switch_all();

print_cpus();

ret = scx_bpf_create_dsq(SHARED_DSQ, -1);
Expand Down
3 changes: 1 addition & 2 deletions scheds/c/scx_qmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,7 @@ int main(int argc, char **argv)
skel->rodata->suppress_dump = true;
break;
case 'p':
skel->rodata->switch_partial = true;
skel->struct_ops.qmap_ops->flags |= __COMPAT_SCX_OPS_SWITCH_PARTIAL;
skel->struct_ops.qmap_ops->flags |= SCX_OPS_SWITCH_PARTIAL;
break;
case 'v':
verbose = true;
Expand Down
1 change: 0 additions & 1 deletion scheds/c/scx_simple.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,6 @@ void BPF_STRUCT_OPS(simple_enable, struct task_struct *p)

s32 BPF_STRUCT_OPS_SLEEPABLE(simple_init)
{
__COMPAT_scx_bpf_switch_all();
return scx_bpf_create_dsq(SHARED_DSQ, -1);
}

Expand Down
7 changes: 5 additions & 2 deletions scheds/include/scx/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@ typedef int64_t s64;

#define SCX_BUG(__fmt, ...) \
do { \
fprintf(stderr, "%s:%d [scx panic]: %s\n", __FILE__, __LINE__, \
strerror(errno)); \
fprintf(stderr, "[SCX_BUG] %s:%d", __FILE__, __LINE__); \
if (errno) \
fprintf(stderr, " (%s)\n", strerror(errno)); \
else \
fprintf(stderr, "\n"); \
fprintf(stderr, __fmt __VA_OPT__(,) __VA_ARGS__); \
fprintf(stderr, "\n"); \
\
Expand Down
Loading

0 comments on commit d18bb48

Please sign in to comment.