Skip to content

Commit

Permalink
scx_rustland: use scx_bpf_dispatch_cancel()
Browse files Browse the repository at this point in the history
Use scx_bpf_dispatch_cancel() to invalidate dispatches on wrong per-CPU
DSQ, due to cpumask race conditions.

This prevents dispatching tasks to CPU that cannot be used according to
the task's cpumask.

With this applied the scheduler passed all the `stress-ng --race-sched`
stress tests.

Link: sched-ext/sched_ext#135
Signed-off-by: Andrea Righi <[email protected]>
  • Loading branch information
Andrea Righi committed Feb 8, 2024
1 parent 13e23e8 commit 6ec074f
Showing 1 changed file with 15 additions and 4 deletions.
19 changes: 15 additions & 4 deletions scheds/rust/scx_rustland/src/bpf/main.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,9 @@ static void dispatch_task(struct task_struct *p, u64 dsq_id, u64 enq_flags)
switch (dsq_id) {
case SCX_DSQ_LOCAL:
case SHARED_DSQ:
scx_bpf_dispatch(p, dsq_id, slice, enq_flags);
dbg_msg("dispatch: pid=%d (%s) dsq=%llu",
p->pid, p->comm, dsq_id);
break;
default:
/*
Expand All @@ -311,18 +314,26 @@ static void dispatch_task(struct task_struct *p, u64 dsq_id, u64 enq_flags)
* in the meantime), we can simply ignore the task, as it has
* been dequeued and re-enqueued, so it will pick a valid CPU.
*/
scx_bpf_dispatch(p, dsq_id, slice, enq_flags);

cpu = dsq_to_cpu(dsq_id);
if (!bpf_cpumask_test_cpu(cpu, p->cpus_ptr)) {
cpu = scx_bpf_task_cpu(p);
if (!bpf_cpumask_test_cpu(cpu, p->cpus_ptr))
return;
dsq_id = dsq_to_cpu(cpu);
dsq_id = SHARED_DSQ;
else
dsq_id = cpu_to_dsq(cpu);

scx_bpf_dispatch_cancel();
scx_bpf_dispatch(p, dsq_id, slice, enq_flags);
}
dbg_msg("dispatch: pid=%d (%s) dsq=%llu",
p->pid, p->comm, dsq_id);

/* Wake up the target CPU (only if idle) */
__COMPAT_scx_bpf_kick_cpu_IDLE(cpu);
break;
}
dbg_msg("dispatch: pid=%d (%s) dsq=%llu", p->pid, p->comm, dsq_id);
scx_bpf_dispatch(p, dsq_id, slice, enq_flags);
}

/*
Expand Down

0 comments on commit 6ec074f

Please sign in to comment.