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/fair: Remove superfluous rcu_read_lock() in the wakeup path

select_task_rq_fair() is always called with p->pi_lock held and IRQs
disabled which makes it equivalent of an RCU read-side.

Since commit 71fedc41c23b ("sched/fair: Switch to
rcu_dereference_all()") switched to using rcu_dereference_all() in the
wakeup path, drop the explicit rcu_read_{lock,unlock}() in the fair
task's wakeup path.

Future plans to reuse select_task_rq_fair() /
find_energy_efficient_cpu() in the fair class' balance callback will do
so with IRQs disabled and will comply with the requirements of
rcu_dereference_all() which makes this safe keeping in mind future
development plans too.

Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
Tested-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
Link: https://patch.msgid.link/20260312044434.1974-8-kprateek.nayak@amd.com

authored by

K Prateek Nayak and committed by
Peter Zijlstra
fa6874df 8ca12326

+12 -21
+12 -21
kernel/sched/fair.c
··· 8570 8570 struct perf_domain *pd; 8571 8571 struct energy_env eenv; 8572 8572 8573 - rcu_read_lock(); 8574 8573 pd = rcu_dereference_all(rd->pd); 8575 8574 if (!pd) 8576 - goto unlock; 8575 + return target; 8577 8576 8578 8577 /* 8579 8578 * Energy-aware wake-up happens on the lowest sched_domain starting ··· 8582 8583 while (sd && !cpumask_test_cpu(prev_cpu, sched_domain_span(sd))) 8583 8584 sd = sd->parent; 8584 8585 if (!sd) 8585 - goto unlock; 8586 + return target; 8586 8587 8587 8588 target = prev_cpu; 8588 8589 8589 8590 sync_entity_load_avg(&p->se); 8590 8591 if (!task_util_est(p) && p_util_min == 0) 8591 - goto unlock; 8592 + return target; 8592 8593 8593 8594 eenv_task_busy_time(&eenv, p, prev_cpu); 8594 8595 ··· 8683 8684 prev_cpu); 8684 8685 /* CPU utilization has changed */ 8685 8686 if (prev_delta < base_energy) 8686 - goto unlock; 8687 + return target; 8687 8688 prev_delta -= base_energy; 8688 8689 prev_actual_cap = cpu_actual_cap; 8689 8690 best_delta = min(best_delta, prev_delta); ··· 8707 8708 max_spare_cap_cpu); 8708 8709 /* CPU utilization has changed */ 8709 8710 if (cur_delta < base_energy) 8710 - goto unlock; 8711 + return target; 8711 8712 cur_delta -= base_energy; 8712 8713 8713 8714 /* ··· 8724 8725 best_actual_cap = cpu_actual_cap; 8725 8726 } 8726 8727 } 8727 - rcu_read_unlock(); 8728 8728 8729 8729 if ((best_fits > prev_fits) || 8730 8730 ((best_fits > 0) && (best_delta < prev_delta)) || 8731 8731 ((best_fits < 0) && (best_actual_cap > prev_actual_cap))) 8732 8732 target = best_energy_cpu; 8733 - 8734 - return target; 8735 - 8736 - unlock: 8737 - rcu_read_unlock(); 8738 8733 8739 8734 return target; 8740 8735 } ··· 8775 8782 want_affine = !wake_wide(p) && cpumask_test_cpu(cpu, p->cpus_ptr); 8776 8783 } 8777 8784 8778 - rcu_read_lock(); 8779 8785 for_each_domain(cpu, tmp) { 8780 8786 /* 8781 8787 * If both 'cpu' and 'prev_cpu' are part of this domain, ··· 8800 8808 break; 8801 8809 } 8802 8810 8803 - if (unlikely(sd)) { 8804 - /* Slow path */ 8805 - new_cpu = sched_balance_find_dst_cpu(sd, p, cpu, prev_cpu, sd_flag); 8806 - } else if (wake_flags & WF_TTWU) { /* XXX always ? */ 8807 - /* Fast path */ 8808 - new_cpu = select_idle_sibling(p, prev_cpu, new_cpu); 8809 - } 8810 - rcu_read_unlock(); 8811 + /* Slow path */ 8812 + if (unlikely(sd)) 8813 + return sched_balance_find_dst_cpu(sd, p, cpu, prev_cpu, sd_flag); 8814 + 8815 + /* Fast path */ 8816 + if (wake_flags & WF_TTWU) 8817 + return select_idle_sibling(p, prev_cpu, new_cpu); 8811 8818 8812 8819 return new_cpu; 8813 8820 }