diff options
Diffstat (limited to 'kernel/fork.c')
-rw-r--r-- | kernel/fork.c | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index d12fcc4db8a3..348fe73155bc 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -1377,9 +1377,6 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) | |||
1377 | sig->oom_score_adj = current->signal->oom_score_adj; | 1377 | sig->oom_score_adj = current->signal->oom_score_adj; |
1378 | sig->oom_score_adj_min = current->signal->oom_score_adj_min; | 1378 | sig->oom_score_adj_min = current->signal->oom_score_adj_min; |
1379 | 1379 | ||
1380 | sig->has_child_subreaper = current->signal->has_child_subreaper || | ||
1381 | current->signal->is_child_subreaper; | ||
1382 | |||
1383 | mutex_init(&sig->cred_guard_mutex); | 1380 | mutex_init(&sig->cred_guard_mutex); |
1384 | 1381 | ||
1385 | return 0; | 1382 | return 0; |
@@ -1814,6 +1811,13 @@ static __latent_entropy struct task_struct *copy_process( | |||
1814 | 1811 | ||
1815 | p->signal->leader_pid = pid; | 1812 | p->signal->leader_pid = pid; |
1816 | p->signal->tty = tty_kref_get(current->signal->tty); | 1813 | p->signal->tty = tty_kref_get(current->signal->tty); |
1814 | /* | ||
1815 | * Inherit has_child_subreaper flag under the same | ||
1816 | * tasklist_lock with adding child to the process tree | ||
1817 | * for propagate_has_child_subreaper optimization. | ||
1818 | */ | ||
1819 | p->signal->has_child_subreaper = p->real_parent->signal->has_child_subreaper || | ||
1820 | p->real_parent->signal->is_child_subreaper; | ||
1817 | list_add_tail(&p->sibling, &p->real_parent->children); | 1821 | list_add_tail(&p->sibling, &p->real_parent->children); |
1818 | list_add_tail_rcu(&p->tasks, &init_task.tasks); | 1822 | list_add_tail_rcu(&p->tasks, &init_task.tasks); |
1819 | attach_pid(p, PIDTYPE_PGID); | 1823 | attach_pid(p, PIDTYPE_PGID); |
@@ -2067,6 +2071,38 @@ SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, | |||
2067 | } | 2071 | } |
2068 | #endif | 2072 | #endif |
2069 | 2073 | ||
2074 | void walk_process_tree(struct task_struct *top, proc_visitor visitor, void *data) | ||
2075 | { | ||
2076 | struct task_struct *leader, *parent, *child; | ||
2077 | int res; | ||
2078 | |||
2079 | read_lock(&tasklist_lock); | ||
2080 | leader = top = top->group_leader; | ||
2081 | down: | ||
2082 | for_each_thread(leader, parent) { | ||
2083 | list_for_each_entry(child, &parent->children, sibling) { | ||
2084 | res = visitor(child, data); | ||
2085 | if (res) { | ||
2086 | if (res < 0) | ||
2087 | goto out; | ||
2088 | leader = child; | ||
2089 | goto down; | ||
2090 | } | ||
2091 | up: | ||
2092 | ; | ||
2093 | } | ||
2094 | } | ||
2095 | |||
2096 | if (leader != top) { | ||
2097 | child = leader; | ||
2098 | parent = child->real_parent; | ||
2099 | leader = parent->group_leader; | ||
2100 | goto up; | ||
2101 | } | ||
2102 | out: | ||
2103 | read_unlock(&tasklist_lock); | ||
2104 | } | ||
2105 | |||
2070 | #ifndef ARCH_MIN_MMSTRUCT_ALIGN | 2106 | #ifndef ARCH_MIN_MMSTRUCT_ALIGN |
2071 | #define ARCH_MIN_MMSTRUCT_ALIGN 0 | 2107 | #define ARCH_MIN_MMSTRUCT_ALIGN 0 |
2072 | #endif | 2108 | #endif |