From 70b93ed6417e812df20cd11ad1be35b370a45b54 Mon Sep 17 00:00:00 2001 From: Andrea Righi Date: Tue, 3 Sep 2024 09:54:29 +0200 Subject: [PATCH] scx_bpfland: skip idle CPU selection for tasks with changing affinity When tasks are changing CPU affinity it is pointless to try to find an optimal idle CPU. In this case just skip the the idle CPU selection step and let the task being dispatched to a global DSQ if needed. Signed-off-by: Andrea Righi --- scheds/rust/scx_bpfland/src/bpf/main.bpf.c | 43 ++++++++++++---------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/scheds/rust/scx_bpfland/src/bpf/main.bpf.c b/scheds/rust/scx_bpfland/src/bpf/main.bpf.c index e3e1e22..8ba2e68 100644 --- a/scheds/rust/scx_bpfland/src/bpf/main.bpf.c +++ b/scheds/rust/scx_bpfland/src/bpf/main.bpf.c @@ -525,6 +525,30 @@ static s32 pick_idle_cpu(struct task_struct *p, s32 prev_cpu) if (!turbo) return -ENOENT; + /* + * If the task isn't allowed to use its previously used CPU it means + * that it's rapidly changing affinity. In this case it's pointless to + * find an optimal idle CPU, just return and let the task being + * dispatched to a global DSQ. + */ + if (!bpf_cpumask_test_cpu(prev_cpu, p->cpus_ptr)) + return -ENOENT; + + /* + * For tasks that can run only on a single CPU, we can simply verify if + * their only allowed CPU is still idle. + * + * Moreover, if local_kthreads is enabled, always allow to dispatch + * per-CPU kthreads directly to their target CPU, independently on the + * idle state. + */ + if (p->nr_cpus_allowed == 1) { + if (is_kthread(p) && local_kthreads || + scx_bpf_test_and_clear_cpu_idle(prev_cpu)) + return prev_cpu; + return -ENOENT; + } + /* * Acquire the CPU masks to determine the online and idle CPUs in the * system. @@ -533,25 +557,6 @@ static s32 pick_idle_cpu(struct task_struct *p, s32 prev_cpu) idle_smtmask = scx_bpf_get_idle_smtmask(); idle_cpumask = scx_bpf_get_idle_cpumask(); - /* - * For tasks that can run only on a single CPU, we can simply verify if - * their only allowed CPU is still usable, online and idle. - * - * Moreover, if local_kthreads is enabled, always dispatch per-CPU - * kthreads directly to their target CPU, independently on its idle - * state. - */ - if (p->nr_cpus_allowed == 1) { - if (bpf_cpumask_test_cpu(prev_cpu, p->cpus_ptr) && - bpf_cpumask_test_cpu(prev_cpu, online_cpumask) && - (is_kthread(p) && local_kthreads || - scx_bpf_test_and_clear_cpu_idle(prev_cpu))) - cpu = prev_cpu; - else - cpu = -ENOENT; - goto out_put_cpumask; - } - /* * Scheduling domains of the previously used CPU. */