[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