sched/fair: Add comments to explain select_idle_sibling()
PATCH 1/1 sched/fair: Add comments to explain select_idle_sibling()
It's not entirely obvious how the main loop in select_idle_sibling() works on first glance. Sprinkle a few comments to explain the design and intention behind the loop based on some conversations with Mike and Peter.
Cc Mike Galbraith <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc Mel Gorman <[email protected]>
Signed-off-by Matt Fleming <[email protected]>
--- kernel/sched/fair.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)
kernel/sched/fair.c +18 -1
@@ -4971,7 +4971,19 @@ static int select_idle_sibling(struct task_struct *p, int target)return i;/* -* Otherwise, iterate the domains and find an elegible idle cpu. +* Otherwise, iterate the domains and find an eligible idle cpu. +* +* A completely idle sched group at higher domains is more +* desirable than an idle group at a lower level, because lower +* domains have smaller groups and usually share hardware +* resources which causes tasks to contend on them, e.g. x86 +* hyperthread siblings in the lowest domain (SMT) can contend +* on the shared cpu pipeline. +* +* However, while we prefer idle groups at higher domains +* finding an idle cpu at the lowest domain is still better than +* returning 'target', which we've already established, isn't +* idle. */ sd =rcu_dereference (per_cpu (sd_llc, target));for_each_lower_domain (sd) {
@@ -4981,11 +4993,16 @@ static int select_idle_sibling(struct task_struct *p, int target) tsk_cpus_allowed(p))) goto next; +/* Ensure the entire group is idle */ for_each_cpu (i,sched_group_cpus (sg)) {if (i == target || !idle_cpu (i)) goto next; } +/* +* It doesn't matter which cpu we pick, the +* whole group is idle. +*/ target =cpumask_first_and (sched_group_cpus (sg),tsk_cpus_allowed (p)); goto done;
Signature · 1 line
2.6.2
tip-bot for Matt Fleming
merge botsched/fair: Add comments to explain select_idle_sibling()
Commit-ID: d4335581dc30ec6545999c7443bb9fead274a980 Gitweb: http://git.kernel.org/tip/d4335581dc30ec6545999c7443bb9fead274a980 Author: Matt Fleming <[email protected]> AuthorDate: Wed, 9 Mar 2016 14:59:08 +0000 Committer: Ingo Molnar <[email protected]> CommitDate: Mon, 21 Mar 2016 10:52:51 +0100
sched/fair: Add comments to explain select_idle_sibling()
It's not entirely obvious how the main loop in select_idle_sibling() works on first glance. Sprinkle a few comments to explain the design and intention behind the loop based on some conversations with Mike and Peter.
Signed-off-by Matt Fleming <[email protected]>
Signed-off-by Peter Zijlstra (Intel) <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Mel Gorman <[email protected]>
Cc Mike Galbraith <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
Signed-off-by Ingo Molnar <[email protected]>
--- kernel/sched/fair.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)
kernel/sched/fair.c +18 -1
@@ -5055,7 +5055,19 @@ static int select_idle_sibling(struct task_struct *p, int target)return i;/* -* Otherwise, iterate the domains and find an elegible idle cpu. +* Otherwise, iterate the domains and find an eligible idle cpu. +* +* A completely idle sched group at higher domains is more +* desirable than an idle group at a lower level, because lower +* domains have smaller groups and usually share hardware +* resources which causes tasks to contend on them, e.g. x86 +* hyperthread siblings in the lowest domain (SMT) can contend +* on the shared cpu pipeline. +* +* However, while we prefer idle groups at higher domains +* finding an idle cpu at the lowest domain is still better than +* returning 'target', which we've already established, isn't +* idle. */ sd =rcu_dereference (per_cpu (sd_llc, target));for_each_lower_domain (sd) {
@@ -5065,11 +5077,16 @@ static int select_idle_sibling(struct task_struct *p, int target) tsk_cpus_allowed(p))) goto next; +/* Ensure the entire group is idle */ for_each_cpu (i,sched_group_cpus (sg)) {if (i == target || !idle_cpu (i)) goto next; } +/* +* It doesn't matter which cpu we pick, the +* whole group is idle. +*/ target =cpumask_first_and (sched_group_cpus (sg),tsk_cpus_allowed (p)); goto done;