aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWaiman Long <longman@redhat.com>2017-08-17 15:33:10 -0400
committerTejun Heo <tj@kernel.org>2017-08-18 11:24:22 -0400
commitb8d1b8ee93df8ffbabbeadd65d39853cfad6d698 (patch)
treed83d190bca0919da340bb0b6b6a6f4b77b3d7d51
parente1cba4b85daa71b710384d451ff6238d5e4d1ff6 (diff)
cpuset: Allow v2 behavior in v1 cgroup
Cpuset v2 has some useful behaviors that are not present in v1 because of backward compatibility concern. One of that is the restoration of the original cpu and memory node mask after a hot removal and addition event sequence. This patch makes the cpuset controller to check the CGRP_ROOT_CPUSET_V2_MODE flag and use the v2 behavior if it is set. Signed-off-by: Waiman Long <longman@redhat.com> Signed-off-by: Tejun Heo <tj@kernel.org>
-rw-r--r--kernel/cgroup/cpuset.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index 252d70c9a49b..f3539a41c49d 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -299,6 +299,16 @@ static DECLARE_WORK(cpuset_hotplug_work, cpuset_hotplug_workfn);
299static DECLARE_WAIT_QUEUE_HEAD(cpuset_attach_wq); 299static DECLARE_WAIT_QUEUE_HEAD(cpuset_attach_wq);
300 300
301/* 301/*
302 * Cgroup v2 behavior is used when on default hierarchy or the
303 * cgroup_v2_mode flag is set.
304 */
305static inline bool is_in_v2_mode(void)
306{
307 return cgroup_subsys_on_dfl(cpuset_cgrp_subsys) ||
308 (cpuset_cgrp_subsys.root->flags & CGRP_ROOT_CPUSET_V2_MODE);
309}
310
311/*
302 * This is ugly, but preserves the userspace API for existing cpuset 312 * This is ugly, but preserves the userspace API for existing cpuset
303 * users. If someone tries to mount the "cpuset" filesystem, we 313 * users. If someone tries to mount the "cpuset" filesystem, we
304 * silently switch it to mount "cgroup" instead 314 * silently switch it to mount "cgroup" instead
@@ -488,8 +498,7 @@ static int validate_change(struct cpuset *cur, struct cpuset *trial)
488 498
489 /* On legacy hiearchy, we must be a subset of our parent cpuset. */ 499 /* On legacy hiearchy, we must be a subset of our parent cpuset. */
490 ret = -EACCES; 500 ret = -EACCES;
491 if (!cgroup_subsys_on_dfl(cpuset_cgrp_subsys) && 501 if (!is_in_v2_mode() && !is_cpuset_subset(trial, par))
492 !is_cpuset_subset(trial, par))
493 goto out; 502 goto out;
494 503
495 /* 504 /*
@@ -895,8 +904,7 @@ static void update_cpumasks_hier(struct cpuset *cs, struct cpumask *new_cpus)
895 * If it becomes empty, inherit the effective mask of the 904 * If it becomes empty, inherit the effective mask of the
896 * parent, which is guaranteed to have some CPUs. 905 * parent, which is guaranteed to have some CPUs.
897 */ 906 */
898 if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys) && 907 if (is_in_v2_mode() && cpumask_empty(new_cpus))
899 cpumask_empty(new_cpus))
900 cpumask_copy(new_cpus, parent->effective_cpus); 908 cpumask_copy(new_cpus, parent->effective_cpus);
901 909
902 /* Skip the whole subtree if the cpumask remains the same. */ 910 /* Skip the whole subtree if the cpumask remains the same. */
@@ -913,7 +921,7 @@ static void update_cpumasks_hier(struct cpuset *cs, struct cpumask *new_cpus)
913 cpumask_copy(cp->effective_cpus, new_cpus); 921 cpumask_copy(cp->effective_cpus, new_cpus);
914 spin_unlock_irq(&callback_lock); 922 spin_unlock_irq(&callback_lock);
915 923
916 WARN_ON(!cgroup_subsys_on_dfl(cpuset_cgrp_subsys) && 924 WARN_ON(!is_in_v2_mode() &&
917 !cpumask_equal(cp->cpus_allowed, cp->effective_cpus)); 925 !cpumask_equal(cp->cpus_allowed, cp->effective_cpus));
918 926
919 update_tasks_cpumask(cp); 927 update_tasks_cpumask(cp);
@@ -1149,8 +1157,7 @@ static void update_nodemasks_hier(struct cpuset *cs, nodemask_t *new_mems)
1149 * If it becomes empty, inherit the effective mask of the 1157 * If it becomes empty, inherit the effective mask of the
1150 * parent, which is guaranteed to have some MEMs. 1158 * parent, which is guaranteed to have some MEMs.
1151 */ 1159 */
1152 if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys) && 1160 if (is_in_v2_mode() && nodes_empty(*new_mems))
1153 nodes_empty(*new_mems))
1154 *new_mems = parent->effective_mems; 1161 *new_mems = parent->effective_mems;
1155 1162
1156 /* Skip the whole subtree if the nodemask remains the same. */ 1163 /* Skip the whole subtree if the nodemask remains the same. */
@@ -1167,7 +1174,7 @@ static void update_nodemasks_hier(struct cpuset *cs, nodemask_t *new_mems)
1167 cp->effective_mems = *new_mems; 1174 cp->effective_mems = *new_mems;
1168 spin_unlock_irq(&callback_lock); 1175 spin_unlock_irq(&callback_lock);
1169 1176
1170 WARN_ON(!cgroup_subsys_on_dfl(cpuset_cgrp_subsys) && 1177 WARN_ON(!is_in_v2_mode() &&
1171 !nodes_equal(cp->mems_allowed, cp->effective_mems)); 1178 !nodes_equal(cp->mems_allowed, cp->effective_mems));
1172 1179
1173 update_tasks_nodemask(cp); 1180 update_tasks_nodemask(cp);
@@ -1459,7 +1466,7 @@ static int cpuset_can_attach(struct cgroup_taskset *tset)
1459 1466
1460 /* allow moving tasks into an empty cpuset if on default hierarchy */ 1467 /* allow moving tasks into an empty cpuset if on default hierarchy */
1461 ret = -ENOSPC; 1468 ret = -ENOSPC;
1462 if (!cgroup_subsys_on_dfl(cpuset_cgrp_subsys) && 1469 if (!is_in_v2_mode() &&
1463 (cpumask_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed))) 1470 (cpumask_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed)))
1464 goto out_unlock; 1471 goto out_unlock;
1465 1472
@@ -1977,7 +1984,7 @@ static int cpuset_css_online(struct cgroup_subsys_state *css)
1977 cpuset_inc(); 1984 cpuset_inc();
1978 1985
1979 spin_lock_irq(&callback_lock); 1986 spin_lock_irq(&callback_lock);
1980 if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys)) { 1987 if (is_in_v2_mode()) {
1981 cpumask_copy(cs->effective_cpus, parent->effective_cpus); 1988 cpumask_copy(cs->effective_cpus, parent->effective_cpus);
1982 cs->effective_mems = parent->effective_mems; 1989 cs->effective_mems = parent->effective_mems;
1983 } 1990 }
@@ -2054,7 +2061,7 @@ static void cpuset_bind(struct cgroup_subsys_state *root_css)
2054 mutex_lock(&cpuset_mutex); 2061 mutex_lock(&cpuset_mutex);
2055 spin_lock_irq(&callback_lock); 2062 spin_lock_irq(&callback_lock);
2056 2063
2057 if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys)) { 2064 if (is_in_v2_mode()) {
2058 cpumask_copy(top_cpuset.cpus_allowed, cpu_possible_mask); 2065 cpumask_copy(top_cpuset.cpus_allowed, cpu_possible_mask);
2059 top_cpuset.mems_allowed = node_possible_map; 2066 top_cpuset.mems_allowed = node_possible_map;
2060 } else { 2067 } else {
@@ -2248,7 +2255,7 @@ retry:
2248 cpus_updated = !cpumask_equal(&new_cpus, cs->effective_cpus); 2255 cpus_updated = !cpumask_equal(&new_cpus, cs->effective_cpus);
2249 mems_updated = !nodes_equal(new_mems, cs->effective_mems); 2256 mems_updated = !nodes_equal(new_mems, cs->effective_mems);
2250 2257
2251 if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys)) 2258 if (is_in_v2_mode())
2252 hotplug_update_tasks(cs, &new_cpus, &new_mems, 2259 hotplug_update_tasks(cs, &new_cpus, &new_mems,
2253 cpus_updated, mems_updated); 2260 cpus_updated, mems_updated);
2254 else 2261 else
@@ -2279,7 +2286,7 @@ static void cpuset_hotplug_workfn(struct work_struct *work)
2279 static cpumask_t new_cpus; 2286 static cpumask_t new_cpus;
2280 static nodemask_t new_mems; 2287 static nodemask_t new_mems;
2281 bool cpus_updated, mems_updated; 2288 bool cpus_updated, mems_updated;
2282 bool on_dfl = cgroup_subsys_on_dfl(cpuset_cgrp_subsys); 2289 bool on_dfl = is_in_v2_mode();
2283 2290
2284 mutex_lock(&cpuset_mutex); 2291 mutex_lock(&cpuset_mutex);
2285 2292