Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 5 additions & 10 deletions scheds/rust/scx_mitosis/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,14 @@ A cgroup-aware scheduler that isolates workloads into *cells*. The eventual goal

The direct children of the cgroup passed via `--cell-parent-cgroup` each get
their own *cell*, except for names excluded with `--cell-exclude`, which remain
in cell 0. Each cell owns a dedicated CPU set with a shared dispatch queue.
Tasks within a cell are scheduled using weighted vtime. CPU-pinned tasks
(typically system threads) use per-CPU queues. Cell and CPU tasks compete for
dispatch based on their vtime.

On multi-LLC systems, LLC-awareness keeps tasks on cache-sharing CPUs. In this case, the single cell queue is split into multiple queues, one per LLC.
in cell 0. Each cell owns a dedicated CPU set with one dispatch queue per LLC.
Tasks within a cell are scheduled using weighted vtime and kept on
cache-sharing CPUs when possible. CPU-pinned tasks (typically system threads)
use per-CPU queues. Cell and CPU tasks compete for dispatch based on their
vtime.

## Usage

```bash
# Basic
scx_mitosis --cell-parent-cgroup /workloads

# With LLC-awareness
scx_mitosis --cell-parent-cgroup /workloads --enable-llc-awareness
```
1 change: 0 additions & 1 deletion scheds/rust/scx_mitosis/src/bpf/intf.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ enum cell_stat_idx {
CSTAT_STEAL,
CSTAT_DRAIN_CNT,
CSTAT_CLAMP_USED,
CSTAT_PIN_SKIP,
CSTAT_SLICE_SHRINK_MAX,
CSTAT_SLICE_SHRINK_PROPORTIONAL,
CSTAT_SLICE_SHRINK_MIN,
Expand Down
39 changes: 16 additions & 23 deletions scheds/rust/scx_mitosis/src/bpf/llc_aware.bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,6 @@ static inline int refresh_cell_llc_draining(u32 cell_id)
u64 llcs_with_cpus = 0;
u32 llc;

if (!enable_llc_awareness)
return 0;

cell = lookup_cell(cell_id);
if (!cell)
return -EINVAL;
Expand Down Expand Up @@ -269,19 +266,14 @@ static inline int account_cell_llc_enqueue(u32 cell_id, u32 llc)
{
struct cell *cell;

if (!enable_llc_awareness)
return 0;

if (!llc_is_valid(llc) || llc >= nr_llc) {
scx_bpf_error("account_cell_llc_enqueue: invalid LLC %u", llc);
return -EINVAL;
}

cell = lookup_cell(cell_id);
if (!cell) {
scx_bpf_error("account_cell_llc_enqueue: invalid cell %u", cell_id);
if (!cell)
return -ENOENT;
}

/*
* Account the logical LLC DSQ insertion before checking llcs_with_cpus.
Expand Down Expand Up @@ -454,17 +446,13 @@ static inline int set_task_llc(struct task_struct *p, struct task_ctx *tctx, u32
}

struct cell *cell = lookup_cell(tctx->cell);
if (!cell) {
scx_bpf_error("failed to lookup cell %u for LLC assignment", tctx->cell);
return -ENOENT;
}
if (!cell)
return -EINVAL;

u32 old_llc = tctx->llc;
if (refresh_task_llc_cpumask(tctx, new_llc)) {
scx_bpf_error("failed to refresh task LLC cpumask for cell %u LLC %u", tctx->cell,
new_llc);
return -EINVAL;
}
int ret = refresh_task_llc_cpumask(tctx, new_llc);
if (ret)
return ret;

/*
* This writes a cell/LLC DSQ. Pinned tasks keep CPU DSQs.
Expand All @@ -488,10 +476,15 @@ static inline int update_task_llc_assignment(struct task_struct *p, struct task_
s32 preferred_cpu)
{
s32 new_llc = choose_task_llc(tctx, preferred_cpu);
int ret;

if (!llc_is_valid(new_llc))
return -EINVAL;

return set_task_llc(p, tctx, (u32)new_llc, true);
ret = set_task_llc(p, tctx, (u32)new_llc, true);
if (ret == -ENOENT)
scx_bpf_error("failed to assign task LLC for cell %u LLC %u", tctx->cell, new_llc);
return ret;
}

static inline int maybe_update_task_llc(struct task_struct *p, struct task_ctx *tctx,
Expand All @@ -510,13 +503,13 @@ static inline int maybe_update_task_llc(struct task_struct *p, struct task_ctx *

if (tctx->llc == new_llc) {
ret = refresh_task_llc_cpumask(tctx, (u32)new_llc);
if (ret && !llc_is_valid(tctx->llc))
return -EINVAL;
return 0;
if (ret == -ENOENT && llc_is_valid(tctx->llc))
return 0;
return ret;
}

ret = set_task_llc(p, tctx, (u32)new_llc, false);
if (ret && llc_is_valid(tctx->llc))
if (ret == -ENOENT && llc_is_valid(tctx->llc))
return 0;
return ret;
}
Loading
Loading