diff options
author | 2012-06-20 14:41:57 -0700 | |
---|---|---|
committer | 2012-06-20 14:41:57 -0700 | |
commit | a2a2609c97c1e21996b9d87d10d2c9ff07277524 (patch) | |
tree | c9db50783d6727f95d2a6b4c019c2d66952969d9 /kernel | |
parent | Merge branch 'fixes' of git://git.linaro.org/people/rmk/linux-arm (diff) | |
parent | mm/memblock: fix overlapping allocation when doubling reserved array (diff) | |
download | wireguard-linux-a2a2609c97c1e21996b9d87d10d2c9ff07277524.tar.xz wireguard-linux-a2a2609c97c1e21996b9d87d10d2c9ff07277524.zip |
Merge branch 'akpm' (Andrew's patch-bomb)
* emailed from Andrew Morton <akpm@linux-foundation.org>: (21 patches)
mm/memblock: fix overlapping allocation when doubling reserved array
c/r: prctl: Move PR_GET_TID_ADDRESS to a proper place
pidns: find_new_reaper() can no longer switch to init_pid_ns.child_reaper
pidns: guarantee that the pidns init will be the last pidns process reaped
fault-inject: avoid call to random32() if fault injection is disabled
Viresh has moved
get_maintainer: Fix --help warning
mm/memory.c: fix kernel-doc warnings
mm: fix kernel-doc warnings
mm: correctly synchronize rss-counters at exit/exec
mm, thp: print useful information when mmap_sem is unlocked in zap_pmd_range
h8300: use the declarations provided by <asm/sections.h>
h8300: fix use of extinct _sbss and _ebss
xtensa: use the declarations provided by <asm/sections.h>
xtensa: use "test -e" instead of bashism "test -a"
xtensa: replace xtensa-specific _f{data,text} by _s{data,text}
memcg: fix use_hierarchy css_is_ancestor oops regression
mm, oom: fix and cleanup oom score calculations
nilfs2: ensure proper cache clearing for gc-inodes
thp: avoid atomic64_read in pmd_read_atomic for 32bit PAE
...
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/exit.c | 19 | ||||
-rw-r--r-- | kernel/pid_namespace.c | 20 | ||||
-rw-r--r-- | kernel/sys.c | 6 |
3 files changed, 36 insertions, 9 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index 34867cc5b42a..2f59cc334516 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -72,6 +72,18 @@ static void __unhash_process(struct task_struct *p, bool group_dead) list_del_rcu(&p->tasks); list_del_init(&p->sibling); __this_cpu_dec(process_counts); + /* + * If we are the last child process in a pid namespace to be + * reaped, notify the reaper sleeping zap_pid_ns_processes(). + */ + if (IS_ENABLED(CONFIG_PID_NS)) { + struct task_struct *parent = p->real_parent; + + if ((task_active_pid_ns(parent)->child_reaper == parent) && + list_empty(&parent->children) && + (parent->flags & PF_EXITING)) + wake_up_process(parent); + } } list_del_rcu(&p->thread_group); } @@ -643,6 +655,7 @@ static void exit_mm(struct task_struct * tsk) mm_release(tsk, mm); if (!mm) return; + sync_mm_rss(mm); /* * Serialize with any possible pending coredump. * We must hold mmap_sem around checking core_state @@ -719,12 +732,6 @@ static struct task_struct *find_new_reaper(struct task_struct *father) zap_pid_ns_processes(pid_ns); write_lock_irq(&tasklist_lock); - /* - * We can not clear ->child_reaper or leave it alone. - * There may by stealth EXIT_DEAD tasks on ->children, - * forget_original_parent() must move them somewhere. - */ - pid_ns->child_reaper = init_pid_ns.child_reaper; } else if (father->signal->has_child_subreaper) { struct task_struct *reaper; diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index 16b20e38c4a1..b3c7fd554250 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c @@ -184,11 +184,31 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns) } read_unlock(&tasklist_lock); + /* Firstly reap the EXIT_ZOMBIE children we may have. */ do { clear_thread_flag(TIF_SIGPENDING); rc = sys_wait4(-1, NULL, __WALL, NULL); } while (rc != -ECHILD); + /* + * sys_wait4() above can't reap the TASK_DEAD children. + * Make sure they all go away, see __unhash_process(). + */ + for (;;) { + bool need_wait = false; + + read_lock(&tasklist_lock); + if (!list_empty(¤t->children)) { + __set_current_state(TASK_UNINTERRUPTIBLE); + need_wait = true; + } + read_unlock(&tasklist_lock); + + if (!need_wait) + break; + schedule(); + } + if (pid_ns->reboot) current->signal->group_exit_code = pid_ns->reboot; diff --git a/kernel/sys.c b/kernel/sys.c index f0ec44dcd415..e0c8ffc50d7f 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -2127,9 +2127,6 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, else return -EINVAL; break; - case PR_GET_TID_ADDRESS: - error = prctl_get_tid_address(me, (int __user **)arg2); - break; default: return -EINVAL; } @@ -2147,6 +2144,9 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, case PR_SET_MM: error = prctl_set_mm(arg2, arg3, arg4, arg5); break; + case PR_GET_TID_ADDRESS: + error = prctl_get_tid_address(me, (int __user **)arg2); + break; case PR_SET_CHILD_SUBREAPER: me->signal->is_child_subreaper = !!arg2; error = 0; |