scx_lavd: fix potential CPU stall in lavd_select_cpu()

Returning prev_cpu after picking an idle CPU will cause the idle CPU
stall because the idle core was already punched out from the idle mask
by the scx core so it is no longer idle from the scx core's point of
view.

This fix conducts the idle core selection at the last step so it never
return prev_cpu after picking the idle core.

Signed-off-by: Changwoo Min <changwoo@igalia.com>
This commit is contained in:
Changwoo Min 2024-03-19 00:17:28 +09:00
parent e41c674fae
commit 512c4e794f

View File

@ -388,11 +388,6 @@ static const u64 lat_prio_to_greedy_thresholds[NICE_WIDTH] = {
static u16 get_nice_prio(struct task_struct *p);
static u64 get_task_load_ideal(struct task_struct *p);
static bool put_local_rq(struct task_struct *p, struct task_ctx *taskc,
u64 enq_flags);
static bool put_global_rq(struct task_struct *p, struct task_ctx *taskc,
u64 enq_flags);
static inline __attribute__((always_inline)) u32 bpf_log2(u32 v)
{
u32 r;
@ -1357,9 +1352,12 @@ s32 BPF_STRUCT_OPS(lavd_select_cpu, struct task_struct *p, s32 prev_cpu,
* CPU. If the task is directly dispatched here, the sched_ext won't
* call ops.enqueue().
*/
cpu_id = scx_bpf_select_cpu_dfl(p, prev_cpu, wake_flags, &found_idle);
if (!is_wakeup_wf(wake_flags)) {
cpu_id = scx_bpf_select_cpu_dfl(p, prev_cpu, wake_flags,
&found_idle);
return found_idle ? cpu_id : prev_cpu;
}
if (found_idle && is_wakeup_wf(wake_flags)) {
struct task_ctx *taskc = get_task_ctx(p);
if (!taskc)
return prev_cpu;
@ -1372,9 +1370,15 @@ s32 BPF_STRUCT_OPS(lavd_select_cpu, struct task_struct *p, s32 prev_cpu,
*/
return prev_cpu;
}
}
return cpu_id;
/*
* Note that once an idle CPU is successfully picked (i.e., found_idle
* == true), then the picked CPU must be returned. Otherwise, that CPU
* is stalled because the picked CPU is already punched out from the
* idle mask.
*/
cpu_id = scx_bpf_select_cpu_dfl(p, prev_cpu, wake_flags, &found_idle);
return found_idle ? cpu_id : prev_cpu;
}
void BPF_STRUCT_OPS(lavd_enqueue, struct task_struct *p, u64 enq_flags)