|
@@ -1375,33 +1375,34 @@ static int cpuset_can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
|
|
|
struct cgroup_taskset *tset)
|
|
|
{
|
|
|
struct cpuset *cs = cgroup_cs(cgrp);
|
|
|
+ struct task_struct *task;
|
|
|
+ int ret;
|
|
|
|
|
|
if (cpumask_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed))
|
|
|
return -ENOSPC;
|
|
|
|
|
|
- /*
|
|
|
- * Kthreads bound to specific cpus cannot be moved to a new cpuset; we
|
|
|
- * cannot change their cpu affinity and isolating such threads by their
|
|
|
- * set of allowed nodes is unnecessary. Thus, cpusets are not
|
|
|
- * applicable for such threads. This prevents checking for success of
|
|
|
- * set_cpus_allowed_ptr() on all attached tasks before cpus_allowed may
|
|
|
- * be changed.
|
|
|
- */
|
|
|
- if (cgroup_taskset_first(tset)->flags & PF_THREAD_BOUND)
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
+ cgroup_taskset_for_each(task, cgrp, tset) {
|
|
|
+ /*
|
|
|
+ * Kthreads bound to specific cpus cannot be moved to a new
|
|
|
+ * cpuset; we cannot change their cpu affinity and
|
|
|
+ * isolating such threads by their set of allowed nodes is
|
|
|
+ * unnecessary. Thus, cpusets are not applicable for such
|
|
|
+ * threads. This prevents checking for success of
|
|
|
+ * set_cpus_allowed_ptr() on all attached tasks before
|
|
|
+ * cpus_allowed may be changed.
|
|
|
+ */
|
|
|
+ if (task->flags & PF_THREAD_BOUND)
|
|
|
+ return -EINVAL;
|
|
|
+ if ((ret = security_task_setscheduler(task)))
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int cpuset_can_attach_task(struct cgroup *cgrp, struct task_struct *task)
|
|
|
-{
|
|
|
- return security_task_setscheduler(task);
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* Protected by cgroup_lock. The nodemasks must be stored globally because
|
|
|
* dynamically allocating them is not allowed in pre_attach, and they must
|
|
|
- * persist among pre_attach, attach_task, and attach.
|
|
|
+ * persist among pre_attach, and attach.
|
|
|
*/
|
|
|
static cpumask_var_t cpus_attach;
|
|
|
static nodemask_t cpuset_attach_nodemask_from;
|
|
@@ -1420,39 +1421,34 @@ static void cpuset_pre_attach(struct cgroup *cont)
|
|
|
guarantee_online_mems(cs, &cpuset_attach_nodemask_to);
|
|
|
}
|
|
|
|
|
|
-/* Per-thread attachment work. */
|
|
|
-static void cpuset_attach_task(struct cgroup *cont, struct task_struct *tsk)
|
|
|
-{
|
|
|
- int err;
|
|
|
- struct cpuset *cs = cgroup_cs(cont);
|
|
|
-
|
|
|
- /*
|
|
|
- * can_attach beforehand should guarantee that this doesn't fail.
|
|
|
- * TODO: have a better way to handle failure here
|
|
|
- */
|
|
|
- err = set_cpus_allowed_ptr(tsk, cpus_attach);
|
|
|
- WARN_ON_ONCE(err);
|
|
|
-
|
|
|
- cpuset_change_task_nodemask(tsk, &cpuset_attach_nodemask_to);
|
|
|
- cpuset_update_task_spread_flag(cs, tsk);
|
|
|
-}
|
|
|
-
|
|
|
static void cpuset_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
|
|
|
struct cgroup_taskset *tset)
|
|
|
{
|
|
|
struct mm_struct *mm;
|
|
|
- struct task_struct *tsk = cgroup_taskset_first(tset);
|
|
|
+ struct task_struct *task;
|
|
|
+ struct task_struct *leader = cgroup_taskset_first(tset);
|
|
|
struct cgroup *oldcgrp = cgroup_taskset_cur_cgroup(tset);
|
|
|
struct cpuset *cs = cgroup_cs(cgrp);
|
|
|
struct cpuset *oldcs = cgroup_cs(oldcgrp);
|
|
|
|
|
|
+ cgroup_taskset_for_each(task, cgrp, tset) {
|
|
|
+ /*
|
|
|
+ * can_attach beforehand should guarantee that this doesn't
|
|
|
+ * fail. TODO: have a better way to handle failure here
|
|
|
+ */
|
|
|
+ WARN_ON_ONCE(set_cpus_allowed_ptr(task, cpus_attach));
|
|
|
+
|
|
|
+ cpuset_change_task_nodemask(task, &cpuset_attach_nodemask_to);
|
|
|
+ cpuset_update_task_spread_flag(cs, task);
|
|
|
+ }
|
|
|
+
|
|
|
/*
|
|
|
* Change mm, possibly for multiple threads in a threadgroup. This is
|
|
|
* expensive and may sleep.
|
|
|
*/
|
|
|
cpuset_attach_nodemask_from = oldcs->mems_allowed;
|
|
|
cpuset_attach_nodemask_to = cs->mems_allowed;
|
|
|
- mm = get_task_mm(tsk);
|
|
|
+ mm = get_task_mm(leader);
|
|
|
if (mm) {
|
|
|
mpol_rebind_mm(mm, &cpuset_attach_nodemask_to);
|
|
|
if (is_memory_migrate(cs))
|
|
@@ -1908,9 +1904,7 @@ struct cgroup_subsys cpuset_subsys = {
|
|
|
.create = cpuset_create,
|
|
|
.destroy = cpuset_destroy,
|
|
|
.can_attach = cpuset_can_attach,
|
|
|
- .can_attach_task = cpuset_can_attach_task,
|
|
|
.pre_attach = cpuset_pre_attach,
|
|
|
- .attach_task = cpuset_attach_task,
|
|
|
.attach = cpuset_attach,
|
|
|
.populate = cpuset_populate,
|
|
|
.post_clone = cpuset_post_clone,
|