deduplicate the complex lock reparent dance.

This commit is contained in:
christos 2016-11-04 18:14:04 +00:00
parent e8fde31e58
commit 9b5ab01589
4 changed files with 37 additions and 46 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_exit.c,v 1.262 2016/11/04 18:12:06 christos Exp $ */
/* $NetBSD: kern_exit.c,v 1.263 2016/11/04 18:14:04 christos Exp $ */
/*-
* Copyright (c) 1998, 1999, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.262 2016/11/04 18:12:06 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.263 2016/11/04 18:14:04 christos Exp $");
#include "opt_ktrace.h"
#include "opt_dtrace.h"
@ -1204,6 +1204,33 @@ proc_free(struct proc *p, struct wrusage *wru)
proc_free_mem(p);
}
/*
* Change the parent of a process for tracing purposes.
*/
void
proc_changeparent(struct proc *t, struct proc *p)
{
SET(t->p_slflag, PSL_TRACED);
t->p_opptr = t->p_pptr;
if (t->p_pptr == p)
return;
struct proc *parent = t->p_pptr;
if (parent->p_lock < t->p_lock) {
if (!mutex_tryenter(parent->p_lock)) {
mutex_exit(t->p_lock);
mutex_enter(parent->p_lock);
mutex_enter(t->p_lock);
}
} else if (parent->p_lock > t->p_lock) {
mutex_enter(parent->p_lock);
}
parent->p_slflag |= PSL_CHTRACED;
proc_reparent(t, p);
if (parent->p_lock != t->p_lock)
mutex_exit(parent->p_lock);
}
/*
* make process 'parent' the new parent of process 'child'.
*

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_fork.c,v 1.195 2016/01/09 07:52:38 dholland Exp $ */
/* $NetBSD: kern_fork.c,v 1.196 2016/11/04 18:14:04 christos Exp $ */
/*-
* Copyright (c) 1999, 2001, 2004, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.195 2016/01/09 07:52:38 dholland Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.196 2016/11/04 18:14:04 christos Exp $");
#include "opt_ktrace.h"
#include "opt_dtrace.h"
@ -477,26 +477,7 @@ fork1(struct lwp *l1, int flags, int exitsig, void *stack, size_t stacksize,
tracefork = (p1->p_slflag & (PSL_TRACEFORK|PSL_TRACED)) ==
(PSL_TRACEFORK|PSL_TRACED) && (flags && FORK_PPWAIT) == 0;
if (tracefork) {
p2->p_slflag |= PSL_TRACED;
p2->p_opptr = p2->p_pptr;
if (p2->p_pptr != p1->p_pptr) {
struct proc *parent1 = p2->p_pptr;
if (parent1->p_lock < p2->p_lock) {
if (!mutex_tryenter(parent1->p_lock)) {
mutex_exit(p2->p_lock);
mutex_enter(parent1->p_lock);
mutex_enter(p2->p_lock);
}
} else if (parent1->p_lock > p2->p_lock) {
mutex_enter(parent1->p_lock);
}
parent1->p_slflag |= PSL_CHTRACED;
proc_reparent(p2, p1->p_pptr);
if (parent1->p_lock != p2->p_lock)
mutex_exit(parent1->p_lock);
}
proc_changeparent(p2, p1->p_pptr);
/*
* Set ptrace status.
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: sys_ptrace_common.c,v 1.1 2016/11/02 00:11:59 pgoyette Exp $ */
/* $NetBSD: sys_ptrace_common.c,v 1.2 2016/11/04 18:14:04 christos Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@ -118,7 +118,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.1 2016/11/02 00:11:59 pgoyette Exp $");
__KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.2 2016/11/04 18:14:04 christos Exp $");
#ifdef _KERNEL_OPT
#include "opt_ptrace.h"
@ -813,25 +813,7 @@ do_ptrace(struct ptrace_methods *ptm, struct lwp *l, int req, pid_t pid,
* proc gets to see all the action.
* Stop the target.
*/
t->p_opptr = t->p_pptr;
if (t->p_pptr != p) {
struct proc *parent = t->p_pptr;
if (parent->p_lock < t->p_lock) {
if (!mutex_tryenter(parent->p_lock)) {
mutex_exit(t->p_lock);
mutex_enter(parent->p_lock);
mutex_enter(t->p_lock);
}
} else if (parent->p_lock > t->p_lock) {
mutex_enter(parent->p_lock);
}
parent->p_slflag |= PSL_CHTRACED;
proc_reparent(t, p);
if (parent->p_lock != t->p_lock)
mutex_exit(parent->p_lock);
}
SET(t->p_slflag, PSL_TRACED);
proc_changeparent(t, p);
signo = SIGSTOP;
goto sendsig;

View File

@ -1,4 +1,4 @@
/* $NetBSD: ptrace.h,v 1.48 2016/11/02 00:12:00 pgoyette Exp $ */
/* $NetBSD: ptrace.h,v 1.49 2016/11/04 18:14:04 christos Exp $ */
/*-
* Copyright (c) 1984, 1993
@ -161,6 +161,7 @@ int process_domem(struct lwp *, struct lwp *, struct uio *);
void process_stoptrace(void);
void proc_reparent(struct proc *, struct proc *);
void proc_changeparent(struct proc *, struct proc *);
int do_ptrace(struct ptrace_methods *, struct lwp *, int, pid_t, void *,