Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 16 Nov 2018 17:07:54 +0000 (UTC)
From:      Mateusz Guzik <mjg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r340482 - in head/sys: compat/linux kern sys
Message-ID:  <201811161707.wAGH7sPA013741@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mjg
Date: Fri Nov 16 17:07:54 2018
New Revision: 340482
URL: https://svnweb.freebsd.org/changeset/base/340482

Log:
  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

Modified:
  head/sys/compat/linux/linux_fork.c
  head/sys/kern/kern_exit.c
  head/sys/kern/kern_fork.c
  head/sys/kern/kern_kthread.c
  head/sys/kern/kern_proc.c
  head/sys/kern/kern_prot.c
  head/sys/kern/sys_procdesc.c
  head/sys/kern/sys_process.c
  head/sys/sys/proc.h

Modified: head/sys/compat/linux/linux_fork.c
==============================================================================
--- head/sys/compat/linux/linux_fork.c	Fri Nov 16 16:51:44 2018	(r340481)
+++ head/sys/compat/linux/linux_fork.c	Fri Nov 16 17:07:54 2018	(r340482)
@@ -235,7 +235,7 @@ linux_clone_proc(struct thread *td, struct linux_clone
 	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);
 	}

Modified: head/sys/kern/kern_exit.c
==============================================================================
--- head/sys/kern/kern_exit.c	Fri Nov 16 16:51:44 2018	(r340481)
+++ head/sys/kern/kern_exit.c	Fri Nov 16 17:07:54 2018	(r340482)
@@ -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 *stat
 	 * 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 *stat
 		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 *stat
 		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;
 }

Modified: head/sys/kern/kern_fork.c
==============================================================================
--- head/sys/kern/kern_fork.c	Fri Nov 16 16:51:44 2018	(r340481)
+++ head/sys/kern/kern_fork.c	Fri Nov 16 17:07:54 2018	(r340482)
@@ -643,6 +643,7 @@ do_fork(struct thread *td, struct fork_req *fr, struct
 		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
 			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);

Modified: head/sys/kern/kern_kthread.c
==============================================================================
--- head/sys/kern/kern_kthread.c	Fri Nov 16 16:51:44 2018	(r340481)
+++ head/sys/kern/kern_kthread.c	Fri Nov 16 17:07:54 2018	(r340482)
@@ -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);
 

Modified: head/sys/kern/kern_proc.c
==============================================================================
--- head/sys/kern/kern_proc.c	Fri Nov 16 16:51:44 2018	(r340481)
+++ head/sys/kern/kern_proc.c	Fri Nov 16 17:07:54 2018	(r340482)
@@ -894,8 +894,6 @@ fill_kinfo_proc_only(struct proc *p, struct kinfo_proc
 	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->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);
 }
 

Modified: head/sys/kern/kern_prot.c
==============================================================================
--- head/sys/kern/kern_prot.c	Fri Nov 16 16:51:44 2018	(r340481)
+++ head/sys/kern/kern_prot.c	Fri Nov 16 17:07:54 2018	(r340482)
@@ -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);
 }
 
 /*

Modified: head/sys/kern/sys_procdesc.c
==============================================================================
--- head/sys/kern/sys_procdesc.c	Fri Nov 16 16:51:44 2018	(r340481)
+++ head/sys/kern/sys_procdesc.c	Fri Nov 16 17:07:54 2018	(r340482)
@@ -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);

Modified: head/sys/kern/sys_process.c
==============================================================================
--- head/sys/kern/sys_process.c	Fri Nov 16 16:51:44 2018	(r340481)
+++ head/sys/kern/sys_process.c	Fri Nov 16 17:07:54 2018	(r340482)
@@ -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, voi
 		 */
 		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, voi
 				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, voi
 			} 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) {

Modified: head/sys/sys/proc.h
==============================================================================
--- head/sys/sys/proc.h	Fri Nov 16 16:51:44 2018	(r340481)
+++ head/sys/sys/proc.h	Fri Nov 16 17:07:54 2018	(r340482)
@@ -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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201811161707.wAGH7sPA013741>