Merge pull request #535 from sched-ext/bpfland-time-slice-control

scx_bpfland: better time slice control
This commit is contained in:
Andrea Righi 2024-08-22 10:32:16 +02:00 committed by GitHub
commit dca4af151e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -413,7 +413,6 @@ static u64 cpu_to_dsq(s32 cpu)
static int dispatch_direct_cpu(struct task_struct *p, s32 cpu, u64 enq_flags)
{
struct bpf_cpumask *offline;
u64 slice = task_slice(p);
u64 vtime = task_vtime(p);
u64 dsq_id = cpu_to_dsq(cpu);
@ -424,7 +423,7 @@ static int dispatch_direct_cpu(struct task_struct *p, s32 cpu, u64 enq_flags)
if (!bpf_cpumask_test_cpu(cpu, p->cpus_ptr))
return -EINVAL;
scx_bpf_dispatch_vtime(p, dsq_id, slice, vtime, enq_flags);
scx_bpf_dispatch_vtime(p, dsq_id, SCX_SLICE_DFL, vtime, enq_flags);
/*
* If the CPU has gone offline notify that the task needs to be
@ -725,7 +724,6 @@ static void handle_sync_wakeup(struct task_struct *p)
void BPF_STRUCT_OPS(bpfland_enqueue, struct task_struct *p, u64 enq_flags)
{
u64 vtime = task_vtime(p);
u64 slice = task_slice(p);
/*
* If the system is saturated and we couldn't dispatch directly in
@ -757,10 +755,12 @@ void BPF_STRUCT_OPS(bpfland_enqueue, struct task_struct *p, u64 enq_flags)
* and simply rely on the vruntime logic.
*/
if (is_task_interactive(p)) {
scx_bpf_dispatch_vtime(p, prio_dsq_id, slice, vtime, enq_flags);
scx_bpf_dispatch_vtime(p, prio_dsq_id, SCX_SLICE_DFL,
vtime, enq_flags);
__sync_fetch_and_add(&nr_prio_dispatches, 1);
} else {
scx_bpf_dispatch_vtime(p, shared_dsq_id, slice, vtime, enq_flags);
scx_bpf_dispatch_vtime(p, shared_dsq_id, SCX_SLICE_DFL,
vtime, enq_flags);
__sync_fetch_and_add(&nr_shared_dispatches, 1);
}
}
@ -903,7 +903,22 @@ void BPF_STRUCT_OPS(bpfland_dispatch, s32 cpu, struct task_struct *prev)
/*
* Lastly, consume regular tasks from the shared DSQ.
*/
consume_regular_task(now);
if (consume_regular_task(now))
return;
/*
* If the current task expired its time slice, but no other task wants
* to run, simply replenish its time slice and let it run for another
* round on the same CPU.
*
* Note that bpfland_stopping() won't be called if we replenish the
* time slice here. As a result, the nvcsw statistics won't be updated,
* but this isn't an issue, because these statistics are only relevant
* when the system is overloaded, which isn't the case when there are
* no other tasks to run.
*/
if (prev && (prev->scx.flags & SCX_TASK_QUEUED))
prev->scx.slice = task_slice(prev);
}
void BPF_STRUCT_OPS(bpfland_running, struct task_struct *p)
@ -913,11 +928,10 @@ void BPF_STRUCT_OPS(bpfland_running, struct task_struct *p)
vtime_now = p->scx.dsq_vtime;
/*
* Ensure time slice never exceeds slice_ns when a task is started on a
* CPU.
* Refresh task's time slice immediately before it starts to run on its
* assigned CPU.
*/
if (p->scx.slice > slice_ns)
p->scx.slice = slice_ns;
p->scx.slice = task_slice(p);
/* Update CPU interactive state */
if (is_task_interactive(p))