]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - kernel/exit.c
Merge master.kernel.org:/home/rmk/linux-2.6-drvmodel
[mirror_ubuntu-bionic-kernel.git] / kernel / exit.c
index 43077732619beef843fd6170361b1f4d04691179..537394b25e8d9a6d1e108ae0f78cbb3fab317769 100644 (file)
@@ -547,7 +547,7 @@ static inline void reparent_thread(task_t *p, task_t *father, int traced)
 
        if (p->pdeath_signal)
                /* We already hold the tasklist_lock here.  */
-               group_send_sig_info(p->pdeath_signal, (void *) 0, p);
+               group_send_sig_info(p->pdeath_signal, SEND_SIG_NOINFO, p);
 
        /* Move the child from its dying parent to the new one.  */
        if (unlikely(traced)) {
@@ -591,8 +591,8 @@ static inline void reparent_thread(task_t *p, task_t *father, int traced)
                int pgrp = process_group(p);
 
                if (will_become_orphaned_pgrp(pgrp, NULL) && has_stopped_jobs(pgrp)) {
-                       __kill_pg_info(SIGHUP, (void *)1, pgrp);
-                       __kill_pg_info(SIGCONT, (void *)1, pgrp);
+                       __kill_pg_info(SIGHUP, SEND_SIG_PRIV, pgrp);
+                       __kill_pg_info(SIGCONT, SEND_SIG_PRIV, pgrp);
                }
        }
 }
@@ -727,8 +727,8 @@ static void exit_notify(struct task_struct *tsk)
            (t->signal->session == tsk->signal->session) &&
            will_become_orphaned_pgrp(process_group(tsk), tsk) &&
            has_stopped_jobs(process_group(tsk))) {
-               __kill_pg_info(SIGHUP, (void *)1, process_group(tsk));
-               __kill_pg_info(SIGCONT, (void *)1, process_group(tsk));
+               __kill_pg_info(SIGHUP, SEND_SIG_PRIV, process_group(tsk));
+               __kill_pg_info(SIGCONT, SEND_SIG_PRIV, process_group(tsk));
        }
 
        /* Let father know we died 
@@ -783,10 +783,6 @@ static void exit_notify(struct task_struct *tsk)
        /* If the process is dead, release it - nobody will wait for it */
        if (state == EXIT_DEAD)
                release_task(tsk);
-
-       /* PF_DEAD causes final put_task_struct after we schedule. */
-       preempt_disable();
-       tsk->flags |= PF_DEAD;
 }
 
 fastcall NORET_TYPE void do_exit(long code)
@@ -839,10 +835,14 @@ fastcall NORET_TYPE void do_exit(long code)
                                preempt_count());
 
        acct_update_integrals(tsk);
-       update_mem_hiwater(tsk);
+       if (tsk->mm) {
+               update_hiwater_rss(tsk->mm);
+               update_hiwater_vm(tsk->mm);
+       }
        group_dead = atomic_dec_and_test(&tsk->signal->live);
        if (group_dead) {
                del_timer_sync(&tsk->signal->real_timer);
+               exit_itimers(tsk->signal);
                acct_process(code);
        }
        exit_mm(tsk);
@@ -869,7 +869,11 @@ fastcall NORET_TYPE void do_exit(long code)
        tsk->mempolicy = NULL;
 #endif
 
-       BUG_ON(!(current->flags & PF_DEAD));
+       /* PF_DEAD causes final put_task_struct after we schedule. */
+       preempt_disable();
+       BUG_ON(tsk->flags & PF_DEAD);
+       tsk->flags |= PF_DEAD;
+
        schedule();
        BUG();
        /* Avoid "noreturn function does return".  */
@@ -1379,6 +1383,15 @@ repeat:
 
                        switch (p->state) {
                        case TASK_TRACED:
+                               /*
+                                * When we hit the race with PTRACE_ATTACH,
+                                * we will not report this child.  But the
+                                * race means it has not yet been moved to
+                                * our ptrace_children list, so we need to
+                                * set the flag here to avoid a spurious ECHILD
+                                * when the race happens with the only child.
+                                */
+                               flag = 1;
                                if (!my_ptrace_child(p))
                                        continue;
                                /*FALLTHROUGH*/