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@xxxxxxxxxxxxxxx> Tested-by: Dan Smith <danms@xxxxxxxxxx> --- 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@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/containers