Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

sched_ext: Make task_can_run_on_remote_rq() use common task_allowed_on_cpu()

task_can_run_on_remote_rq() is similar to is_cpu_allowed() but there are
subtle differences. It currently open codes all the tests. This is
cumbersome to understand and error-prone in case the intersecting tests need
to be updated.

Factor out the common part - testing whether the task is allowed on the CPU
at all regardless of the CPU state - into task_allowed_on_cpu() and make
both is_cpu_allowed() and SCX's task_can_run_on_remote_rq() use it. As the
code is now linked between the two and each contains only the extra tests
that differ between them, it's less error-prone when the conditions need to
be updated. Also, improve the comment to explain why they are different.

v2: Replace accidental "extern inline" with "static inline" (Peter).

Signed-off-by: Tejun Heo <tj@kernel.org>
Suggested-by: Peter Zijlstra <peterz@infradead.org>
Acked-by: David Vernet <void@manifault.com>

+36 -7
+2 -2
kernel/sched/core.c
··· 2342 2342 static inline bool is_cpu_allowed(struct task_struct *p, int cpu) 2343 2343 { 2344 2344 /* When not in the task's cpumask, no point in looking further. */ 2345 - if (!cpumask_test_cpu(cpu, p->cpus_ptr)) 2345 + if (!task_allowed_on_cpu(p, cpu)) 2346 2346 return false; 2347 2347 2348 2348 /* migrate_disabled() must be allowed to finish. */ ··· 2351 2351 2352 2352 /* Non kernel threads are not allowed during either online or offline. */ 2353 2353 if (!(p->flags & PF_KTHREAD)) 2354 - return cpu_active(cpu) && task_cpu_possible(cpu, p); 2354 + return cpu_active(cpu); 2355 2355 2356 2356 /* KTHREAD_IS_PER_CPU is always allowed. */ 2357 2357 if (kthread_is_per_cpu(p))
+16 -5
kernel/sched/ext.c
··· 2224 2224 2225 2225 #ifdef CONFIG_SMP 2226 2226 /* 2227 - * Similar to kernel/sched/core.c::is_cpu_allowed() but we're testing whether @p 2228 - * can be pulled to @rq. 2227 + * Similar to kernel/sched/core.c::is_cpu_allowed(). However, there are two 2228 + * differences: 2229 + * 2230 + * - is_cpu_allowed() asks "Can this task run on this CPU?" while 2231 + * task_can_run_on_remote_rq() asks "Can the BPF scheduler migrate the task to 2232 + * this CPU?". 2233 + * 2234 + * While migration is disabled, is_cpu_allowed() has to say "yes" as the task 2235 + * must be allowed to finish on the CPU that it's currently on regardless of 2236 + * the CPU state. However, task_can_run_on_remote_rq() must say "no" as the 2237 + * BPF scheduler shouldn't attempt to migrate a task which has migration 2238 + * disabled. 2239 + * 2240 + * - The BPF scheduler is bypassed while the rq is offline and we can always say 2241 + * no to the BPF scheduler initiated migrations while offline. 2229 2242 */ 2230 2243 static bool task_can_run_on_remote_rq(struct task_struct *p, struct rq *rq) 2231 2244 { 2232 2245 int cpu = cpu_of(rq); 2233 2246 2234 - if (!cpumask_test_cpu(cpu, p->cpus_ptr)) 2247 + if (!task_allowed_on_cpu(p, cpu)) 2235 2248 return false; 2236 2249 if (unlikely(is_migration_disabled(p))) 2237 - return false; 2238 - if (!(p->flags & PF_KTHREAD) && unlikely(!task_cpu_possible(cpu, p))) 2239 2250 return false; 2240 2251 if (!scx_rq_online(rq)) 2241 2252 return false;
+18
kernel/sched/sched.h
··· 2534 2534 extern int __set_cpus_allowed_ptr(struct task_struct *p, struct affinity_context *ctx); 2535 2535 extern void set_cpus_allowed_common(struct task_struct *p, struct affinity_context *ctx); 2536 2536 2537 + static inline bool task_allowed_on_cpu(struct task_struct *p, int cpu) 2538 + { 2539 + /* When not in the task's cpumask, no point in looking further. */ 2540 + if (!cpumask_test_cpu(cpu, p->cpus_ptr)) 2541 + return false; 2542 + 2543 + /* Can @cpu run a user thread? */ 2544 + if (!(p->flags & PF_KTHREAD) && !task_cpu_possible(cpu, p)) 2545 + return false; 2546 + 2547 + return true; 2548 + } 2549 + 2537 2550 static inline cpumask_t *alloc_user_cpus_ptr(int node) 2538 2551 { 2539 2552 /* ··· 2579 2566 extern int push_cpu_stop(void *arg); 2580 2567 2581 2568 #else /* !CONFIG_SMP: */ 2569 + 2570 + static inline bool task_allowed_on_cpu(struct task_struct *p, int cpu) 2571 + { 2572 + return true; 2573 + } 2582 2574 2583 2575 static inline int __set_cpus_allowed_ptr(struct task_struct *p, 2584 2576 struct affinity_context *ctx)