mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
proc: always store parent pid in p_oppid
Doing so removes the dependency on proctree lock from sysctl process list export which further reduces contention during poudriere -j 128 runs. Reviewed by: kib (previous version) Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D17825
This commit is contained in:
parent
14343799dc
commit
2c054ce924
9 changed files with 25 additions and 57 deletions
|
|
@ -235,7 +235,7 @@ linux_clone_proc(struct thread *td, struct linux_clone_args *args)
|
|||
if (args->flags & LINUX_CLONE_PARENT) {
|
||||
sx_xlock(&proctree_lock);
|
||||
PROC_LOCK(p2);
|
||||
proc_reparent(p2, td->td_proc->p_pptr);
|
||||
proc_reparent(p2, td->td_proc->p_pptr, true);
|
||||
PROC_UNLOCK(p2);
|
||||
sx_xunlock(&proctree_lock);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,14 +107,9 @@ proc_realparent(struct proc *child)
|
|||
struct proc *p, *parent;
|
||||
|
||||
sx_assert(&proctree_lock, SX_LOCKED);
|
||||
if ((child->p_treeflag & P_TREE_ORPHANED) == 0) {
|
||||
if (child->p_oppid == 0 ||
|
||||
child->p_pptr->p_pid == child->p_oppid)
|
||||
parent = child->p_pptr;
|
||||
else
|
||||
parent = initproc;
|
||||
return (parent);
|
||||
}
|
||||
if ((child->p_treeflag & P_TREE_ORPHANED) == 0)
|
||||
return (child->p_pptr->p_pid == child->p_oppid ?
|
||||
child->p_pptr : initproc);
|
||||
for (p = child; (p->p_treeflag & P_TREE_FIRST_ORPHAN) == 0;) {
|
||||
/* Cannot use LIST_PREV(), since the list head is not known. */
|
||||
p = __containerof(p->p_orphan.le_prev, struct proc,
|
||||
|
|
@ -144,7 +139,7 @@ reaper_abandon_children(struct proc *p, bool exiting)
|
|||
LIST_INSERT_HEAD(&p1->p_reaplist, p2, p_reapsibling);
|
||||
if (exiting && p2->p_pptr == p) {
|
||||
PROC_LOCK(p2);
|
||||
proc_reparent(p2, p1);
|
||||
proc_reparent(p2, p1, true);
|
||||
PROC_UNLOCK(p2);
|
||||
}
|
||||
}
|
||||
|
|
@ -458,7 +453,7 @@ exit1(struct thread *td, int rval, int signo)
|
|||
q->p_sigparent = SIGCHLD;
|
||||
|
||||
if (!(q->p_flag & P_TRACED)) {
|
||||
proc_reparent(q, q->p_reaper);
|
||||
proc_reparent(q, q->p_reaper, true);
|
||||
if (q->p_state == PRS_ZOMBIE) {
|
||||
/*
|
||||
* Inform reaper about the reparented
|
||||
|
|
@ -494,10 +489,10 @@ exit1(struct thread *td, int rval, int signo)
|
|||
*/
|
||||
t = proc_realparent(q);
|
||||
if (t == p) {
|
||||
proc_reparent(q, q->p_reaper);
|
||||
proc_reparent(q, q->p_reaper, true);
|
||||
} else {
|
||||
PROC_LOCK(t);
|
||||
proc_reparent(q, t);
|
||||
proc_reparent(q, t, true);
|
||||
PROC_UNLOCK(t);
|
||||
}
|
||||
/*
|
||||
|
|
@ -589,7 +584,7 @@ exit1(struct thread *td, int rval, int signo)
|
|||
mtx_unlock(&p->p_pptr->p_sigacts->ps_mtx);
|
||||
pp = p->p_pptr;
|
||||
PROC_UNLOCK(pp);
|
||||
proc_reparent(p, p->p_reaper);
|
||||
proc_reparent(p, p->p_reaper, true);
|
||||
p->p_sigparent = SIGCHLD;
|
||||
PROC_LOCK(p->p_pptr);
|
||||
|
||||
|
|
@ -855,7 +850,7 @@ proc_reap(struct thread *td, struct proc *p, int *status, int options)
|
|||
* If we got the child via a ptrace 'attach', we need to give it back
|
||||
* to the old parent.
|
||||
*/
|
||||
if (p->p_oppid != 0 && p->p_oppid != p->p_pptr->p_pid) {
|
||||
if (p->p_oppid != p->p_pptr->p_pid) {
|
||||
PROC_UNLOCK(p);
|
||||
t = proc_realparent(p);
|
||||
PROC_LOCK(t);
|
||||
|
|
@ -863,8 +858,7 @@ proc_reap(struct thread *td, struct proc *p, int *status, int options)
|
|||
CTR2(KTR_PTRACE,
|
||||
"wait: traced child %d moved back to parent %d", p->p_pid,
|
||||
t->p_pid);
|
||||
proc_reparent(p, t);
|
||||
p->p_oppid = 0;
|
||||
proc_reparent(p, t, false);
|
||||
PROC_UNLOCK(p);
|
||||
pksignal(t, SIGCHLD, p->p_ksi);
|
||||
wakeup(t);
|
||||
|
|
@ -873,7 +867,6 @@ proc_reap(struct thread *td, struct proc *p, int *status, int options)
|
|||
sx_xunlock(&proctree_lock);
|
||||
return;
|
||||
}
|
||||
p->p_oppid = 0;
|
||||
PROC_UNLOCK(p);
|
||||
|
||||
/*
|
||||
|
|
@ -1333,7 +1326,7 @@ loop_locked:
|
|||
* Must be called with an exclusive hold of proctree lock.
|
||||
*/
|
||||
void
|
||||
proc_reparent(struct proc *child, struct proc *parent)
|
||||
proc_reparent(struct proc *child, struct proc *parent, bool set_oppid)
|
||||
{
|
||||
|
||||
sx_assert(&proctree_lock, SX_XLOCKED);
|
||||
|
|
@ -1361,4 +1354,6 @@ proc_reparent(struct proc *child, struct proc *parent)
|
|||
}
|
||||
|
||||
child->p_pptr = parent;
|
||||
if (set_oppid)
|
||||
child->p_oppid = parent->p_pid;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -643,6 +643,7 @@ do_fork(struct thread *td, struct fork_req *fr, struct proc *p2, struct thread *
|
|||
pptr = p1;
|
||||
}
|
||||
p2->p_pptr = pptr;
|
||||
p2->p_oppid = pptr->p_pid;
|
||||
LIST_INSERT_HEAD(&pptr->p_children, p2, p_sibling);
|
||||
LIST_INIT(&p2->p_reaplist);
|
||||
LIST_INSERT_HEAD(&p2->p_reaper->p_reaplist, p2, p_reapsibling);
|
||||
|
|
@ -774,7 +775,7 @@ do_fork(struct thread *td, struct fork_req *fr, struct proc *p2, struct thread *
|
|||
CTR2(KTR_PTRACE,
|
||||
"do_fork: attaching to new child pid %d: oppid %d",
|
||||
p2->p_pid, p2->p_oppid);
|
||||
proc_reparent(p2, p1->p_pptr);
|
||||
proc_reparent(p2, p1->p_pptr, false);
|
||||
}
|
||||
PROC_UNLOCK(p2);
|
||||
sx_xunlock(&proctree_lock);
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ kproc_exit(int ecode)
|
|||
*/
|
||||
sx_xlock(&proctree_lock);
|
||||
PROC_LOCK(p);
|
||||
proc_reparent(p, initproc);
|
||||
proc_reparent(p, initproc, true);
|
||||
PROC_UNLOCK(p);
|
||||
sx_xunlock(&proctree_lock);
|
||||
|
||||
|
|
|
|||
|
|
@ -894,8 +894,6 @@ fill_kinfo_proc_only(struct proc *p, struct kinfo_proc *kp)
|
|||
struct sigacts *ps;
|
||||
struct timeval boottime;
|
||||
|
||||
/* For proc_realparent. */
|
||||
sx_assert(&proctree_lock, SX_LOCKED);
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
bzero(kp, sizeof(*kp));
|
||||
|
||||
|
|
@ -1029,7 +1027,7 @@ fill_kinfo_proc_only(struct proc *p, struct kinfo_proc *kp)
|
|||
kp->ki_acflag = p->p_acflag;
|
||||
kp->ki_lock = p->p_lock;
|
||||
if (p->p_pptr) {
|
||||
kp->ki_ppid = proc_realparent(p)->p_pid;
|
||||
kp->ki_ppid = p->p_oppid;
|
||||
if (p->p_flag & P_TRACED)
|
||||
kp->ki_tracer = p->p_pptr->p_pid;
|
||||
}
|
||||
|
|
@ -1450,11 +1448,9 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS)
|
|||
error = sysctl_wire_old_buffer(req, 0);
|
||||
if (error)
|
||||
return (error);
|
||||
sx_slock(&proctree_lock);
|
||||
error = pget((pid_t)name[0], PGET_CANSEE, &p);
|
||||
if (error == 0)
|
||||
error = sysctl_out_proc(p, req, flags);
|
||||
sx_sunlock(&proctree_lock);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
@ -1482,12 +1478,6 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS)
|
|||
error = sysctl_wire_old_buffer(req, 0);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
/*
|
||||
* This lock is only needed to safely grab the parent of a
|
||||
* traced process. Only grab it if we are producing any
|
||||
* data to begin with.
|
||||
*/
|
||||
sx_slock(&proctree_lock);
|
||||
}
|
||||
sx_slock(&allproc_lock);
|
||||
for (doingzomb=0 ; doingzomb < 2 ; doingzomb++) {
|
||||
|
|
@ -1595,8 +1585,6 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS)
|
|||
}
|
||||
out:
|
||||
sx_sunlock(&allproc_lock);
|
||||
if (req->oldptr != NULL)
|
||||
sx_sunlock(&proctree_lock);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -124,22 +124,8 @@ int
|
|||
kern_getppid(struct thread *td)
|
||||
{
|
||||
struct proc *p = td->td_proc;
|
||||
struct proc *pp;
|
||||
int ppid;
|
||||
|
||||
PROC_LOCK(p);
|
||||
if (!(p->p_flag & P_TRACED)) {
|
||||
ppid = p->p_pptr->p_pid;
|
||||
PROC_UNLOCK(p);
|
||||
} else {
|
||||
PROC_UNLOCK(p);
|
||||
sx_slock(&proctree_lock);
|
||||
pp = proc_realparent(p);
|
||||
ppid = pp->p_pid;
|
||||
sx_sunlock(&proctree_lock);
|
||||
}
|
||||
|
||||
return (ppid);
|
||||
return (p->p_oppid);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -416,7 +416,7 @@ procdesc_close(struct file *fp, struct thread *td)
|
|||
* terminate with prejudice.
|
||||
*/
|
||||
p->p_sigparent = SIGCHLD;
|
||||
proc_reparent(p, p->p_reaper);
|
||||
proc_reparent(p, p->p_reaper, true);
|
||||
if ((pd->pd_flags & PDF_DAEMON) == 0)
|
||||
kern_psignal(p, SIGKILL);
|
||||
PROC_UNLOCK(p);
|
||||
|
|
|
|||
|
|
@ -695,7 +695,6 @@ proc_set_traced(struct proc *p, bool stop)
|
|||
if (stop)
|
||||
p->p_flag2 |= P2_PTRACE_FSTP;
|
||||
p->p_ptevents = PTRACE_DEFAULT;
|
||||
p->p_oppid = p->p_pptr->p_pid;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -919,7 +918,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
|
|||
*/
|
||||
proc_set_traced(p, true);
|
||||
if (p->p_pptr != td->td_proc) {
|
||||
proc_reparent(p, td->td_proc);
|
||||
proc_reparent(p, td->td_proc, false);
|
||||
}
|
||||
CTR2(KTR_PTRACE, "PT_ATTACH: pid %d, oppid %d", p->p_pid,
|
||||
p->p_oppid);
|
||||
|
|
@ -1113,7 +1112,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
|
|||
PROC_UNLOCK(p->p_pptr);
|
||||
|
||||
pp = proc_realparent(p);
|
||||
proc_reparent(p, pp);
|
||||
proc_reparent(p, pp, false);
|
||||
if (pp == initproc)
|
||||
p->p_sigparent = SIGCHLD;
|
||||
CTR3(KTR_PTRACE,
|
||||
|
|
@ -1122,7 +1121,6 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
|
|||
} else
|
||||
CTR2(KTR_PTRACE, "PT_DETACH: pid %d, sig %d",
|
||||
p->p_pid, data);
|
||||
p->p_oppid = 0;
|
||||
p->p_ptevents = 0;
|
||||
FOREACH_THREAD_IN_PROC(p, td3) {
|
||||
if ((td3->td_dbgflags & TDB_FSTP) != 0) {
|
||||
|
|
|
|||
|
|
@ -594,10 +594,10 @@ struct proc {
|
|||
struct ksiginfo *p_ksi; /* Locked by parent proc lock */
|
||||
sigqueue_t p_sigqueue; /* (c) Sigs not delivered to a td. */
|
||||
#define p_siglist p_sigqueue.sq_signals
|
||||
pid_t p_oppid; /* (c + e) Real parent pid. */
|
||||
|
||||
/* The following fields are all zeroed upon creation in fork. */
|
||||
#define p_startzero p_oppid
|
||||
pid_t p_oppid; /* (c + e) Save ppid in ptrace. XXX */
|
||||
#define p_startzero p_vmspace
|
||||
struct vmspace *p_vmspace; /* (b) Address space. */
|
||||
u_int p_swtick; /* (c) Tick when swapped in or out. */
|
||||
u_int p_cowgen; /* (c) Generation of COW pointers. */
|
||||
|
|
@ -1050,7 +1050,7 @@ void proc_linkup0(struct proc *p, struct thread *td);
|
|||
void proc_linkup(struct proc *p, struct thread *td);
|
||||
struct proc *proc_realparent(struct proc *child);
|
||||
void proc_reap(struct thread *td, struct proc *p, int *status, int options);
|
||||
void proc_reparent(struct proc *child, struct proc *newparent);
|
||||
void proc_reparent(struct proc *child, struct proc *newparent, bool set_oppid);
|
||||
void proc_set_traced(struct proc *p, bool stop);
|
||||
void proc_wkilled(struct proc *p);
|
||||
struct pstats *pstats_alloc(void);
|
||||
|
|
|
|||
Loading…
Reference in a new issue