19454b2d8SWarner Losh /*- 2df8bae1dSRodney W. Grimes * Copyright (c) 1982, 1986, 1989, 1991, 1993 3df8bae1dSRodney W. Grimes * The Regents of the University of California. All rights reserved. 4df8bae1dSRodney W. Grimes * (c) UNIX System Laboratories, Inc. 5df8bae1dSRodney W. Grimes * All or some portions of this file are derived from material licensed 6df8bae1dSRodney W. Grimes * to the University of California by American Telephone and Telegraph 7df8bae1dSRodney W. Grimes * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8df8bae1dSRodney W. Grimes * the permission of UNIX System Laboratories, Inc. 9df8bae1dSRodney W. Grimes * 10df8bae1dSRodney W. Grimes * Redistribution and use in source and binary forms, with or without 11df8bae1dSRodney W. Grimes * modification, are permitted provided that the following conditions 12df8bae1dSRodney W. Grimes * are met: 13df8bae1dSRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 14df8bae1dSRodney W. Grimes * notice, this list of conditions and the following disclaimer. 15df8bae1dSRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 16df8bae1dSRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 17df8bae1dSRodney W. Grimes * documentation and/or other materials provided with the distribution. 18df8bae1dSRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 19df8bae1dSRodney W. Grimes * may be used to endorse or promote products derived from this software 20df8bae1dSRodney W. Grimes * without specific prior written permission. 21df8bae1dSRodney W. Grimes * 22df8bae1dSRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23df8bae1dSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24df8bae1dSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25df8bae1dSRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26df8bae1dSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27df8bae1dSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28df8bae1dSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29df8bae1dSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30df8bae1dSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31df8bae1dSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32df8bae1dSRodney W. Grimes * SUCH DAMAGE. 33df8bae1dSRodney W. Grimes * 34df8bae1dSRodney W. Grimes * @(#)kern_exit.c 8.7 (Berkeley) 2/12/94 35df8bae1dSRodney W. Grimes */ 36df8bae1dSRodney W. Grimes 37677b542eSDavid E. O'Brien #include <sys/cdefs.h> 38677b542eSDavid E. O'Brien __FBSDID("$FreeBSD$"); 39677b542eSDavid E. O'Brien 405591b823SEivind Eklund #include "opt_compat.h" 41db6a20e2SGarrett Wollman #include "opt_ktrace.h" 422555374cSRobert Watson #include "opt_mac.h" 43db6a20e2SGarrett Wollman 44df8bae1dSRodney W. Grimes #include <sys/param.h> 45df8bae1dSRodney W. Grimes #include <sys/systm.h> 465fdb8324SBruce Evans #include <sys/sysproto.h> 4775b8b3b2SJohn Baldwin #include <sys/eventhandler.h> 481c5bb3eaSPeter Wemm #include <sys/kernel.h> 49a1c995b6SPoul-Henning Kamp #include <sys/malloc.h> 50f34fa851SJohn Baldwin #include <sys/lock.h> 5135e0e5b3SJohn Baldwin #include <sys/mutex.h> 52df8bae1dSRodney W. Grimes #include <sys/proc.h> 532a024a2bSSean Eric Fagan #include <sys/pioctl.h> 54df8bae1dSRodney W. Grimes #include <sys/tty.h> 55df8bae1dSRodney W. Grimes #include <sys/wait.h> 56eb30c1c0SPeter Wemm #include <sys/vmmeter.h> 577a6b989bSJohn Baldwin #include <sys/vnode.h> 58df8bae1dSRodney W. Grimes #include <sys/resourcevar.h> 59797f2d22SPoul-Henning Kamp #include <sys/signalvar.h> 60b43179fbSJeff Roberson #include <sys/sched.h> 611005a129SJohn Baldwin #include <sys/sx.h> 62c8837938SJohn Baldwin #include <sys/syscallsubr.h> 63df8bae1dSRodney W. Grimes #include <sys/ptrace.h> 647c409b8aSJeffrey Hsu #include <sys/acct.h> /* for acct_process() function prototype */ 65797f2d22SPoul-Henning Kamp #include <sys/filedesc.h> 662555374cSRobert Watson #include <sys/mac.h> 67780dc5a8SPeter Wemm #include <sys/shm.h> 68780dc5a8SPeter Wemm #include <sys/sem.h> 6960354683SDavid Xu #include <sys/timers.h> 706c84de02SJohn Baldwin #ifdef KTRACE 716c84de02SJohn Baldwin #include <sys/ktrace.h> 726c84de02SJohn Baldwin #endif 73780dc5a8SPeter Wemm 74df8bae1dSRodney W. Grimes #include <vm/vm.h> 75eb30c1c0SPeter Wemm #include <vm/vm_extern.h> 767a6b989bSJohn Baldwin #include <vm/vm_param.h> 77efeaf95aSDavid Greenman #include <vm/pmap.h> 78efeaf95aSDavid Greenman #include <vm/vm_map.h> 792d21129dSAlan Cox #include <vm/vm_page.h> 80c897b813SJeff Roberson #include <vm/uma.h> 81df8bae1dSRodney W. Grimes 82ba198b1cSMark Newton /* Required to be non-static for SysVR4 emulator */ 8369a6f20bSMark Newton MALLOC_DEFINE(M_ZOMBIE, "zombie", "zombie proc status"); 8455166637SPoul-Henning Kamp 85c0bc2867SGleb Smirnoff /* Hook for NFS teardown procedure. */ 86c0bc2867SGleb Smirnoff void (*nlminfo_release_p)(struct proc *p); 87c0bc2867SGleb Smirnoff 88df8bae1dSRodney W. Grimes /* 89df8bae1dSRodney W. Grimes * exit -- 90df8bae1dSRodney W. Grimes * Death of process. 91234216efSMatthew Dillon * 92234216efSMatthew Dillon * MPSAFE 93df8bae1dSRodney W. Grimes */ 94fc0b1dbfSBruce Evans void 95830c3153SDag-Erling Smørgrav sys_exit(struct thread *td, struct sys_exit_args *uap) 96df8bae1dSRodney W. Grimes { 97b40ce416SJulian Elischer 98b40ce416SJulian Elischer exit1(td, W_EXITCODE(uap->rval, 0)); 99df8bae1dSRodney W. Grimes /* NOTREACHED */ 100df8bae1dSRodney W. Grimes } 101df8bae1dSRodney W. Grimes 102df8bae1dSRodney W. Grimes /* 103df8bae1dSRodney W. Grimes * Exit: deallocate address space and other resources, change proc state 104df8bae1dSRodney W. Grimes * to zombie, and unlink proc from allproc and parent's lists. Save exit 105df8bae1dSRodney W. Grimes * status and rusage for wait(). Check for child processes and orphan them. 106df8bae1dSRodney W. Grimes */ 107fc0b1dbfSBruce Evans void 108830c3153SDag-Erling Smørgrav exit1(struct thread *td, int rv) 109df8bae1dSRodney W. Grimes { 110871684b8SBruce Evans struct bintime new_switchtime; 111276c5169SJohn Baldwin struct proc *p, *nq, *q; 112276c5169SJohn Baldwin struct tty *tp; 113276c5169SJohn Baldwin struct vnode *ttyvp; 114830c3153SDag-Erling Smørgrav struct vmspace *vm; 11579deba82SMatthew Dillon struct vnode *vtmp; 116d7aadbf9SJohn Baldwin #ifdef KTRACE 117d7aadbf9SJohn Baldwin struct vnode *tracevp; 118a5881ea5SJohn Baldwin struct ucred *tracecred; 119d7aadbf9SJohn Baldwin #endif 12091d5354aSJohn Baldwin struct plimit *plim; 12157606880SChristian S.J. Peron int locked, refcnt; 122df8bae1dSRodney W. Grimes 1234ae89b95SJohn Baldwin /* 1244ae89b95SJohn Baldwin * Drop Giant if caller has it. Eventually we should warn about 1254ae89b95SJohn Baldwin * being called with Giant held. 1264ae89b95SJohn Baldwin */ 1274ae89b95SJohn Baldwin while (mtx_owned(&Giant)) 1284ae89b95SJohn Baldwin mtx_unlock(&Giant); 1290cddd8f0SMatthew Dillon 130276c5169SJohn Baldwin p = td->td_proc; 131e746d950SJohn Baldwin if (p == initproc) { 1325f7bd355SPoul-Henning Kamp printf("init died (signal %d, exit %d)\n", 133df8bae1dSRodney W. Grimes WTERMSIG(rv), WEXITSTATUS(rv)); 1345f7bd355SPoul-Henning Kamp panic("Going nowhere without my init!"); 1355f7bd355SPoul-Henning Kamp } 1362c1011f7SJohn Dyson 1377a6b989bSJohn Baldwin /* 1382c10d16aSJeff Roberson * MUST abort all other threads before proceeding past here. 1397a6b989bSJohn Baldwin */ 140e602ba25SJulian Elischer PROC_LOCK(p); 141ed062c8dSJulian Elischer if (p->p_flag & P_HADTHREADS) { 1420aabef65SDavid Xu retry: 143e602ba25SJulian Elischer /* 144e602ba25SJulian Elischer * First check if some other thread got here before us.. 145e602ba25SJulian Elischer * if so, act apropriatly, (exit or suspend); 146e602ba25SJulian Elischer */ 147e602ba25SJulian Elischer thread_suspend_check(0); 148e602ba25SJulian Elischer 149e602ba25SJulian Elischer /* 150e602ba25SJulian Elischer * Kill off the other threads. This requires 1516111dcd2SJohn Baldwin * some co-operation from other parts of the kernel 1526111dcd2SJohn Baldwin * so it may not be instantaneous. With this state set 1536111dcd2SJohn Baldwin * any thread entering the kernel from userspace will 154e602ba25SJulian Elischer * thread_exit() in trap(). Any thread attempting to 1556111dcd2SJohn Baldwin * sleep will return immediately with EINTR or EWOULDBLOCK 1566111dcd2SJohn Baldwin * which will hopefully force them to back out to userland 1576111dcd2SJohn Baldwin * freeing resources as they go. Any thread attempting 158b3248998SJulian Elischer * to return to userland will thread_exit() from userret(). 1596111dcd2SJohn Baldwin * thread_exit() will unsuspend us when the last of the 1606111dcd2SJohn Baldwin * other threads exits. 161b370279eSDavid Xu * If there is already a thread singler after resumption, 1626111dcd2SJohn Baldwin * calling thread_single will fail; in that case, we just 163b370279eSDavid Xu * re-check all suspension request, the thread should 164b370279eSDavid Xu * either be suspended there or exit. 165e602ba25SJulian Elischer */ 16637814395SPeter Wemm if (thread_single(SINGLE_EXIT)) 1670aabef65SDavid Xu goto retry; 1686111dcd2SJohn Baldwin 169e602ba25SJulian Elischer /* 170e602ba25SJulian Elischer * All other activity in this process is now stopped. 171ed062c8dSJulian Elischer * Threading support has been turned off. 172e602ba25SJulian Elischer */ 173e602ba25SJulian Elischer } 174e602ba25SJulian Elischer 175e602ba25SJulian Elischer p->p_flag |= P_WEXIT; 176ebceaf6dSDavid Xu 177ebceaf6dSDavid Xu PROC_LOCK(p->p_pptr); 178ebceaf6dSDavid Xu sigqueue_take(p->p_ksi); 179ebceaf6dSDavid Xu PROC_UNLOCK(p->p_pptr); 180ebceaf6dSDavid Xu 181e602ba25SJulian Elischer PROC_UNLOCK(p); 182b40ce416SJulian Elischer 1837a6b989bSJohn Baldwin /* Are we a task leader? */ 1842c1011f7SJohn Dyson if (p == p->p_leader) { 185c6544064SJohn Baldwin mtx_lock(&ppeers_lock); 1862c1011f7SJohn Dyson q = p->p_peers; 187776e0b36SJohn Baldwin while (q != NULL) { 188776e0b36SJohn Baldwin PROC_LOCK(q); 189776e0b36SJohn Baldwin psignal(q, SIGKILL); 190776e0b36SJohn Baldwin PROC_UNLOCK(q); 1912c1011f7SJohn Dyson q = q->p_peers; 1922c1011f7SJohn Dyson } 193c6544064SJohn Baldwin while (p->p_peers != NULL) 194c6544064SJohn Baldwin msleep(p, &ppeers_lock, PWAIT, "exit1", 0); 195c6544064SJohn Baldwin mtx_unlock(&ppeers_lock); 1962c1011f7SJohn Dyson } 1972c1011f7SJohn Dyson 1984ae89b95SJohn Baldwin PROC_LOCK(p); 1994ae89b95SJohn Baldwin _STOPEVENT(p, S_EXIT, rv); 20089361835SSean Eric Fagan wakeup(&p->p_stype); /* Wakeup anyone in procfs' PIOCWAIT */ 2014ae89b95SJohn Baldwin PROC_UNLOCK(p); 2022a024a2bSSean Eric Fagan 203fed06968SJulian Elischer /* 204e9189611SPeter Wemm * Check if any loadable modules need anything done at process exit. 2056111dcd2SJohn Baldwin * E.g. SYSV IPC stuff 206fed06968SJulian Elischer * XXX what if one of these generates an error? 207fed06968SJulian Elischer */ 20875b8b3b2SJohn Baldwin EVENTHANDLER_INVOKE(process_exit, p); 209a914fb6bSJohn Baldwin 210df8bae1dSRodney W. Grimes MALLOC(p->p_ru, struct rusage *, sizeof(struct rusage), 211a163d034SWarner Losh M_ZOMBIE, M_WAITOK); 212df8bae1dSRodney W. Grimes /* 213df8bae1dSRodney W. Grimes * If parent is waiting for us to exit or exec, 214df8bae1dSRodney W. Grimes * P_PPWAIT is set; we will wakeup the parent below. 215df8bae1dSRodney W. Grimes */ 216a914fb6bSJohn Baldwin PROC_LOCK(p); 217a282253aSJulian Elischer stopprofclock(p); 218df8bae1dSRodney W. Grimes p->p_flag &= ~(P_TRACED | P_PPWAIT); 2195499ea01SJohn Baldwin 2205499ea01SJohn Baldwin /* 2215499ea01SJohn Baldwin * Stop the real interval timer. If the handler is currently 2225499ea01SJohn Baldwin * executing, prevent it from rearming itself and let it finish. 2235499ea01SJohn Baldwin */ 2245499ea01SJohn Baldwin if (timevalisset(&p->p_realtimer.it_value) && 2255499ea01SJohn Baldwin callout_stop(&p->p_itcallout) == 0) { 2265499ea01SJohn Baldwin timevalclear(&p->p_realtimer.it_interval); 2275499ea01SJohn Baldwin msleep(&p->p_itcallout, &p->p_mtx, PWAIT, "ritwait", 0); 2285499ea01SJohn Baldwin KASSERT(!timevalisset(&p->p_realtimer.it_value), 2295499ea01SJohn Baldwin ("realtime timer is still armed")); 2305499ea01SJohn Baldwin } 23186857b36SDavid Xu sigqueue_flush(&p->p_sigqueue); 23286857b36SDavid Xu sigqueue_flush(&td->td_sigqueue); 23396d7f8efSTim J. Robbins PROC_UNLOCK(p); 234df8bae1dSRodney W. Grimes 23586857b36SDavid Xu itimers_event_hook(p, ITIMER_EV_EXIT); 23686857b36SDavid Xu 237df8bae1dSRodney W. Grimes /* 238831d27a9SDon Lewis * Reset any sigio structures pointing to us as a result of 239831d27a9SDon Lewis * F_SETOWN with our pid. 240831d27a9SDon Lewis */ 2414ae89b95SJohn Baldwin mtx_lock(&Giant); /* XXX: not sure if needed */ 242831d27a9SDon Lewis funsetownlst(&p->p_sigiolst); 24368a17869SJohn Baldwin mtx_unlock(&Giant); 244831d27a9SDon Lewis 245831d27a9SDon Lewis /* 246c0bc2867SGleb Smirnoff * If this process has an nlminfo data area (for lockd), release it 247c0bc2867SGleb Smirnoff */ 248c0bc2867SGleb Smirnoff if (nlminfo_release_p != NULL && p->p_nlminfo != NULL) 249c0bc2867SGleb Smirnoff (*nlminfo_release_p)(p); 250c0bc2867SGleb Smirnoff 251c0bc2867SGleb Smirnoff /* 252df8bae1dSRodney W. Grimes * Close open files and release open-file table. 253df8bae1dSRodney W. Grimes * This may block! 254df8bae1dSRodney W. Grimes */ 255edf6699aSAlfred Perlstein fdfree(td); 256df8bae1dSRodney W. Grimes 257a914fb6bSJohn Baldwin /* 258a2587073SPoul-Henning Kamp * If this thread tickled GEOM, we need to wait for the giggling to 259a2587073SPoul-Henning Kamp * stop before we return to userland 260a2587073SPoul-Henning Kamp */ 261a2587073SPoul-Henning Kamp if (td->td_pflags & TDP_GEOM) 262a2587073SPoul-Henning Kamp g_waitidle(); 263a2587073SPoul-Henning Kamp 264a2587073SPoul-Henning Kamp /* 265a914fb6bSJohn Baldwin * Remove ourself from our leader's peer list and wake our leader. 266a914fb6bSJohn Baldwin */ 267c6544064SJohn Baldwin mtx_lock(&ppeers_lock); 26879fc0bf4SMike Smith if (p->p_leader->p_peers) { 26979fc0bf4SMike Smith q = p->p_leader; 27079fc0bf4SMike Smith while (q->p_peers != p) 27179fc0bf4SMike Smith q = q->p_peers; 27279fc0bf4SMike Smith q->p_peers = p->p_peers; 2737f05b035SAlfred Perlstein wakeup(p->p_leader); 27479fc0bf4SMike Smith } 275c6544064SJohn Baldwin mtx_unlock(&ppeers_lock); 27679fc0bf4SMike Smith 277df8bae1dSRodney W. Grimes /* The next two chunks should probably be moved to vmspace_exit. */ 278df8bae1dSRodney W. Grimes vm = p->p_vmspace; 279df8bae1dSRodney W. Grimes /* 280df8bae1dSRodney W. Grimes * Release user portion of address space. 281df8bae1dSRodney W. Grimes * This releases references to vnodes, 282df8bae1dSRodney W. Grimes * which could cause I/O if the file has been unlinked. 283df8bae1dSRodney W. Grimes * Need to do this early enough that we can still sleep. 284df8bae1dSRodney W. Grimes * Can't free the entire vmspace as the kernel stack 285df8bae1dSRodney W. Grimes * may be mapped within that space also. 286389d2b6eSMatthew Dillon * 287389d2b6eSMatthew Dillon * Processes sharing the same vmspace may exit in one order, and 288389d2b6eSMatthew Dillon * get cleaned up by vmspace_exit() in a different order. The 289389d2b6eSMatthew Dillon * last exiting process to reach this point releases as much of 290389d2b6eSMatthew Dillon * the environment as it can, and the last process cleaned up 291389d2b6eSMatthew Dillon * by vmspace_exit() (which decrements exitingcnt) cleans up the 292389d2b6eSMatthew Dillon * remainder. 293df8bae1dSRodney W. Grimes */ 2941a276a3fSAlan Cox atomic_add_int(&vm->vm_exitingcnt, 1); 2951a276a3fSAlan Cox do 2961a276a3fSAlan Cox refcnt = vm->vm_refcnt; 2971a276a3fSAlan Cox while (!atomic_cmpset_int(&vm->vm_refcnt, refcnt, refcnt - 1)); 2981a276a3fSAlan Cox if (refcnt == 1) { 2993db161e0SMatthew Dillon shmexit(vm); 30005ba50f5SJake Burkholder pmap_remove_pages(vmspace_pmap(vm), vm_map_min(&vm->vm_map), 30105ba50f5SJake Burkholder vm_map_max(&vm->vm_map)); 30205ba50f5SJake Burkholder (void) vm_map_remove(&vm->vm_map, vm_map_min(&vm->vm_map), 30305ba50f5SJake Burkholder vm_map_max(&vm->vm_map)); 3049d3fbbb5SJohn Dyson } 305df8bae1dSRodney W. Grimes 306ea97757aSJohn Baldwin sx_xlock(&proctree_lock); 307df8bae1dSRodney W. Grimes if (SESS_LEADER(p)) { 308830c3153SDag-Erling Smørgrav struct session *sp; 309df8bae1dSRodney W. Grimes 310f591779bSSeigo Tanimura sp = p->p_session; 311df8bae1dSRodney W. Grimes if (sp->s_ttyvp) { 31257606880SChristian S.J. Peron locked = VFS_LOCK_GIANT(sp->s_ttyvp->v_mount); 313df8bae1dSRodney W. Grimes /* 314df8bae1dSRodney W. Grimes * Controlling process. 315df8bae1dSRodney W. Grimes * Signal foreground pgrp, 316df8bae1dSRodney W. Grimes * drain controlling terminal 317df8bae1dSRodney W. Grimes * and revoke access to controlling terminal. 318df8bae1dSRodney W. Grimes */ 319dd45d8adSJulian Elischer if (sp->s_ttyp && (sp->s_ttyp->t_session == sp)) { 320f591779bSSeigo Tanimura tp = sp->s_ttyp; 321f591779bSSeigo Tanimura if (sp->s_ttyp->t_pgrp) { 322f591779bSSeigo Tanimura PGRP_LOCK(sp->s_ttyp->t_pgrp); 323df8bae1dSRodney W. Grimes pgsignal(sp->s_ttyp->t_pgrp, SIGHUP, 1); 324f591779bSSeigo Tanimura PGRP_UNLOCK(sp->s_ttyp->t_pgrp); 325f591779bSSeigo Tanimura } 326f591779bSSeigo Tanimura /* XXX tp should be locked. */ 327ea97757aSJohn Baldwin sx_xunlock(&proctree_lock); 328f591779bSSeigo Tanimura (void) ttywait(tp); 329ea97757aSJohn Baldwin sx_xlock(&proctree_lock); 330df8bae1dSRodney W. Grimes /* 331df8bae1dSRodney W. Grimes * The tty could have been revoked 332df8bae1dSRodney W. Grimes * if we blocked. 333df8bae1dSRodney W. Grimes */ 334f591779bSSeigo Tanimura if (sp->s_ttyvp) { 335f591779bSSeigo Tanimura ttyvp = sp->s_ttyvp; 336f591779bSSeigo Tanimura SESS_LOCK(p->p_session); 337df8bae1dSRodney W. Grimes sp->s_ttyvp = NULL; 338f591779bSSeigo Tanimura SESS_UNLOCK(p->p_session); 339ea97757aSJohn Baldwin sx_xunlock(&proctree_lock); 3402b3183a8SJeff Roberson VOP_LOCK(ttyvp, LK_EXCLUSIVE, td); 341f591779bSSeigo Tanimura VOP_REVOKE(ttyvp, REVOKEALL); 3422b3183a8SJeff Roberson vput(ttyvp); 343ea97757aSJohn Baldwin sx_xlock(&proctree_lock); 344f591779bSSeigo Tanimura } 345f591779bSSeigo Tanimura } 346f591779bSSeigo Tanimura if (sp->s_ttyvp) { 347f591779bSSeigo Tanimura ttyvp = sp->s_ttyvp; 348f591779bSSeigo Tanimura SESS_LOCK(p->p_session); 349f591779bSSeigo Tanimura sp->s_ttyvp = NULL; 350f591779bSSeigo Tanimura SESS_UNLOCK(p->p_session); 351f591779bSSeigo Tanimura vrele(ttyvp); 352f591779bSSeigo Tanimura } 353df8bae1dSRodney W. Grimes /* 354df8bae1dSRodney W. Grimes * s_ttyp is not zero'd; we use this to indicate 355df8bae1dSRodney W. Grimes * that the session once had a controlling terminal. 356df8bae1dSRodney W. Grimes * (for logging and informational purposes) 357df8bae1dSRodney W. Grimes */ 35857606880SChristian S.J. Peron VFS_UNLOCK_GIANT(locked); 359df8bae1dSRodney W. Grimes } 360f591779bSSeigo Tanimura SESS_LOCK(p->p_session); 361df8bae1dSRodney W. Grimes sp->s_leader = NULL; 362f591779bSSeigo Tanimura SESS_UNLOCK(p->p_session); 363f591779bSSeigo Tanimura } 364df8bae1dSRodney W. Grimes fixjobc(p, p->p_pgrp, 0); 365ea97757aSJohn Baldwin sx_xunlock(&proctree_lock); 366b40ce416SJulian Elischer (void)acct_process(td); 367df8bae1dSRodney W. Grimes #ifdef KTRACE 368df8bae1dSRodney W. Grimes /* 3692c255e9dSRobert Watson * Drain any pending records on the thread and release the trace 3702c255e9dSRobert Watson * file. It might be better if drain-and-clear were atomic. 371df8bae1dSRodney W. Grimes */ 3722c255e9dSRobert Watson ktrprocexit(td); 373d7aadbf9SJohn Baldwin PROC_LOCK(p); 3746c84de02SJohn Baldwin mtx_lock(&ktrace_mtx); 375df8bae1dSRodney W. Grimes p->p_traceflag = 0; /* don't trace the vrele() */ 376a5881ea5SJohn Baldwin tracevp = p->p_tracevp; 377a5881ea5SJohn Baldwin p->p_tracevp = NULL; 378a5881ea5SJohn Baldwin tracecred = p->p_tracecred; 379a5881ea5SJohn Baldwin p->p_tracecred = NULL; 3806c84de02SJohn Baldwin mtx_unlock(&ktrace_mtx); 381d7aadbf9SJohn Baldwin PROC_UNLOCK(p); 38215088317SBrian Feldman if (tracevp != NULL) { 38357606880SChristian S.J. Peron locked = VFS_LOCK_GIANT(tracevp->v_mount); 384d7aadbf9SJohn Baldwin vrele(tracevp); 38557606880SChristian S.J. Peron VFS_UNLOCK_GIANT(locked); 38615088317SBrian Feldman } 387a5881ea5SJohn Baldwin if (tracecred != NULL) 388a5881ea5SJohn Baldwin crfree(tracecred); 389df8bae1dSRodney W. Grimes #endif 390df8bae1dSRodney W. Grimes /* 391ee42d0a9SDavid Malone * Release reference to text vnode 392ee42d0a9SDavid Malone */ 393ee42d0a9SDavid Malone if ((vtmp = p->p_textvp) != NULL) { 394ee42d0a9SDavid Malone p->p_textvp = NULL; 39557606880SChristian S.J. Peron locked = VFS_LOCK_GIANT(vtmp->v_mount); 396ee42d0a9SDavid Malone vrele(vtmp); 39757606880SChristian S.J. Peron VFS_UNLOCK_GIANT(locked); 398ee42d0a9SDavid Malone } 399ee42d0a9SDavid Malone 400ee42d0a9SDavid Malone /* 401d7aadbf9SJohn Baldwin * Release our limits structure. 402d7aadbf9SJohn Baldwin */ 40391d5354aSJohn Baldwin PROC_LOCK(p); 40491d5354aSJohn Baldwin plim = p->p_limit; 405d7aadbf9SJohn Baldwin p->p_limit = NULL; 40691d5354aSJohn Baldwin PROC_UNLOCK(p); 40791d5354aSJohn Baldwin lim_free(plim); 408d7aadbf9SJohn Baldwin 409d7aadbf9SJohn Baldwin /* 410df8bae1dSRodney W. Grimes * Remove proc from allproc queue and pidhash chain. 411df8bae1dSRodney W. Grimes * Place onto zombproc. Unlink from parent's child list. 412df8bae1dSRodney W. Grimes */ 4131005a129SJohn Baldwin sx_xlock(&allproc_lock); 414b75356e1SJeffrey Hsu LIST_REMOVE(p, p_list); 415b75356e1SJeffrey Hsu LIST_INSERT_HEAD(&zombproc, p, p_list); 416b75356e1SJeffrey Hsu LIST_REMOVE(p, p_hash); 4171005a129SJohn Baldwin sx_xunlock(&allproc_lock); 418df8bae1dSRodney W. Grimes 4191005a129SJohn Baldwin sx_xlock(&proctree_lock); 4202e3c8fcbSPoul-Henning Kamp q = LIST_FIRST(&p->p_children); 421a914fb6bSJohn Baldwin if (q != NULL) /* only need this if any child is S_ZOMB */ 4227f05b035SAlfred Perlstein wakeup(initproc); 423a914fb6bSJohn Baldwin for (; q != NULL; q = nq) { 4242e3c8fcbSPoul-Henning Kamp nq = LIST_NEXT(q, p_sibling); 425a914fb6bSJohn Baldwin PROC_LOCK(q); 426c65437a3SJohn Baldwin proc_reparent(q, initproc); 4274ac9ae70SJulian Elischer q->p_sigparent = SIGCHLD; 428df8bae1dSRodney W. Grimes /* 429df8bae1dSRodney W. Grimes * Traced processes are killed 430df8bae1dSRodney W. Grimes * since their existence means someone is screwing up. 431df8bae1dSRodney W. Grimes */ 432df8bae1dSRodney W. Grimes if (q->p_flag & P_TRACED) { 433c2836532SDavid Xu q->p_flag &= ~(P_TRACED | P_STOPPED_TRACE); 434df8bae1dSRodney W. Grimes psignal(q, SIGKILL); 435c65437a3SJohn Baldwin } 436a914fb6bSJohn Baldwin PROC_UNLOCK(q); 437df8bae1dSRodney W. Grimes } 438df8bae1dSRodney W. Grimes 439df8bae1dSRodney W. Grimes /* 44078c85e8dSJohn Baldwin * Save exit status and finalize rusage info except for times, 44178c85e8dSJohn Baldwin * adding in child rusage info. 442df8bae1dSRodney W. Grimes */ 443d7aadbf9SJohn Baldwin PROC_LOCK(p); 444df8bae1dSRodney W. Grimes p->p_xstat = rv; 445cbf4e354SDavid Xu p->p_xthread = td; 44678c85e8dSJohn Baldwin p->p_stats->p_ru.ru_nvcsw++; 447df8bae1dSRodney W. Grimes *p->p_ru = p->p_stats->p_ru; 44878c85e8dSJohn Baldwin ruadd(p->p_ru, &p->p_rux, &p->p_stats->p_cru, &p->p_crux); 449df8bae1dSRodney W. Grimes 450df8bae1dSRodney W. Grimes /* 4517a6b989bSJohn Baldwin * Notify interested parties of our demise. 452cb679c38SJonathan Lemon */ 453ad3b9257SJohn-Mark Gurney KNOTE_LOCKED(&p->p_klist, NOTE_EXIT); 4547eaec467SJohn Baldwin 4551a29c806SOlivier Houchard /* 4561a29c806SOlivier Houchard * Just delete all entries in the p_klist. At this point we won't 4571a29c806SOlivier Houchard * report any more events, and there are nasty race conditions that 4581a29c806SOlivier Houchard * can beat us if we don't. 4591a29c806SOlivier Houchard */ 460ad3b9257SJohn-Mark Gurney knlist_clear(&p->p_klist, 1); 461cb679c38SJonathan Lemon 462cb679c38SJonathan Lemon /* 463645682fdSLuoqi Chen * Notify parent that we're gone. If parent has the PS_NOCLDWAIT 464ba1551caSIan Dowse * flag set, or if the handler is set to SIG_IGN, notify process 465ba1551caSIan Dowse * 1 instead (and hope it will handle this situation). 466df8bae1dSRodney W. Grimes */ 467d7aadbf9SJohn Baldwin PROC_LOCK(p->p_pptr); 46890af4afaSJohn Baldwin mtx_lock(&p->p_pptr->p_sigacts->ps_mtx); 46990af4afaSJohn Baldwin if (p->p_pptr->p_sigacts->ps_flag & (PS_NOCLDWAIT | PS_CLDSIGIGN)) { 470276c5169SJohn Baldwin struct proc *pp; 471276c5169SJohn Baldwin 47290af4afaSJohn Baldwin mtx_unlock(&p->p_pptr->p_sigacts->ps_mtx); 473276c5169SJohn Baldwin pp = p->p_pptr; 474f591779bSSeigo Tanimura PROC_UNLOCK(pp); 475245f17d4SJoerg Wunsch proc_reparent(p, initproc); 47655b5f2a2SDon Lewis p->p_sigparent = SIGCHLD; 477f591779bSSeigo Tanimura PROC_LOCK(p->p_pptr); 478245f17d4SJoerg Wunsch /* 479245f17d4SJoerg Wunsch * If this was the last child of our parent, notify 480245f17d4SJoerg Wunsch * parent, so in case he was wait(2)ing, he will 481245f17d4SJoerg Wunsch * continue. 482245f17d4SJoerg Wunsch */ 483245f17d4SJoerg Wunsch if (LIST_EMPTY(&pp->p_children)) 4847f05b035SAlfred Perlstein wakeup(pp); 48590af4afaSJohn Baldwin } else 48690af4afaSJohn Baldwin mtx_unlock(&p->p_pptr->p_sigacts->ps_mtx); 487245f17d4SJoerg Wunsch 4886567eef7SDon Lewis if (p->p_pptr == initproc) 4896626c604SJulian Elischer psignal(p->p_pptr, SIGCHLD); 490ebceaf6dSDavid Xu else if (p->p_sigparent != 0) { 491ebceaf6dSDavid Xu if (p->p_sigparent == SIGCHLD) 492ebceaf6dSDavid Xu childproc_exited(p); 493ebceaf6dSDavid Xu else /* LINUX thread */ 4946567eef7SDon Lewis psignal(p->p_pptr, p->p_sigparent); 495ebceaf6dSDavid Xu } 496c65437a3SJohn Baldwin PROC_UNLOCK(p->p_pptr); 497776e0b36SJohn Baldwin 498776e0b36SJohn Baldwin /* 499776e0b36SJohn Baldwin * If this is a kthread, then wakeup anyone waiting for it to exit. 500776e0b36SJohn Baldwin */ 501776e0b36SJohn Baldwin if (p->p_flag & P_KTHREAD) 5027f05b035SAlfred Perlstein wakeup(p); 503c65437a3SJohn Baldwin PROC_UNLOCK(p); 5048e2e767bSJohn Baldwin 5058e2e767bSJohn Baldwin /* 506df8bae1dSRodney W. Grimes * Finally, call machine-dependent code to release the remaining 507696058c3SJulian Elischer * resources including address space. 508582ec34cSAlfred Perlstein * The address space is released by "vmspace_exitfree(p)" in 509582ec34cSAlfred Perlstein * vm_waitproc(). 510df8bae1dSRodney W. Grimes */ 511b40ce416SJulian Elischer cpu_exit(td); 512eb30c1c0SPeter Wemm 51383de502dSJohn Baldwin WITNESS_WARN(WARN_PANIC, &proctree_lock.sx_object, 51483de502dSJohn Baldwin "process (pid %d) exiting", p->p_pid); 51583de502dSJohn Baldwin 516eb30c1c0SPeter Wemm PROC_LOCK(p); 517d7aadbf9SJohn Baldwin PROC_LOCK(p->p_pptr); 518d7aadbf9SJohn Baldwin sx_xunlock(&proctree_lock); 519696058c3SJulian Elischer 520eb30c1c0SPeter Wemm /* 521462f31bfSJohn Baldwin * We have to wait until after acquiring all locks before 522a9a64385SJohn Baldwin * changing p_state. We need to avoid all possible context 523a9a64385SJohn Baldwin * switches (including ones from blocking on a mutex) while 524ddf9c4f7SJohn Baldwin * marked as a zombie. We also have to set the zombie state 525ddf9c4f7SJohn Baldwin * before we release the parent process' proc lock to avoid 526ddf9c4f7SJohn Baldwin * a lost wakeup. So, we first call wakeup, then we grab the 527ddf9c4f7SJohn Baldwin * sched lock, update the state, and release the parent process' 528ddf9c4f7SJohn Baldwin * proc lock. 529eb30c1c0SPeter Wemm */ 530ddf9c4f7SJohn Baldwin wakeup(p->p_pptr); 531e5bb601dSJohn Baldwin mtx_lock_spin(&sched_lock); 532e602ba25SJulian Elischer p->p_state = PRS_ZOMBIE; 533d7aadbf9SJohn Baldwin PROC_UNLOCK(p->p_pptr); 534871684b8SBruce Evans 535871684b8SBruce Evans /* Do the same timestamp bookkeeping that mi_switch() would do. */ 536871684b8SBruce Evans binuptime(&new_switchtime); 53778c85e8dSJohn Baldwin bintime_add(&p->p_rux.rux_runtime, &new_switchtime); 53878c85e8dSJohn Baldwin bintime_sub(&p->p_rux.rux_runtime, PCPU_PTR(switchtime)); 539871684b8SBruce Evans PCPU_SET(switchtime, new_switchtime); 540d7aadbf9SJohn Baldwin PCPU_SET(switchticks, ticks); 541871684b8SBruce Evans cnt.v_swtch++; 542a9a64385SJohn Baldwin 54355d44f79SJulian Elischer sched_exit(p->p_pptr, td); 544f6f230feSJeff Roberson 545f6f230feSJeff Roberson /* 5467eaec467SJohn Baldwin * Hopefully no one will try to deliver a signal to the process this 547ad3b9257SJohn-Mark Gurney * late in the game. 548ad3b9257SJohn-Mark Gurney */ 549ad3b9257SJohn-Mark Gurney knlist_destroy(&p->p_klist); 550ad3b9257SJohn-Mark Gurney 551ad3b9257SJohn-Mark Gurney /* 552696058c3SJulian Elischer * Make sure the scheduler takes this thread out of its tables etc. 553e602ba25SJulian Elischer * This will also release this thread's reference to the ucred. 554696058c3SJulian Elischer * Other thread parts to release include pcb bits and such. 555e602ba25SJulian Elischer */ 556e602ba25SJulian Elischer thread_exit(); 557df8bae1dSRodney W. Grimes } 558df8bae1dSRodney W. Grimes 559b2f9e8b1SBruce Evans #ifdef COMPAT_43 560234216efSMatthew Dillon /* 561a9a64385SJohn Baldwin * The dirty work is handled by kern_wait(). 562a9a64385SJohn Baldwin * 563a9a64385SJohn Baldwin * MPSAFE. 564234216efSMatthew Dillon */ 56526f9a767SRodney W. Grimes int 566830c3153SDag-Erling Smørgrav owait(struct thread *td, struct owait_args *uap __unused) 567df8bae1dSRodney W. Grimes { 568b7e23e82SJohn Baldwin int error, status; 569df8bae1dSRodney W. Grimes 570b7e23e82SJohn Baldwin error = kern_wait(td, WAIT_ANY, &status, 0, NULL); 571b7e23e82SJohn Baldwin if (error == 0) 572b7e23e82SJohn Baldwin td->td_retval[1] = status; 573b7e23e82SJohn Baldwin return (error); 574df8bae1dSRodney W. Grimes } 575b2f9e8b1SBruce Evans #endif /* COMPAT_43 */ 576df8bae1dSRodney W. Grimes 577234216efSMatthew Dillon /* 578a9a64385SJohn Baldwin * The dirty work is handled by kern_wait(). 579a9a64385SJohn Baldwin * 580a9a64385SJohn Baldwin * MPSAFE. 581234216efSMatthew Dillon */ 58226f9a767SRodney W. Grimes int 583830c3153SDag-Erling Smørgrav wait4(struct thread *td, struct wait_args *uap) 584df8bae1dSRodney W. Grimes { 58578c85e8dSJohn Baldwin struct rusage ru, *rup; 586b7e23e82SJohn Baldwin int error, status; 587b40ce416SJulian Elischer 58878c85e8dSJohn Baldwin if (uap->rusage != NULL) 58978c85e8dSJohn Baldwin rup = &ru; 59078c85e8dSJohn Baldwin else 59178c85e8dSJohn Baldwin rup = NULL; 59278c85e8dSJohn Baldwin error = kern_wait(td, uap->pid, &status, uap->options, rup); 593b7e23e82SJohn Baldwin if (uap->status != NULL && error == 0) 594b7e23e82SJohn Baldwin error = copyout(&status, uap->status, sizeof(status)); 595b7e23e82SJohn Baldwin if (uap->rusage != NULL && error == 0) 596b7e23e82SJohn Baldwin error = copyout(&ru, uap->rusage, sizeof(struct rusage)); 597b7e23e82SJohn Baldwin return (error); 598df8bae1dSRodney W. Grimes } 599df8bae1dSRodney W. Grimes 600b7e23e82SJohn Baldwin int 6017eaec467SJohn Baldwin kern_wait(struct thread *td, pid_t pid, int *status, int options, 6027eaec467SJohn Baldwin struct rusage *rusage) 603df8bae1dSRodney W. Grimes { 60448bfcdddSJulian Elischer struct proc *p, *q, *t; 605a9a64385SJohn Baldwin int error, nfound; 606df8bae1dSRodney W. Grimes 607b40ce416SJulian Elischer q = td->td_proc; 608b7e23e82SJohn Baldwin if (pid == 0) { 609f591779bSSeigo Tanimura PROC_LOCK(q); 610b7e23e82SJohn Baldwin pid = -q->p_pgid; 611f591779bSSeigo Tanimura PROC_UNLOCK(q); 612f591779bSSeigo Tanimura } 613b7e23e82SJohn Baldwin if (options &~ (WUNTRACED|WNOHANG|WCONTINUED|WLINUXCLONE)) 6146dc958b9SJohn Baldwin return (EINVAL); 615df8bae1dSRodney W. Grimes loop: 616902c0d82SDavid Xu if (q->p_flag & P_STATCHILD) { 617902c0d82SDavid Xu PROC_LOCK(q); 618902c0d82SDavid Xu q->p_flag &= ~P_STATCHILD; 619902c0d82SDavid Xu PROC_UNLOCK(q); 620902c0d82SDavid Xu } 621df8bae1dSRodney W. Grimes nfound = 0; 622d7aadbf9SJohn Baldwin sx_xlock(&proctree_lock); 6232e3c8fcbSPoul-Henning Kamp LIST_FOREACH(p, &q->p_children, p_sibling) { 624f591779bSSeigo Tanimura PROC_LOCK(p); 625b7e23e82SJohn Baldwin if (pid != WAIT_ANY && 626b7e23e82SJohn Baldwin p->p_pid != pid && p->p_pgid != -pid) { 627f591779bSSeigo Tanimura PROC_UNLOCK(p); 628df8bae1dSRodney W. Grimes continue; 629f591779bSSeigo Tanimura } 630babe9a2bSRobert Watson if (p_canwait(td, p)) { 631babe9a2bSRobert Watson PROC_UNLOCK(p); 632babe9a2bSRobert Watson continue; 633babe9a2bSRobert Watson } 6344ac9ae70SJulian Elischer 6351156bc4dSJake Burkholder /* 6361156bc4dSJake Burkholder * This special case handles a kthread spawned by linux_clone 6371156bc4dSJake Burkholder * (see linux_misc.c). The linux_wait4 and linux_waitpid 6381156bc4dSJake Burkholder * functions need to be able to distinguish between waiting 6391156bc4dSJake Burkholder * on a process and waiting on a thread. It is a thread if 6401156bc4dSJake Burkholder * p_sigparent is not SIGCHLD, and the WLINUXCLONE option 6411156bc4dSJake Burkholder * signifies we want to wait for threads and not processes. 6424ac9ae70SJulian Elischer */ 6431156bc4dSJake Burkholder if ((p->p_sigparent != SIGCHLD) ^ 644b7e23e82SJohn Baldwin ((options & WLINUXCLONE) != 0)) { 645a914fb6bSJohn Baldwin PROC_UNLOCK(p); 6464ac9ae70SJulian Elischer continue; 647a914fb6bSJohn Baldwin } 6484ac9ae70SJulian Elischer 649df8bae1dSRodney W. Grimes nfound++; 650e602ba25SJulian Elischer if (p->p_state == PRS_ZOMBIE) { 651ddf9c4f7SJohn Baldwin 652ddf9c4f7SJohn Baldwin /* 653ddf9c4f7SJohn Baldwin * It is possible that the last thread of this 654ddf9c4f7SJohn Baldwin * process is still running on another CPU 655ddf9c4f7SJohn Baldwin * in thread_exit() after having dropped the process 656ddf9c4f7SJohn Baldwin * lock via PROC_UNLOCK() but before it has completed 657ddf9c4f7SJohn Baldwin * cpu_throw(). In that case, the other thread must 658ddf9c4f7SJohn Baldwin * still hold sched_lock, so simply by acquiring 659ddf9c4f7SJohn Baldwin * sched_lock once we will wait long enough for the 660ddf9c4f7SJohn Baldwin * thread to exit in that case. 661ddf9c4f7SJohn Baldwin */ 662ddf9c4f7SJohn Baldwin mtx_lock_spin(&sched_lock); 663ddf9c4f7SJohn Baldwin mtx_unlock_spin(&sched_lock); 664ddf9c4f7SJohn Baldwin 665b40ce416SJulian Elischer td->td_retval[0] = p->p_pid; 666b7e23e82SJohn Baldwin if (status) 667b7e23e82SJohn Baldwin *status = p->p_xstat; /* convert to int */ 66878c85e8dSJohn Baldwin if (rusage) { 669fd544ee8SRobert Watson *rusage = *p->p_ru; 67078c85e8dSJohn Baldwin calcru(p, &rusage->ru_utime, &rusage->ru_stime); 67178c85e8dSJohn Baldwin } 672b7e23e82SJohn Baldwin 673ebceaf6dSDavid Xu PROC_LOCK(q); 674ebceaf6dSDavid Xu sigqueue_take(p->p_ksi); 675ebceaf6dSDavid Xu PROC_UNLOCK(q); 676ebceaf6dSDavid Xu 677df8bae1dSRodney W. Grimes /* 678df8bae1dSRodney W. Grimes * If we got the child via a ptrace 'attach', 679df8bae1dSRodney W. Grimes * we need to give it back to the old parent. 680df8bae1dSRodney W. Grimes */ 681b7e23e82SJohn Baldwin PROC_UNLOCK(p); 682d7aadbf9SJohn Baldwin if (p->p_oppid && (t = pfind(p->p_oppid)) != NULL) { 683c65437a3SJohn Baldwin PROC_LOCK(p); 684df8bae1dSRodney W. Grimes p->p_oppid = 0; 685df8bae1dSRodney W. Grimes proc_reparent(p, t); 686c65437a3SJohn Baldwin PROC_UNLOCK(p); 687ebceaf6dSDavid Xu tdsignal(t, NULL, SIGCHLD, p->p_ksi); 6887f05b035SAlfred Perlstein wakeup(t); 689c65437a3SJohn Baldwin PROC_UNLOCK(t); 6901005a129SJohn Baldwin sx_xunlock(&proctree_lock); 691d7aadbf9SJohn Baldwin return (0); 692df8bae1dSRodney W. Grimes } 693ebdc3f1dSSeigo Tanimura 6943890793eSTim J. Robbins /* 6953890793eSTim J. Robbins * Remove other references to this process to ensure 6963890793eSTim J. Robbins * we have an exclusive reference. 6973890793eSTim J. Robbins */ 6986ec62361STim J. Robbins sx_xlock(&allproc_lock); 6996ec62361STim J. Robbins LIST_REMOVE(p, p_list); /* off zombproc */ 7006ec62361STim J. Robbins sx_xunlock(&allproc_lock); 7016ec62361STim J. Robbins LIST_REMOVE(p, p_sibling); 7023890793eSTim J. Robbins leavepgrp(p); 703ebdc3f1dSSeigo Tanimura sx_xunlock(&proctree_lock); 704ebdc3f1dSSeigo Tanimura 705ebdc3f1dSSeigo Tanimura /* 706d7aadbf9SJohn Baldwin * As a side effect of this lock, we know that 707d7aadbf9SJohn Baldwin * all other writes to this proc are visible now, so 708d7aadbf9SJohn Baldwin * no more locking is needed for p. 709d7aadbf9SJohn Baldwin */ 710d7aadbf9SJohn Baldwin PROC_LOCK(p); 711d7aadbf9SJohn Baldwin p->p_xstat = 0; /* XXX: why? */ 712d7aadbf9SJohn Baldwin PROC_UNLOCK(p); 713d7aadbf9SJohn Baldwin PROC_LOCK(q); 71478c85e8dSJohn Baldwin ruadd(&q->p_stats->p_cru, &q->p_crux, p->p_ru, 71578c85e8dSJohn Baldwin &p->p_rux); 716d7aadbf9SJohn Baldwin PROC_UNLOCK(q); 717d7aadbf9SJohn Baldwin FREE(p->p_ru, M_ZOMBIE); 718d7aadbf9SJohn Baldwin p->p_ru = NULL; 719d7aadbf9SJohn Baldwin 720d7aadbf9SJohn Baldwin /* 721d7aadbf9SJohn Baldwin * Decrement the count of procs running with this uid. 722d7aadbf9SJohn Baldwin */ 723d7aadbf9SJohn Baldwin (void)chgproccnt(p->p_ucred->cr_ruidinfo, -1, 0); 724d7aadbf9SJohn Baldwin 725d7aadbf9SJohn Baldwin /* 726a9a64385SJohn Baldwin * Free credentials, arguments, and sigacts. 727df8bae1dSRodney W. Grimes */ 728da654d90SPoul-Henning Kamp crfree(p->p_ucred); 72990af4afaSJohn Baldwin p->p_ucred = NULL; 730d7aadbf9SJohn Baldwin pargs_drop(p->p_args); 731d7aadbf9SJohn Baldwin p->p_args = NULL; 73290af4afaSJohn Baldwin sigacts_free(p->p_sigacts); 73390af4afaSJohn Baldwin p->p_sigacts = NULL; 73488c5ea45SJulian Elischer 735df8bae1dSRodney W. Grimes /* 736a9a64385SJohn Baldwin * Do any thread-system specific cleanups. 737e602ba25SJulian Elischer */ 738696058c3SJulian Elischer thread_wait(p); 739e602ba25SJulian Elischer 740e602ba25SJulian Elischer /* 741eb30c1c0SPeter Wemm * Give vm and machine-dependent layer a chance 742df8bae1dSRodney W. Grimes * to free anything that cpu_exit couldn't 743df8bae1dSRodney W. Grimes * release while still running in process context. 744df8bae1dSRodney W. Grimes */ 745eb30c1c0SPeter Wemm vm_waitproc(p); 7462555374cSRobert Watson #ifdef MAC 7472555374cSRobert Watson mac_destroy_proc(p); 7482555374cSRobert Watson #endif 7491faf202eSJulian Elischer KASSERT(FIRST_THREAD_IN_PROC(p), 750b7e23e82SJohn Baldwin ("kern_wait: no residual thread!")); 751c897b813SJeff Roberson uma_zfree(proc_zone, p); 752d7aadbf9SJohn Baldwin sx_xlock(&allproc_lock); 753df8bae1dSRodney W. Grimes nprocs--; 754d7aadbf9SJohn Baldwin sx_xunlock(&allproc_lock); 755d7aadbf9SJohn Baldwin return (0); 756df8bae1dSRodney W. Grimes } 757112afcb2SJohn Baldwin mtx_lock_spin(&sched_lock); 7585a2f73e6SDavid Xu if ((p->p_flag & P_STOPPED_SIG) && 7595a2f73e6SDavid Xu (p->p_suspcount == p->p_numthreads) && 760a9a64385SJohn Baldwin (p->p_flag & P_WAITED) == 0 && 761b7e23e82SJohn Baldwin (p->p_flag & P_TRACED || options & WUNTRACED)) { 762112afcb2SJohn Baldwin mtx_unlock_spin(&sched_lock); 763df8bae1dSRodney W. Grimes p->p_flag |= P_WAITED; 764d7aadbf9SJohn Baldwin sx_xunlock(&proctree_lock); 765b40ce416SJulian Elischer td->td_retval[0] = p->p_pid; 766b7e23e82SJohn Baldwin if (status) 767b7e23e82SJohn Baldwin *status = W_STOPCODE(p->p_xstat); 768d7aadbf9SJohn Baldwin PROC_UNLOCK(p); 769ebceaf6dSDavid Xu 770ebceaf6dSDavid Xu PROC_LOCK(q); 771ebceaf6dSDavid Xu sigqueue_take(p->p_ksi); 772ebceaf6dSDavid Xu PROC_UNLOCK(q); 773ebceaf6dSDavid Xu 774b7e23e82SJohn Baldwin return (0); 775df8bae1dSRodney W. Grimes } 776112afcb2SJohn Baldwin mtx_unlock_spin(&sched_lock); 777b7e23e82SJohn Baldwin if (options & WCONTINUED && (p->p_flag & P_CONTINUED)) { 7786ee093fbSMike Barcroft sx_xunlock(&proctree_lock); 7796ee093fbSMike Barcroft td->td_retval[0] = p->p_pid; 7806ee093fbSMike Barcroft p->p_flag &= ~P_CONTINUED; 7816ee093fbSMike Barcroft PROC_UNLOCK(p); 7826ee093fbSMike Barcroft 783ebceaf6dSDavid Xu PROC_LOCK(q); 784ebceaf6dSDavid Xu sigqueue_take(p->p_ksi); 785ebceaf6dSDavid Xu PROC_UNLOCK(q); 786ebceaf6dSDavid Xu 787b7e23e82SJohn Baldwin if (status) 788b7e23e82SJohn Baldwin *status = SIGCONT; 789b7e23e82SJohn Baldwin return (0); 7906ee093fbSMike Barcroft } 791d7aadbf9SJohn Baldwin PROC_UNLOCK(p); 792d7aadbf9SJohn Baldwin } 793d7aadbf9SJohn Baldwin if (nfound == 0) { 794d7aadbf9SJohn Baldwin sx_xunlock(&proctree_lock); 795d7aadbf9SJohn Baldwin return (ECHILD); 796d7aadbf9SJohn Baldwin } 797b7e23e82SJohn Baldwin if (options & WNOHANG) { 798d7aadbf9SJohn Baldwin sx_xunlock(&proctree_lock); 799d7aadbf9SJohn Baldwin td->td_retval[0] = 0; 800d7aadbf9SJohn Baldwin return (0); 801d7aadbf9SJohn Baldwin } 802d7aadbf9SJohn Baldwin PROC_LOCK(q); 803d7aadbf9SJohn Baldwin sx_xunlock(&proctree_lock); 80495992d56SDavid Xu if (q->p_flag & P_STATCHILD) { 80595992d56SDavid Xu q->p_flag &= ~P_STATCHILD; 80695992d56SDavid Xu error = 0; 80795992d56SDavid Xu } else 8087f05b035SAlfred Perlstein error = msleep(q, &q->p_mtx, PWAIT | PCATCH, "wait", 0); 809d7aadbf9SJohn Baldwin PROC_UNLOCK(q); 8104ae89b95SJohn Baldwin if (error) 811d7aadbf9SJohn Baldwin return (error); 812d7aadbf9SJohn Baldwin goto loop; 813d7aadbf9SJohn Baldwin } 814df8bae1dSRodney W. Grimes 815df8bae1dSRodney W. Grimes /* 81698f03f90SJake Burkholder * Make process 'parent' the new parent of process 'child'. 81798f03f90SJake Burkholder * Must be called with an exclusive hold of proctree lock. 818df8bae1dSRodney W. Grimes */ 819df8bae1dSRodney W. Grimes void 820830c3153SDag-Erling Smørgrav proc_reparent(struct proc *child, struct proc *parent) 821df8bae1dSRodney W. Grimes { 822df8bae1dSRodney W. Grimes 8234e5e677bSJohn Baldwin sx_assert(&proctree_lock, SX_XLOCKED); 824c65437a3SJohn Baldwin PROC_LOCK_ASSERT(child, MA_OWNED); 825df8bae1dSRodney W. Grimes if (child->p_pptr == parent) 826df8bae1dSRodney W. Grimes return; 827df8bae1dSRodney W. Grimes 828b75356e1SJeffrey Hsu LIST_REMOVE(child, p_sibling); 829b75356e1SJeffrey Hsu LIST_INSERT_HEAD(&parent->p_children, child, p_sibling); 830df8bae1dSRodney W. Grimes child->p_pptr = parent; 831df8bae1dSRodney W. Grimes } 832