Skip to content

Commit b9a7b88

Browse files
Valentin SchneiderIngo Molnar
authored andcommitted
sched/fair: Skip LLC NOHZ logic for asymmetric systems
The LLC NOHZ condition will become true as soon as >=2 CPUs in a single LLC domain are busy. On big.LITTLE systems, this translates to two or more CPUs of a "cluster" (big or LITTLE) being busy. Issuing a NOHZ kick in these conditions isn't desired for asymmetric systems, as if the busy CPUs can provide enough compute capacity to the running tasks, then we can leave the NOHZ CPUs in peace. Skip the LLC NOHZ condition for asymmetric systems, and rely on nr_running & capacity checks to trigger NOHZ kicks when the system actually needs them. Suggested-by: Morten Rasmussen <[email protected]> Signed-off-by: Valentin Schneider <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Dave Hansen <[email protected]> Cc: [email protected] Cc: H. Peter Anvin <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Rik van Riel <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: [email protected] Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent a0fe2cf commit b9a7b88

File tree

1 file changed

+37
-28
lines changed

1 file changed

+37
-28
lines changed

kernel/sched/fair.c

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9603,24 +9603,6 @@ static void nohz_balancer_kick(struct rq *rq)
96039603
}
96049604

96059605
rcu_read_lock();
9606-
sds = rcu_dereference(per_cpu(sd_llc_shared, cpu));
9607-
if (sds) {
9608-
/*
9609-
* If there is an imbalance between LLC domains (IOW we could
9610-
* increase the overall cache use), we need some less-loaded LLC
9611-
* domain to pull some load. Likewise, we may need to spread
9612-
* load within the current LLC domain (e.g. packed SMT cores but
9613-
* other CPUs are idle). We can't really know from here how busy
9614-
* the others are - so just get a nohz balance going if it looks
9615-
* like this LLC domain has tasks we could move.
9616-
*/
9617-
nr_busy = atomic_read(&sds->nr_busy_cpus);
9618-
if (nr_busy > 1) {
9619-
flags = NOHZ_KICK_MASK;
9620-
goto unlock;
9621-
}
9622-
9623-
}
96249606

96259607
sd = rcu_dereference(rq->sd);
96269608
if (sd) {
@@ -9635,6 +9617,21 @@ static void nohz_balancer_kick(struct rq *rq)
96359617
}
96369618
}
96379619

9620+
sd = rcu_dereference(per_cpu(sd_asym_packing, cpu));
9621+
if (sd) {
9622+
/*
9623+
* When ASYM_PACKING; see if there's a more preferred CPU
9624+
* currently idle; in which case, kick the ILB to move tasks
9625+
* around.
9626+
*/
9627+
for_each_cpu_and(i, sched_domain_span(sd), nohz.idle_cpus_mask) {
9628+
if (sched_asym_prefer(i, cpu)) {
9629+
flags = NOHZ_KICK_MASK;
9630+
goto unlock;
9631+
}
9632+
}
9633+
}
9634+
96389635
sd = rcu_dereference(per_cpu(sd_asym_cpucapacity, cpu));
96399636
if (sd) {
96409637
/*
@@ -9645,20 +9642,32 @@ static void nohz_balancer_kick(struct rq *rq)
96459642
flags = NOHZ_KICK_MASK;
96469643
goto unlock;
96479644
}
9645+
9646+
/*
9647+
* For asymmetric systems, we do not want to nicely balance
9648+
* cache use, instead we want to embrace asymmetry and only
9649+
* ensure tasks have enough CPU capacity.
9650+
*
9651+
* Skip the LLC logic because it's not relevant in that case.
9652+
*/
9653+
goto unlock;
96489654
}
96499655

9650-
sd = rcu_dereference(per_cpu(sd_asym_packing, cpu));
9651-
if (sd) {
9656+
sds = rcu_dereference(per_cpu(sd_llc_shared, cpu));
9657+
if (sds) {
96529658
/*
9653-
* When ASYM_PACKING; see if there's a more preferred CPU
9654-
* currently idle; in which case, kick the ILB to move tasks
9655-
* around.
9659+
* If there is an imbalance between LLC domains (IOW we could
9660+
* increase the overall cache use), we need some less-loaded LLC
9661+
* domain to pull some load. Likewise, we may need to spread
9662+
* load within the current LLC domain (e.g. packed SMT cores but
9663+
* other CPUs are idle). We can't really know from here how busy
9664+
* the others are - so just get a nohz balance going if it looks
9665+
* like this LLC domain has tasks we could move.
96569666
*/
9657-
for_each_cpu_and(i, sched_domain_span(sd), nohz.idle_cpus_mask) {
9658-
if (sched_asym_prefer(i, cpu)) {
9659-
flags = NOHZ_KICK_MASK;
9660-
goto unlock;
9661-
}
9667+
nr_busy = atomic_read(&sds->nr_busy_cpus);
9668+
if (nr_busy > 1) {
9669+
flags = NOHZ_KICK_MASK;
9670+
goto unlock;
96629671
}
96639672
}
96649673
unlock:

0 commit comments

Comments
 (0)