[Devel] [PATCH 1/2] c/r: fix task tree traversal for threads
Oren Laadan
orenl at cs.columbia.edu
Sun Jul 11 19:05:21 PDT 2010
This patch fixes the logic of walk_task_subtree() to correctly account
for all threads (and not only threads of the tree root).
Signed-off-by: Oren Laadan <orenl at cs.columbia.edu>
Tested-by: Dan Smith <danms at us.ibm.com>
---
kernel/checkpoint/sys.c | 24 ++++++++++++++----------
1 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/kernel/checkpoint/sys.c b/kernel/checkpoint/sys.c
index 5e6994e..171c867 100644
--- a/kernel/checkpoint/sys.c
+++ b/kernel/checkpoint/sys.c
@@ -565,7 +565,10 @@ EXPORT_SYMBOL(do_ckpt_msg);
*
* The function will start with @root, and iterate through all the
* descendants, including threads, in a DFS manner. Children of a task
- * are traversed before proceeding to the next thread of that task.
+ * are traversed before proceeding to the next thread of that task,
+ * and threads of a task are traversed before proceeding to the next
+ * sibling of that task. (Threads of the root task are included, but
+ * siblings of the root task are skipped).
*
* For each task, the callback @func will be called providing the task
* pointer and the @data. The callback is invoked while holding the
@@ -580,10 +583,8 @@ int walk_task_subtree(struct task_struct *root,
int (*func)(struct task_struct *, void *),
void *data)
{
-
- struct task_struct *leader = root;
- struct task_struct *parent = NULL;
struct task_struct *task = root;
+ struct task_struct *parent = NULL;
int total = 0;
int ret;
@@ -604,7 +605,13 @@ int walk_task_subtree(struct task_struct *root,
continue;
}
+ /* by definition, skip siblings of root */
while (task != root) {
+ /* if not last thread - proceed with thread */
+ task = next_thread(task);
+ if (!thread_group_leader(task))
+ break;
+
/* if has sibling - proceed with sibling */
if (!list_is_last(&task->sibling, &parent->children)) {
task = list_entry(task->sibling.next,
@@ -617,12 +624,9 @@ int walk_task_subtree(struct task_struct *root,
parent = parent->real_parent;
}
- if (task == root) {
- /* in case root task is multi-threaded */
- root = task = next_thread(task);
- if (root == leader)
- break;
- }
+ /* if we arrive at root again -- done */
+ if (task == root)
+ break;
}
read_unlock(&tasklist_lock);
--
1.7.0.4
_______________________________________________
Containers mailing list
Containers at lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/containers
More information about the Devel
mailing list