diff options
author | Li Zefan <lizefan@huawei.com> | 2014-07-09 04:47:50 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2014-07-09 15:56:16 -0400 |
commit | 8b5f1c52dcd1accd3a940cfcb148bef6de589524 (patch) | |
tree | 200c279a6b64f4e4ef8f34fdd9f3d4a7cc6b9736 /kernel/cpuset.c | |
parent | 554b0d1c845e42ef01d7f6f5f24b3e4c6129ce8f (diff) |
cpuset: use effective cpumask to build sched domains
We're going to have separate user-configured masks and effective ones.
Eventually configured masks can only be changed by writing cpuset.cpus
and cpuset.mems, and they won't be restricted by parent cpuset. While
effective masks reflect cpu/memory hotplug and hierachical restriction,
and these are the real masks that apply to the tasks in the cpuset.
We calculate effective mask this way:
- top cpuset's effective_mask == online_mask, otherwise
- cpuset's effective_mask == configured_mask & parent effective_mask,
if the result is empty, it inherits parent effective mask.
Those behavior changes are for default hierarchy only. For legacy
hierarchy, effective_mask and configured_mask are the same, so we won't
break old interfaces.
We should partition sched domains according to effective_cpus, which
is the real cpulist that takes effects on tasks in the cpuset.
This won't introduce behavior change.
v2:
- Add a comment for the call of rebuild_sched_domains(), suggested
by Tejun.
Signed-off-by: Li Zefan <lizefan@huawei.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'kernel/cpuset.c')
-rw-r--r-- | kernel/cpuset.c | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index f8340026d01c..60577ccdbfc7 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
@@ -494,11 +494,11 @@ out: | |||
494 | #ifdef CONFIG_SMP | 494 | #ifdef CONFIG_SMP |
495 | /* | 495 | /* |
496 | * Helper routine for generate_sched_domains(). | 496 | * Helper routine for generate_sched_domains(). |
497 | * Do cpusets a, b have overlapping cpus_allowed masks? | 497 | * Do cpusets a, b have overlapping effective cpus_allowed masks? |
498 | */ | 498 | */ |
499 | static int cpusets_overlap(struct cpuset *a, struct cpuset *b) | 499 | static int cpusets_overlap(struct cpuset *a, struct cpuset *b) |
500 | { | 500 | { |
501 | return cpumask_intersects(a->cpus_allowed, b->cpus_allowed); | 501 | return cpumask_intersects(a->effective_cpus, b->effective_cpus); |
502 | } | 502 | } |
503 | 503 | ||
504 | static void | 504 | static void |
@@ -615,7 +615,7 @@ static int generate_sched_domains(cpumask_var_t **domains, | |||
615 | *dattr = SD_ATTR_INIT; | 615 | *dattr = SD_ATTR_INIT; |
616 | update_domain_attr_tree(dattr, &top_cpuset); | 616 | update_domain_attr_tree(dattr, &top_cpuset); |
617 | } | 617 | } |
618 | cpumask_copy(doms[0], top_cpuset.cpus_allowed); | 618 | cpumask_copy(doms[0], top_cpuset.effective_cpus); |
619 | 619 | ||
620 | goto done; | 620 | goto done; |
621 | } | 621 | } |
@@ -719,7 +719,7 @@ restart: | |||
719 | struct cpuset *b = csa[j]; | 719 | struct cpuset *b = csa[j]; |
720 | 720 | ||
721 | if (apn == b->pn) { | 721 | if (apn == b->pn) { |
722 | cpumask_or(dp, dp, b->cpus_allowed); | 722 | cpumask_or(dp, dp, b->effective_cpus); |
723 | if (dattr) | 723 | if (dattr) |
724 | update_domain_attr_tree(dattr + nslot, b); | 724 | update_domain_attr_tree(dattr + nslot, b); |
725 | 725 | ||
@@ -771,7 +771,7 @@ static void rebuild_sched_domains_locked(void) | |||
771 | * passing doms with offlined cpu to partition_sched_domains(). | 771 | * passing doms with offlined cpu to partition_sched_domains(). |
772 | * Anyways, hotplug work item will rebuild sched domains. | 772 | * Anyways, hotplug work item will rebuild sched domains. |
773 | */ | 773 | */ |
774 | if (!cpumask_equal(top_cpuset.cpus_allowed, cpu_active_mask)) | 774 | if (!cpumask_equal(top_cpuset.effective_cpus, cpu_active_mask)) |
775 | goto out; | 775 | goto out; |
776 | 776 | ||
777 | /* Generate domain masks and attrs */ | 777 | /* Generate domain masks and attrs */ |
@@ -870,6 +870,7 @@ static void update_cpumasks_hier(struct cpuset *cs, struct cpumask *new_cpus) | |||
870 | { | 870 | { |
871 | struct cpuset *cp; | 871 | struct cpuset *cp; |
872 | struct cgroup_subsys_state *pos_css; | 872 | struct cgroup_subsys_state *pos_css; |
873 | bool need_rebuild_sched_domains = false; | ||
873 | 874 | ||
874 | rcu_read_lock(); | 875 | rcu_read_lock(); |
875 | cpuset_for_each_descendant_pre(cp, pos_css, cs) { | 876 | cpuset_for_each_descendant_pre(cp, pos_css, cs) { |
@@ -903,10 +904,21 @@ static void update_cpumasks_hier(struct cpuset *cs, struct cpumask *new_cpus) | |||
903 | 904 | ||
904 | update_tasks_cpumask(cp); | 905 | update_tasks_cpumask(cp); |
905 | 906 | ||
907 | /* | ||
908 | * If the effective cpumask of any non-empty cpuset is changed, | ||
909 | * we need to rebuild sched domains. | ||
910 | */ | ||
911 | if (!cpumask_empty(cp->cpus_allowed) && | ||
912 | is_sched_load_balance(cp)) | ||
913 | need_rebuild_sched_domains = true; | ||
914 | |||
906 | rcu_read_lock(); | 915 | rcu_read_lock(); |
907 | css_put(&cp->css); | 916 | css_put(&cp->css); |
908 | } | 917 | } |
909 | rcu_read_unlock(); | 918 | rcu_read_unlock(); |
919 | |||
920 | if (need_rebuild_sched_domains) | ||
921 | rebuild_sched_domains_locked(); | ||
910 | } | 922 | } |
911 | 923 | ||
912 | /** | 924 | /** |
@@ -919,7 +931,6 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs, | |||
919 | const char *buf) | 931 | const char *buf) |
920 | { | 932 | { |
921 | int retval; | 933 | int retval; |
922 | int is_load_balanced; | ||
923 | 934 | ||
924 | /* top_cpuset.cpus_allowed tracks cpu_online_mask; it's read-only */ | 935 | /* top_cpuset.cpus_allowed tracks cpu_online_mask; it's read-only */ |
925 | if (cs == &top_cpuset) | 936 | if (cs == &top_cpuset) |
@@ -950,17 +961,12 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs, | |||
950 | if (retval < 0) | 961 | if (retval < 0) |
951 | return retval; | 962 | return retval; |
952 | 963 | ||
953 | is_load_balanced = is_sched_load_balance(trialcs); | ||
954 | |||
955 | mutex_lock(&callback_mutex); | 964 | mutex_lock(&callback_mutex); |
956 | cpumask_copy(cs->cpus_allowed, trialcs->cpus_allowed); | 965 | cpumask_copy(cs->cpus_allowed, trialcs->cpus_allowed); |
957 | mutex_unlock(&callback_mutex); | 966 | mutex_unlock(&callback_mutex); |
958 | 967 | ||
959 | /* use trialcs->cpus_allowed as a temp variable */ | 968 | /* use trialcs->cpus_allowed as a temp variable */ |
960 | update_cpumasks_hier(cs, trialcs->cpus_allowed); | 969 | update_cpumasks_hier(cs, trialcs->cpus_allowed); |
961 | |||
962 | if (is_load_balanced) | ||
963 | rebuild_sched_domains_locked(); | ||
964 | return 0; | 970 | return 0; |
965 | } | 971 | } |
966 | 972 | ||