diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 07b5a1eb611f..20a186ee206d 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -862,6 +862,8 @@ proc_reap(struct thread *td, struct proc *p, int *status, int options) return; } p->p_oppid = 0; + + p->p_state = PRS_DEAD; PROC_UNLOCK(p); /* diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 11e09e3687ec..9b56bbe2dcaa 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -131,8 +131,10 @@ struct pidhashhead *pidhashtbl; u_long pidhash; struct pgrphashhead *pgrphashtbl; u_long pgrphash; +struct proclist allocatedproc; struct proclist allproc; struct proclist zombproc; +struct sx __exclusive_cache_line allocatedproc_lock; struct sx __exclusive_cache_line allproc_lock; struct sx __exclusive_cache_line proctree_lock; struct mtx __exclusive_cache_line ppeers_lock; @@ -184,6 +186,7 @@ void procinit(void) { + sx_init(&allocatedproc_lock, "allocatedproc"); sx_init(&allproc_lock, "allproc"); sx_init(&proctree_lock, "proctree"); mtx_init(&ppeers_lock, "p_peers", NULL, MTX_DEF); @@ -215,6 +218,12 @@ proc_ctor(void *mem, int size, void *arg, int flags) /* Make sure all thread constructors are executed */ EVENTHANDLER_DIRECT_INVOKE(thread_ctor, td); } + if (!p->p_onalloclist) { + sx_xlock(&allocatedproc_lock); + LIST_INSERT_HEAD(&allocatedproc, p, p_alloclist); + sx_xunlock(&allocatedproc_lock); + p->p_onalloclist = 1; + } return (0); } @@ -272,6 +281,8 @@ proc_init(void *mem, int size, int flags) EVENTHANDLER_DIRECT_INVOKE(process_init, p); p->p_stats = pstats_alloc(); p->p_pgrp = NULL; + p->p_state = PRS_DEAD; + p->p_onalloclist = 0; SDT_PROBE3(proc, , init, return, p, size, flags); return (0); } diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 4da8bdf3a300..1be2653930ee 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1675,13 +1675,24 @@ killpg1(struct thread *td, int sig, int pgid, int all, ksiginfo_t *ksi) /* * broadcast */ - sx_slock(&allproc_lock); - FOREACH_PROC_IN_SYSTEM(p) { + sx_slock(&allocatedproc_lock); + FOREACH_ALLOCATED_PROC_IN_SYSTEM(p) { + if (p->p_state == PRS_DEAD) + continue; if (p->p_pid <= 1 || p->p_flag & P_SYSTEM || p == td->td_proc || p->p_state == PRS_NEW) { continue; } PROC_LOCK(p); + if (p->p_state == PRS_DEAD) { + PROC_UNLOCK(p); + continue; + } + if (p->p_pid <= 1 || p->p_flag & P_SYSTEM || + p == td->td_proc || p->p_state == PRS_NEW) { + PROC_UNLOCK(p); + continue; + } err = p_cansignal(td, p, sig); if (err == 0) { if (sig) @@ -1692,7 +1703,7 @@ killpg1(struct thread *td, int sig, int pgid, int all, ksiginfo_t *ksi) ret = err; PROC_UNLOCK(p); } - sx_sunlock(&allproc_lock); + sx_sunlock(&allocatedproc_lock); } else { sx_slock(&proctree_lock); if (pgid == 0) { diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 9bc75db8591a..ed11e2e323c7 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -560,7 +560,8 @@ struct proc { enum { PRS_NEW = 0, /* In creation */ PRS_NORMAL, /* threads can be run. */ - PRS_ZOMBIE + PRS_ZOMBIE, + PRS_DEAD, } p_state; /* (j/c) Process status. */ pid_t p_pid; /* (b) Process identifier. */ LIST_ENTRY(proc) p_hash; /* (d) Hash chain. */ @@ -670,6 +671,8 @@ struct proc { */ LIST_ENTRY(proc) p_orphan; /* (e) List of orphan processes. */ LIST_HEAD(, proc) p_orphans; /* (e) Pointer to list of orphans. */ + LIST_ENTRY(proc) p_alloclist; /* (d) List of allocated processes. */ + int p_onalloclist; }; #define p_session p_pgrp->pg_session @@ -797,6 +800,8 @@ MALLOC_DECLARE(M_SESSION); MALLOC_DECLARE(M_SUBPROC); #endif +#define FOREACH_ALLOCATED_PROC_IN_SYSTEM(p) \ + LIST_FOREACH((p), &allocatedproc, p_list) #define FOREACH_PROC_IN_SYSTEM(p) \ LIST_FOREACH((p), &allproc, p_list) #define FOREACH_THREAD_IN_PROC(p, td) \ @@ -940,6 +945,7 @@ extern struct rwlock tidhash_lock; extern LIST_HEAD(pgrphashhead, pgrp) *pgrphashtbl; extern u_long pgrphash; +extern struct sx allocatedproc_lock; extern struct sx allproc_lock; extern int allproc_gen; extern struct sx proctree_lock; @@ -957,6 +963,7 @@ extern u_long ps_arg_cache_limit; LIST_HEAD(proclist, proc); TAILQ_HEAD(procqueue, proc); TAILQ_HEAD(threadqueue, thread); +extern struct proclist allocatedproc; /* List of all allocated processes. */ extern struct proclist allproc; /* List of all processes. */ extern struct proclist zombproc; /* List of zombie processes. */ extern struct proc *initproc, *pageproc; /* Process slots for init, pager. */