]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
cpusets, cgroups: disallow attaching kthreadd
authorMike Galbraith <efault@gmx.de>
Fri, 16 Dec 2011 04:50:30 +0000 (15:50 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Mon, 19 Dec 2011 07:19:47 +0000 (18:19 +1100)
Allowing kthreadd to be moved to a non-root group makes no sense, it being
a global resource, and needlessly leads unsuspecting users toward trouble.

1. An RT workqueue worker thread spawned in a task group with no
   rt_runtime allocated is not schedulable.  Simple user error, but
   harmful to the box.

2. A worker thread which acquires PF_THREAD_BOUND can never leave a
   cpuset, rendering the cpuset immortal.

Save the user some unexpected trouble, just say no.

Signed-off-by: Mike Galbraith <efault@gmx.de>
Acked-by: David Rientjes <rientjes@google.com>
Acked-by: Paul Menage <paul@paulmenage.org>
Cc: Tejun Heo <htejun@gmail.com>
Cc: Li Zefan <lizf@cn.fujitsu.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
kernel/cpuset.c
kernel/sched/core.c

index a09ac2b9a661d277ebee0d0e412e819ca5e70279..ca85d353e0fef674c93588073b24b5760c095139 100644 (file)
@@ -59,6 +59,7 @@
 #include <linux/mutex.h>
 #include <linux/workqueue.h>
 #include <linux/cgroup.h>
+#include <linux/kthread.h>
 
 /*
  * Workqueue for cpuset related tasks.
@@ -1417,9 +1418,11 @@ static int cpuset_can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
                 * 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.
+                * cpus_allowed may be changed.  We also disallow attaching
+                * kthreadd, to prevent its child from becoming trapped should
+                * it then acquire PF_THREAD_BOUND.
                 */
-               if (task->flags & PF_THREAD_BOUND)
+               if (task->flags & PF_THREAD_BOUND || task == kthreadd_task)
                        return -EINVAL;
                if ((ret = security_task_setscheduler(task)))
                        return ret;
index 9775b8d44336101df6444b77ef6c073aed65fc37..211cdc595d60db3b4a4305a5736815ee8c0591b8 100644 (file)
@@ -71,6 +71,7 @@
 #include <linux/ftrace.h>
 #include <linux/slab.h>
 #include <linux/init_task.h>
+#include <linux/kthread.h>
 
 #include <asm/tlb.h>
 #include <asm/irq_regs.h>
@@ -7535,6 +7536,14 @@ static int cpu_cgroup_can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
        struct task_struct *task;
 
        cgroup_taskset_for_each(task, cgrp, tset) {
+               /*
+                * kthreadd can fork workers for an RT workqueue in a cgroup
+                * which may or may not have rt_runtime allocated.  Just say no,
+                * as attaching a global resource to a non-root group  doesn't
+                * make any sense anyway.
+                */
+               if (task == kthreadd_task)
+                       return -EINVAL;
 #ifdef CONFIG_RT_GROUP_SCHED
                if (!sched_rt_can_attach(cgroup_tg(cgrp), task))
                        return -EINVAL;