[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20131109065114.151262963@linuxfoundation.org>
Date: Fri, 8 Nov 2013 22:51:14 -0800
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
stable@...r.kernel.org, Eunki Kim <eunki_kim@...sung.com>,
Anjana V Kumar <anjanavk12@...il.com>,
Li Zefan <lizefan@...wei.com>, Tejun Heo <tj@...nel.org>
Subject: [PATCH 3.10 09/74] cgroup: fix to break the while loop in cgroup_attach_task() correctly
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anjana V Kumar <anjanavk12@...il.com>
commit ea84753c98a7ac6b74e530b64c444a912b3835ca upstream.
Both Anjana and Eunki reported a stall in the while_each_thread loop
in cgroup_attach_task().
It's because, when we attach a single thread to a cgroup, if the cgroup
is exiting or is already in that cgroup, we won't break the loop.
If the task is already in the cgroup, the bug can lead to another thread
being attached to the cgroup unexpectedly:
# echo 5207 > tasks
# cat tasks
5207
# echo 5207 > tasks
# cat tasks
5207
5215
What's worse, if the task to be attached isn't the leader of the thread
group, we might never exit the loop, hence cpu stall. Thanks for Oleg's
analysis.
This bug was introduced by commit 081aa458c38ba576bdd4265fc807fa95b48b9e79
("cgroup: consolidate cgroup_attach_task() and cgroup_attach_proc()")
[ lizf: - fixed the first continue, pointed out by Oleg,
- rewrote changelog. ]
Reported-by: Eunki Kim <eunki_kim@...sung.com>
Reported-by: Anjana V Kumar <anjanavk12@...il.com>
Signed-off-by: Anjana V Kumar <anjanavk12@...il.com>
Signed-off-by: Li Zefan <lizefan@...wei.com>
Signed-off-by: Tejun Heo <tj@...nel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
---
kernel/cgroup.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -1995,7 +1995,7 @@ static int cgroup_attach_task(struct cgr
/* @tsk either already exited or can't exit until the end */
if (tsk->flags & PF_EXITING)
- continue;
+ goto next;
/* as per above, nr_threads may decrease, but not increase. */
BUG_ON(i >= group_size);
@@ -2003,7 +2003,7 @@ static int cgroup_attach_task(struct cgr
ent.cgrp = task_cgroup_from_root(tsk, root);
/* nothing to do if this task is already in the cgroup */
if (ent.cgrp == cgrp)
- continue;
+ goto next;
/*
* saying GFP_ATOMIC has no effect here because we did prealloc
* earlier, but it's good form to communicate our expectations.
@@ -2011,7 +2011,7 @@ static int cgroup_attach_task(struct cgr
retval = flex_array_put(group, i, &ent, GFP_ATOMIC);
BUG_ON(retval != 0);
i++;
-
+ next:
if (!threadgroup)
break;
} while_each_thread(leader, tsk);
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists