aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cpuset.c
diff options
context:
space:
mode:
authorLai Jiangshan <laijs@cn.fujitsu.com>2008-07-30 01:33:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-30 12:41:44 -0400
commitf5393693e96393131a4a2e2743f883986d508503 (patch)
tree91c6b0687939b9361c8cdcebb05494f1d0524f72 /kernel/cpuset.c
parent8d1e6266f512b3a94ef6d33528ff385f1aea0392 (diff)
cpuset: speed up sched domain partition
All child cpusets contain a subset of the parent's cpus, so we can skip them when partitioning sched domains. This decreases 'csa' greately for cpusets with multi-level hierarchy. Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> Signed-off-by: Li Zefan <lizf@cn.fujitsu.com> Cc: Paul Menage <menage@google.com> Cc: Cedric Le Goater <clg@fr.ibm.com> Cc: Balbir Singh <balbir@in.ibm.com> Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Reviewed-by: Paul Jackson <pj@sgi.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/cpuset.c')
-rw-r--r--kernel/cpuset.c41
1 files changed, 37 insertions, 4 deletions
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 3624dc0e95ed..c818c36b0c5f 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -486,13 +486,38 @@ static int cpusets_overlap(struct cpuset *a, struct cpuset *b)
486static void 486static void
487update_domain_attr(struct sched_domain_attr *dattr, struct cpuset *c) 487update_domain_attr(struct sched_domain_attr *dattr, struct cpuset *c)
488{ 488{
489 if (!dattr)
490 return;
491 if (dattr->relax_domain_level < c->relax_domain_level) 489 if (dattr->relax_domain_level < c->relax_domain_level)
492 dattr->relax_domain_level = c->relax_domain_level; 490 dattr->relax_domain_level = c->relax_domain_level;
493 return; 491 return;
494} 492}
495 493
494static void
495update_domain_attr_tree(struct sched_domain_attr *dattr, struct cpuset *c)
496{
497 LIST_HEAD(q);
498
499 list_add(&c->stack_list, &q);
500 while (!list_empty(&q)) {
501 struct cpuset *cp;
502 struct cgroup *cont;
503 struct cpuset *child;
504
505 cp = list_first_entry(&q, struct cpuset, stack_list);
506 list_del(q.next);
507
508 if (cpus_empty(cp->cpus_allowed))
509 continue;
510
511 if (is_sched_load_balance(cp))
512 update_domain_attr(dattr, cp);
513
514 list_for_each_entry(cont, &cp->css.cgroup->children, sibling) {
515 child = cgroup_cs(cont);
516 list_add_tail(&child->stack_list, &q);
517 }
518 }
519}
520
496/* 521/*
497 * rebuild_sched_domains() 522 * rebuild_sched_domains()
498 * 523 *
@@ -614,8 +639,16 @@ void rebuild_sched_domains(void)
614 if (cpus_empty(cp->cpus_allowed)) 639 if (cpus_empty(cp->cpus_allowed))
615 continue; 640 continue;
616 641
617 if (is_sched_load_balance(cp)) 642 /*
643 * All child cpusets contain a subset of the parent's cpus, so
644 * just skip them, and then we call update_domain_attr_tree()
645 * to calc relax_domain_level of the corresponding sched
646 * domain.
647 */
648 if (is_sched_load_balance(cp)) {
618 csa[csn++] = cp; 649 csa[csn++] = cp;
650 continue;
651 }
619 652
620 list_for_each_entry(cont, &cp->css.cgroup->children, sibling) { 653 list_for_each_entry(cont, &cp->css.cgroup->children, sibling) {
621 child = cgroup_cs(cont); 654 child = cgroup_cs(cont);
@@ -686,7 +719,7 @@ restart:
686 cpus_or(*dp, *dp, b->cpus_allowed); 719 cpus_or(*dp, *dp, b->cpus_allowed);
687 b->pn = -1; 720 b->pn = -1;
688 if (dattr) 721 if (dattr)
689 update_domain_attr(dattr 722 update_domain_attr_tree(dattr
690 + nslot, b); 723 + nslot, b);
691 } 724 }
692 } 725 }