aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cpuset.c
diff options
context:
space:
mode:
authorLi Zefan <lizefan@huawei.com>2014-07-09 04:47:29 -0400
committerTejun Heo <tj@kernel.org>2014-07-09 15:56:16 -0400
commit734d45130cb4f668fb33d182f6943523628582ef (patch)
treed13a09fb59491e64e7cf147823d54373192dcab9 /kernel/cpuset.c
parent1344ab9c2991b45bacfd2e26a8800a62663ae427 (diff)
cpuset: update cs->effective_{cpus, mems} when config changes
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. To make cs->effective_{cpus,mems} to be effective masks, we need to - update the effective masks at hotplug - update the effective masks at config change - take on ancestor's mask when the effective mask is empty The second item is done here. We don't need to treat root_cs specially in update_cpumasks_hier(). This won't introduce behavior change. v3: - add a WARN_ON() to check if effective masks are the same with configured masks on legacy hierarchy. - pass trialcs->cpus_allowed to update_cpumasks_hier() and add a comment for it. Similar change for update_nodemasks_hier(). Suggested by Tejun. v2: - revise the comment in update_{cpu,node}masks_hier(), suggested by Tejun. - fix to use @cp instead of @cs in these two functions. 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.c88
1 files changed, 54 insertions, 34 deletions
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 94f651d2eee5..da766c3736c4 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -855,36 +855,45 @@ static void update_tasks_cpumask(struct cpuset *cs)
855} 855}
856 856
857/* 857/*
858 * update_tasks_cpumask_hier - Update the cpumasks of tasks in the hierarchy. 858 * update_cpumasks_hier - Update effective cpumasks and tasks in the subtree
859 * @root_cs: the root cpuset of the hierarchy 859 * @cs: the cpuset to consider
860 * @update_root: update root cpuset or not? 860 * @new_cpus: temp variable for calculating new effective_cpus
861 *
862 * When congifured cpumask is changed, the effective cpumasks of this cpuset
863 * and all its descendants need to be updated.
861 * 864 *
862 * This will update cpumasks of tasks in @root_cs and all other empty cpusets 865 * On legacy hierachy, effective_cpus will be the same with cpu_allowed.
863 * which take on cpumask of @root_cs.
864 * 866 *
865 * Called with cpuset_mutex held 867 * Called with cpuset_mutex held
866 */ 868 */
867static void update_tasks_cpumask_hier(struct cpuset *root_cs, bool update_root) 869static void update_cpumasks_hier(struct cpuset *cs, struct cpumask *new_cpus)
868{ 870{
869 struct cpuset *cp; 871 struct cpuset *cp;
870 struct cgroup_subsys_state *pos_css; 872 struct cgroup_subsys_state *pos_css;
871 873
872 rcu_read_lock(); 874 rcu_read_lock();
873 cpuset_for_each_descendant_pre(cp, pos_css, root_cs) { 875 cpuset_for_each_descendant_pre(cp, pos_css, cs) {
874 if (cp == root_cs) { 876 struct cpuset *parent = parent_cs(cp);
875 if (!update_root) 877
876 continue; 878 cpumask_and(new_cpus, cp->cpus_allowed, parent->effective_cpus);
877 } else { 879
878 /* skip the whole subtree if @cp have some CPU */ 880 /* Skip the whole subtree if the cpumask remains the same. */
879 if (!cpumask_empty(cp->cpus_allowed)) { 881 if (cpumask_equal(new_cpus, cp->effective_cpus)) {
880 pos_css = css_rightmost_descendant(pos_css); 882 pos_css = css_rightmost_descendant(pos_css);
881 continue; 883 continue;
882 }
883 } 884 }
885
884 if (!css_tryget_online(&cp->css)) 886 if (!css_tryget_online(&cp->css))
885 continue; 887 continue;
886 rcu_read_unlock(); 888 rcu_read_unlock();
887 889
890 mutex_lock(&callback_mutex);
891 cpumask_copy(cp->effective_cpus, new_cpus);
892 mutex_unlock(&callback_mutex);
893
894 WARN_ON(!cgroup_on_dfl(cp->css.cgroup) &&
895 !cpumask_equal(cp->cpus_allowed, cp->effective_cpus));
896
888 update_tasks_cpumask(cp); 897 update_tasks_cpumask(cp);
889 898
890 rcu_read_lock(); 899 rcu_read_lock();
@@ -940,7 +949,8 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs,
940 cpumask_copy(cs->cpus_allowed, trialcs->cpus_allowed); 949 cpumask_copy(cs->cpus_allowed, trialcs->cpus_allowed);
941 mutex_unlock(&callback_mutex); 950 mutex_unlock(&callback_mutex);
942 951
943 update_tasks_cpumask_hier(cs, true); 952 /* use trialcs->cpus_allowed as a temp variable */
953 update_cpumasks_hier(cs, trialcs->cpus_allowed);
944 954
945 if (is_load_balanced) 955 if (is_load_balanced)
946 rebuild_sched_domains_locked(); 956 rebuild_sched_domains_locked();
@@ -1091,36 +1101,45 @@ static void update_tasks_nodemask(struct cpuset *cs)
1091} 1101}
1092 1102
1093/* 1103/*
1094 * update_tasks_nodemask_hier - Update the nodemasks of tasks in the hierarchy. 1104 * update_nodemasks_hier - Update effective nodemasks and tasks in the subtree
1095 * @cs: the root cpuset of the hierarchy 1105 * @cs: the cpuset to consider
1096 * @update_root: update the root cpuset or not? 1106 * @new_mems: a temp variable for calculating new effective_mems
1107 *
1108 * When configured nodemask is changed, the effective nodemasks of this cpuset
1109 * and all its descendants need to be updated.
1097 * 1110 *
1098 * This will update nodemasks of tasks in @root_cs and all other empty cpusets 1111 * On legacy hiearchy, effective_mems will be the same with mems_allowed.
1099 * which take on nodemask of @root_cs.
1100 * 1112 *
1101 * Called with cpuset_mutex held 1113 * Called with cpuset_mutex held
1102 */ 1114 */
1103static void update_tasks_nodemask_hier(struct cpuset *root_cs, bool update_root) 1115static void update_nodemasks_hier(struct cpuset *cs, nodemask_t *new_mems)
1104{ 1116{
1105 struct cpuset *cp; 1117 struct cpuset *cp;
1106 struct cgroup_subsys_state *pos_css; 1118 struct cgroup_subsys_state *pos_css;
1107 1119
1108 rcu_read_lock(); 1120 rcu_read_lock();
1109 cpuset_for_each_descendant_pre(cp, pos_css, root_cs) { 1121 cpuset_for_each_descendant_pre(cp, pos_css, cs) {
1110 if (cp == root_cs) { 1122 struct cpuset *parent = parent_cs(cp);
1111 if (!update_root) 1123
1112 continue; 1124 nodes_and(*new_mems, cp->mems_allowed, parent->effective_mems);
1113 } else { 1125
1114 /* skip the whole subtree if @cp have some CPU */ 1126 /* Skip the whole subtree if the nodemask remains the same. */
1115 if (!nodes_empty(cp->mems_allowed)) { 1127 if (nodes_equal(*new_mems, cp->effective_mems)) {
1116 pos_css = css_rightmost_descendant(pos_css); 1128 pos_css = css_rightmost_descendant(pos_css);
1117 continue; 1129 continue;
1118 }
1119 } 1130 }
1131
1120 if (!css_tryget_online(&cp->css)) 1132 if (!css_tryget_online(&cp->css))
1121 continue; 1133 continue;
1122 rcu_read_unlock(); 1134 rcu_read_unlock();
1123 1135
1136 mutex_lock(&callback_mutex);
1137 cp->effective_mems = *new_mems;
1138 mutex_unlock(&callback_mutex);
1139
1140 WARN_ON(!cgroup_on_dfl(cp->css.cgroup) &&
1141 nodes_equal(cp->mems_allowed, cp->effective_mems));
1142
1124 update_tasks_nodemask(cp); 1143 update_tasks_nodemask(cp);
1125 1144
1126 rcu_read_lock(); 1145 rcu_read_lock();
@@ -1188,7 +1207,8 @@ static int update_nodemask(struct cpuset *cs, struct cpuset *trialcs,
1188 cs->mems_allowed = trialcs->mems_allowed; 1207 cs->mems_allowed = trialcs->mems_allowed;
1189 mutex_unlock(&callback_mutex); 1208 mutex_unlock(&callback_mutex);
1190 1209
1191 update_tasks_nodemask_hier(cs, true); 1210 /* use trialcs->mems_allowed as a temp variable */
1211 update_nodemasks_hier(cs, &cs->mems_allowed);
1192done: 1212done:
1193 return retval; 1213 return retval;
1194} 1214}