@@ -418,7 +418,7 @@ void scx_idle_update_selcpu_topology(struct sched_ext_ops *ops)
418
418
* NOTE: tasks that can only run on 1 CPU are excluded by this logic, because
419
419
* we never call ops.select_cpu() for them, see select_task_rq().
420
420
*/
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 )
422
422
{
423
423
const struct cpumask * llc_cpus = NULL ;
424
424
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
455
455
* If WAKE_SYNC, try to migrate the wakee to the waker's CPU.
456
456
*/
457
457
if (wake_flags & SCX_WAKE_SYNC ) {
458
- cpu = smp_processor_id () ;
458
+ int waker_node ;
459
459
460
460
/*
461
461
* If the waker's CPU is cache affine and prev_cpu is idle,
462
462
* then avoid a migration.
463
463
*/
464
+ cpu = smp_processor_id ();
464
465
if (cpus_share_cache (cpu , prev_cpu ) &&
465
466
scx_idle_test_and_clear_cpu (prev_cpu )) {
466
467
cpu = prev_cpu ;
@@ -480,9 +481,11 @@ s32 scx_select_cpu_dfl(struct task_struct *p, s32 prev_cpu, u64 wake_flags, bool
480
481
* piled up on it even if there is an idle core elsewhere on
481
482
* the system.
482
483
*/
484
+ waker_node = cpu_to_node (cpu );
483
485
if (!(current -> flags & PF_EXITING ) &&
484
486
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 )) {
486
489
if (cpumask_test_cpu (cpu , p -> cpus_ptr ))
487
490
goto cpu_found ;
488
491
}
@@ -521,15 +524,25 @@ s32 scx_select_cpu_dfl(struct task_struct *p, s32 prev_cpu, u64 wake_flags, bool
521
524
}
522
525
523
526
/*
524
- * Search for any full idle core usable by the task.
527
+ * Search for any full- idle core usable by the task.
525
528
*
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
527
531
* begin in prev_cpu's node and proceed to other nodes in
528
532
* order of increasing distance.
529
533
*/
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 );
531
535
if (cpu >= 0 )
532
536
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
+ }
533
546
}
534
547
535
548
/*
@@ -560,18 +573,24 @@ s32 scx_select_cpu_dfl(struct task_struct *p, s32 prev_cpu, u64 wake_flags, bool
560
573
561
574
/*
562
575
* 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.
563
581
*/
564
- cpu = scx_pick_idle_cpu (p -> cpus_ptr , node , 0 );
582
+ cpu = scx_pick_idle_cpu (p -> cpus_ptr , node , flags );
565
583
if (cpu >= 0 )
566
584
goto cpu_found ;
567
585
568
- rcu_read_unlock () ;
569
- return prev_cpu ;
586
+ cpu = prev_cpu ;
587
+ goto out_unlock ;
570
588
571
589
cpu_found :
590
+ * found = true;
591
+ out_unlock :
572
592
rcu_read_unlock ();
573
593
574
- * found = true;
575
594
return cpu ;
576
595
}
577
596
@@ -810,7 +829,7 @@ __bpf_kfunc s32 scx_bpf_select_cpu_dfl(struct task_struct *p, s32 prev_cpu,
810
829
goto prev_cpu ;
811
830
812
831
#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 );
814
833
#endif
815
834
816
835
prev_cpu :
0 commit comments