@@ -418,7 +418,7 @@ void scx_idle_update_selcpu_topology(struct sched_ext_ops *ops)
418418 * NOTE: tasks that can only run on 1 CPU are excluded by this logic, because
419419 * we never call ops.select_cpu() for them, see select_task_rq().
420420 */
421- s32 scx_select_cpu_dfl (struct task_struct * p , s32 prev_cpu , u64 wake_flags , bool * found )
421+ s32 scx_select_cpu_dfl (struct task_struct * p , s32 prev_cpu , u64 wake_flags , u64 flags , bool * found )
422422{
423423 const struct cpumask * llc_cpus = NULL ;
424424 const struct cpumask * numa_cpus = NULL ;
@@ -455,12 +455,13 @@ s32 scx_select_cpu_dfl(struct task_struct *p, s32 prev_cpu, u64 wake_flags, bool
455455 * If WAKE_SYNC, try to migrate the wakee to the waker's CPU.
456456 */
457457 if (wake_flags & SCX_WAKE_SYNC ) {
458- cpu = smp_processor_id () ;
458+ int waker_node ;
459459
460460 /*
461461 * If the waker's CPU is cache affine and prev_cpu is idle,
462462 * then avoid a migration.
463463 */
464+ cpu = smp_processor_id ();
464465 if (cpus_share_cache (cpu , prev_cpu ) &&
465466 scx_idle_test_and_clear_cpu (prev_cpu )) {
466467 cpu = prev_cpu ;
@@ -480,9 +481,11 @@ s32 scx_select_cpu_dfl(struct task_struct *p, s32 prev_cpu, u64 wake_flags, bool
480481 * piled up on it even if there is an idle core elsewhere on
481482 * the system.
482483 */
484+ waker_node = cpu_to_node (cpu );
483485 if (!(current -> flags & PF_EXITING ) &&
484486 cpu_rq (cpu )-> scx .local_dsq .nr == 0 &&
485- !cpumask_empty (idle_cpumask (cpu_to_node (cpu ))-> cpu )) {
487+ (!(flags & SCX_PICK_IDLE_IN_NODE ) || (waker_node == node )) &&
488+ !cpumask_empty (idle_cpumask (waker_node )-> cpu )) {
486489 if (cpumask_test_cpu (cpu , p -> cpus_ptr ))
487490 goto cpu_found ;
488491 }
@@ -521,15 +524,25 @@ s32 scx_select_cpu_dfl(struct task_struct *p, s32 prev_cpu, u64 wake_flags, bool
521524 }
522525
523526 /*
524- * Search for any full idle core usable by the task.
527+ * Search for any full- idle core usable by the task.
525528 *
526- * If NUMA aware idle selection is enabled, the search will
529+ * If the node-aware idle CPU selection policy is enabled
530+ * (%SCX_OPS_BUILTIN_IDLE_PER_NODE), the search will always
527531 * begin in prev_cpu's node and proceed to other nodes in
528532 * order of increasing distance.
529533 */
530- cpu = scx_pick_idle_cpu (p -> cpus_ptr , node , SCX_PICK_IDLE_CORE );
534+ cpu = scx_pick_idle_cpu (p -> cpus_ptr , node , flags | SCX_PICK_IDLE_CORE );
531535 if (cpu >= 0 )
532536 goto cpu_found ;
537+
538+ /*
539+ * Give up if we're strictly looking for a full-idle SMT
540+ * core.
541+ */
542+ if (flags & SCX_PICK_IDLE_CORE ) {
543+ cpu = prev_cpu ;
544+ goto out_unlock ;
545+ }
533546 }
534547
535548 /*
@@ -560,18 +573,24 @@ s32 scx_select_cpu_dfl(struct task_struct *p, s32 prev_cpu, u64 wake_flags, bool
560573
561574 /*
562575 * Search for any idle CPU usable by the task.
576+ *
577+ * If the node-aware idle CPU selection policy is enabled
578+ * (%SCX_OPS_BUILTIN_IDLE_PER_NODE), the search will always begin
579+ * in prev_cpu's node and proceed to other nodes in order of
580+ * increasing distance.
563581 */
564- cpu = scx_pick_idle_cpu (p -> cpus_ptr , node , 0 );
582+ cpu = scx_pick_idle_cpu (p -> cpus_ptr , node , flags );
565583 if (cpu >= 0 )
566584 goto cpu_found ;
567585
568- rcu_read_unlock () ;
569- return prev_cpu ;
586+ cpu = prev_cpu ;
587+ goto out_unlock ;
570588
571589cpu_found :
590+ * found = true;
591+ out_unlock :
572592 rcu_read_unlock ();
573593
574- * found = true;
575594 return cpu ;
576595}
577596
@@ -810,7 +829,7 @@ __bpf_kfunc s32 scx_bpf_select_cpu_dfl(struct task_struct *p, s32 prev_cpu,
810829 goto prev_cpu ;
811830
812831#ifdef CONFIG_SMP
813- return scx_select_cpu_dfl (p , prev_cpu , wake_flags , is_idle );
832+ return scx_select_cpu_dfl (p , prev_cpu , wake_flags , 0 , is_idle );
814833#endif
815834
816835prev_cpu :
0 commit comments