|
@@ -91,6 +91,12 @@ struct cpuset {
|
|
|
|
|
|
struct fmeter fmeter; /* memory_pressure filter */
|
|
|
|
|
|
+ /*
|
|
|
+ * Tasks are being attached to this cpuset. Used to prevent
|
|
|
+ * zeroing cpus/mems_allowed between ->can_attach() and ->attach().
|
|
|
+ */
|
|
|
+ int attach_in_progress;
|
|
|
+
|
|
|
/* partition number for rebuild_sched_domains() */
|
|
|
int pn;
|
|
|
|
|
@@ -468,9 +474,12 @@ static int validate_change(const struct cpuset *cur, const struct cpuset *trial)
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
- /* Cpusets with tasks can't have empty cpus_allowed or mems_allowed */
|
|
|
+ /*
|
|
|
+ * Cpusets with tasks - existing or newly being attached - can't
|
|
|
+ * have empty cpus_allowed or mems_allowed.
|
|
|
+ */
|
|
|
ret = -ENOSPC;
|
|
|
- if (cgroup_task_count(cur->css.cgroup) &&
|
|
|
+ if ((cgroup_task_count(cur->css.cgroup) || cur->attach_in_progress) &&
|
|
|
(cpumask_empty(trial->cpus_allowed) ||
|
|
|
nodes_empty(trial->mems_allowed)))
|
|
|
goto out;
|
|
@@ -1386,9 +1395,21 @@ static int cpuset_can_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * Mark attach is in progress. This makes validate_change() fail
|
|
|
+ * changes which zero cpus/mems_allowed.
|
|
|
+ */
|
|
|
+ cs->attach_in_progress++;
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static void cpuset_cancel_attach(struct cgroup *cgrp,
|
|
|
+ struct cgroup_taskset *tset)
|
|
|
+{
|
|
|
+ cgroup_cs(cgrp)->attach_in_progress--;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Protected by cgroup_mutex. cpus_attach is used only by cpuset_attach()
|
|
|
* but we can't allocate it dynamically there. Define it global and
|
|
@@ -1441,6 +1462,8 @@ static void cpuset_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
|
|
|
&cpuset_attach_nodemask_to);
|
|
|
mmput(mm);
|
|
|
}
|
|
|
+
|
|
|
+ cs->attach_in_progress--;
|
|
|
}
|
|
|
|
|
|
/* The various types of files and directories in a cpuset file system */
|
|
@@ -1908,6 +1931,7 @@ struct cgroup_subsys cpuset_subsys = {
|
|
|
.css_offline = cpuset_css_offline,
|
|
|
.css_free = cpuset_css_free,
|
|
|
.can_attach = cpuset_can_attach,
|
|
|
+ .cancel_attach = cpuset_cancel_attach,
|
|
|
.attach = cpuset_attach,
|
|
|
.subsys_id = cpuset_subsys_id,
|
|
|
.base_cftypes = files,
|