Implement an aggressive psref leak detector
It is yet another psref leak detector that enables to tell where a leak occurs while a simpler version that is already committed just tells an occurrence of a leak. Investigating of psref leaks is hard because once a leak occurs a percpu list of psref that tracks references can be corrupted. A reference to a tracking object is memorized in the list via an intermediate object (struct psref) that is normally allocated on a stack of a thread. Thus, the intermediate object can be overwritten on a leak resulting in corruption of the list. The tracker makes a shadow entry to an intermediate object and stores some hints into it (currently it's a caller address of psref_acquire). We can detect a leak by checking the entries on certain points where any references should be released such as the return point of syscalls and the end of each softint handler. The feature is expensive and enabled only if the kernel is built with PSREF_DEBUG. Proposed on tech-kern
This commit is contained in:
parent
01a177fdbf
commit
7fc219a5ee
@ -1,4 +1,4 @@
|
||||
# $NetBSD: files,v 1.1235 2019/04/26 10:11:03 jmcneill Exp $
|
||||
# $NetBSD: files,v 1.1236 2019/05/17 03:34:26 ozaki-r Exp $
|
||||
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
|
||||
|
||||
version 20171118
|
||||
@ -315,6 +315,7 @@ defparam opt_kgdb.h KGDB_DEV KGDB_DEVNAME KGDB_DEVPORT
|
||||
defflag LOCKDEBUG
|
||||
defflag SYSCALL_DEBUG
|
||||
defflag opt_kstack.h KSTACK_CHECK_MAGIC
|
||||
defflag PSREF_DEBUG
|
||||
|
||||
# memory (ram) disk options
|
||||
#
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: init_main.c,v 1.503 2019/02/20 10:07:27 hannken Exp $ */
|
||||
/* $NetBSD: init_main.c,v 1.504 2019/05/17 03:34:26 ozaki-r Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
|
||||
@ -97,7 +97,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.503 2019/02/20 10:07:27 hannken Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.504 2019/05/17 03:34:26 ozaki-r Exp $");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_inet.h"
|
||||
@ -195,6 +195,7 @@ extern void *_binary_splash_image_end;
|
||||
#include <sys/kauth.h>
|
||||
#include <net80211/ieee80211_netbsd.h>
|
||||
#include <sys/cprng.h>
|
||||
#include <sys/psref.h>
|
||||
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/syscallargs.h>
|
||||
@ -393,6 +394,9 @@ main(void)
|
||||
procinit();
|
||||
lwpinit();
|
||||
|
||||
/* Must be called after lwpinit (lwpinit_specificdata) */
|
||||
psref_init();
|
||||
|
||||
/* Initialize signal-related data structures. */
|
||||
signal_init();
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: kern_exit.c,v 1.274 2019/03/01 09:02:03 hannken Exp $ */
|
||||
/* $NetBSD: kern_exit.c,v 1.275 2019/05/17 03:34:26 ozaki-r 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.274 2019/03/01 09:02:03 hannken Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.275 2019/05/17 03:34:26 ozaki-r Exp $");
|
||||
|
||||
#include "opt_ktrace.h"
|
||||
#include "opt_dtrace.h"
|
||||
@ -105,6 +105,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.274 2019/03/01 09:02:03 hannken Exp
|
||||
#include <sys/lwpctl.h>
|
||||
#include <sys/atomic.h>
|
||||
#include <sys/sdt.h>
|
||||
#include <sys/psref.h>
|
||||
|
||||
#include <uvm/uvm_extern.h>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: kern_lwp.c,v 1.200 2019/05/03 22:34:21 kamil Exp $ */
|
||||
/* $NetBSD: kern_lwp.c,v 1.201 2019/05/17 03:34:26 ozaki-r Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001, 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc.
|
||||
@ -211,7 +211,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.200 2019/05/03 22:34:21 kamil Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.201 2019/05/17 03:34:26 ozaki-r Exp $");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_lockdebug.h"
|
||||
@ -242,6 +242,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.200 2019/05/03 22:34:21 kamil Exp $")
|
||||
#include <sys/xcall.h>
|
||||
#include <sys/uidinfo.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/psref.h>
|
||||
|
||||
#include <uvm/uvm_extern.h>
|
||||
#include <uvm/uvm_object.h>
|
||||
@ -878,6 +879,7 @@ lwp_create(lwp_t *l1, proc_t *p2, vaddr_t uaddr, int flags,
|
||||
cv_init(&l2->l_sigcv, "sigwait");
|
||||
cv_init(&l2->l_waitcv, "vfork");
|
||||
l2->l_syncobj = &sched_syncobj;
|
||||
PSREF_DEBUG_INIT_LWP(l2);
|
||||
|
||||
if (rnewlwpp != NULL)
|
||||
*rnewlwpp = l2;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: kern_softint.c,v 1.46 2019/04/19 01:52:55 ozaki-r Exp $ */
|
||||
/* $NetBSD: kern_softint.c,v 1.47 2019/05/17 03:34:26 ozaki-r Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
|
||||
@ -170,7 +170,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_softint.c,v 1.46 2019/04/19 01:52:55 ozaki-r Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_softint.c,v 1.47 2019/05/17 03:34:26 ozaki-r Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/proc.h>
|
||||
@ -604,6 +604,8 @@ softint_execute(softint_t *si, lwp_t *l, int s)
|
||||
sh->sh_flags ^= SOFTINT_ACTIVE;
|
||||
}
|
||||
|
||||
PSREF_DEBUG_BARRIER();
|
||||
|
||||
if (havelock) {
|
||||
KERNEL_UNLOCK_ONE(l);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: subr_lwp_specificdata.c,v 1.3 2013/10/25 16:17:35 martin Exp $ */
|
||||
/* $NetBSD: subr_lwp_specificdata.c,v 1.4 2019/05/17 03:34:26 ozaki-r Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||
@ -29,7 +29,7 @@
|
||||
#define _LWP_API_PRIVATE
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_lwp_specificdata.c,v 1.3 2013/10/25 16:17:35 martin Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_lwp_specificdata.c,v 1.4 2019/05/17 03:34:26 ozaki-r Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/lwp.h>
|
||||
@ -129,3 +129,11 @@ lwp_setspecific(specificdata_key_t key, void *data)
|
||||
specificdata_setspecific(lwp_specificdata_domain,
|
||||
&curlwp->l_specdataref, key, data);
|
||||
}
|
||||
|
||||
void
|
||||
lwp_setspecific_by_lwp(struct lwp *l, specificdata_key_t key, void *data)
|
||||
{
|
||||
|
||||
specificdata_setspecific(lwp_specificdata_domain,
|
||||
&l->l_specdataref, key, data);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: subr_psref.c,v 1.12 2019/04/19 01:52:55 ozaki-r Exp $ */
|
||||
/* $NetBSD: subr_psref.c,v 1.13 2019/05/17 03:34:26 ozaki-r Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2016 The NetBSD Foundation, Inc.
|
||||
@ -64,7 +64,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_psref.c,v 1.12 2019/04/19 01:52:55 ozaki-r Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_psref.c,v 1.13 2019/05/17 03:34:26 ozaki-r Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/condvar.h>
|
||||
@ -77,6 +77,7 @@ __KERNEL_RCSID(0, "$NetBSD: subr_psref.c,v 1.12 2019/04/19 01:52:55 ozaki-r Exp
|
||||
#include <sys/psref.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/xcall.h>
|
||||
#include <sys/lwp.h>
|
||||
|
||||
SLIST_HEAD(psref_head, psref);
|
||||
|
||||
@ -107,6 +108,44 @@ struct psref_cpu {
|
||||
struct psref_head pcpu_head;
|
||||
};
|
||||
|
||||
/*
|
||||
* Data structures and functions for debugging.
|
||||
*/
|
||||
#ifndef PSREF_DEBUG_NITEMS
|
||||
#define PSREF_DEBUG_NITEMS 16
|
||||
#endif
|
||||
|
||||
struct psref_debug_item {
|
||||
void *prdi_caller;
|
||||
struct psref *prdi_psref;
|
||||
};
|
||||
|
||||
struct psref_debug {
|
||||
int prd_refs_peek;
|
||||
struct psref_debug_item prd_items[PSREF_DEBUG_NITEMS];
|
||||
};
|
||||
|
||||
#ifdef PSREF_DEBUG
|
||||
static void psref_debug_acquire(struct psref *);
|
||||
static void psref_debug_release(struct psref *);
|
||||
|
||||
static void psref_debug_lwp_free(void *);
|
||||
|
||||
static specificdata_key_t psref_debug_lwp_key;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* psref_init()
|
||||
*/
|
||||
void
|
||||
psref_init(void)
|
||||
{
|
||||
|
||||
#ifdef PSREF_DEBUG
|
||||
lwp_specific_key_create(&psref_debug_lwp_key, psref_debug_lwp_free);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* psref_class_create(name, ipl)
|
||||
*
|
||||
@ -279,9 +318,12 @@ psref_acquire(struct psref *psref, const struct psref_target *target,
|
||||
percpu_putref(class->prc_percpu);
|
||||
splx(s);
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
#if defined(DIAGNOSTIC) || defined(PSREF_DEBUG)
|
||||
curlwp->l_psrefs++;
|
||||
#endif
|
||||
#ifdef PSREF_DEBUG
|
||||
psref_debug_acquire(psref);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -336,10 +378,13 @@ psref_release(struct psref *psref, const struct psref_target *target,
|
||||
percpu_putref(class->prc_percpu);
|
||||
splx(s);
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
#if defined(DIAGNOSTIC) || defined(PSREF_DEBUG)
|
||||
KASSERT(curlwp->l_psrefs > 0);
|
||||
curlwp->l_psrefs--;
|
||||
#endif
|
||||
#ifdef PSREF_DEBUG
|
||||
psref_debug_release(psref);
|
||||
#endif
|
||||
|
||||
/* If someone is waiting for users to drain, notify 'em. */
|
||||
if (__predict_false(target->prt_draining))
|
||||
@ -398,7 +443,7 @@ psref_copy(struct psref *pto, const struct psref *pfrom,
|
||||
percpu_putref(class->prc_percpu);
|
||||
splx(s);
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
#if defined(DIAGNOSTIC) || defined(PSREF_DEBUG)
|
||||
curlwp->l_psrefs++;
|
||||
#endif
|
||||
}
|
||||
@ -565,3 +610,90 @@ psref_held(const struct psref_target *target, struct psref_class *class)
|
||||
|
||||
return _psref_held(target, class, false);
|
||||
}
|
||||
|
||||
#ifdef PSREF_DEBUG
|
||||
void
|
||||
psref_debug_init_lwp(struct lwp *l)
|
||||
{
|
||||
struct psref_debug *prd;
|
||||
|
||||
prd = kmem_zalloc(sizeof(*prd), KM_SLEEP);
|
||||
lwp_setspecific_by_lwp(l, psref_debug_lwp_key, prd);
|
||||
}
|
||||
|
||||
static void
|
||||
psref_debug_lwp_free(void *arg)
|
||||
{
|
||||
struct psref_debug *prd = arg;
|
||||
|
||||
kmem_free(prd, sizeof(*prd));
|
||||
}
|
||||
|
||||
static void
|
||||
psref_debug_acquire(struct psref *psref)
|
||||
{
|
||||
struct psref_debug *prd;
|
||||
struct lwp *l = curlwp;
|
||||
int s, i;
|
||||
|
||||
prd = lwp_getspecific(psref_debug_lwp_key);
|
||||
if (__predict_false(prd == NULL)) {
|
||||
psref->psref_debug = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
s = splserial();
|
||||
if (l->l_psrefs > prd->prd_refs_peek) {
|
||||
prd->prd_refs_peek = l->l_psrefs;
|
||||
if (__predict_false(prd->prd_refs_peek > PSREF_DEBUG_NITEMS))
|
||||
panic("exceeded PSREF_DEBUG_NITEMS");
|
||||
}
|
||||
for (i = 0; i < prd->prd_refs_peek; i++) {
|
||||
struct psref_debug_item *prdi = &prd->prd_items[i];
|
||||
if (prdi->prdi_psref != NULL)
|
||||
continue;
|
||||
prdi->prdi_caller = psref->psref_debug;
|
||||
prdi->prdi_psref = psref;
|
||||
psref->psref_debug = prdi;
|
||||
break;
|
||||
}
|
||||
if (__predict_false(i == prd->prd_refs_peek))
|
||||
panic("out of range: %d", i);
|
||||
splx(s);
|
||||
}
|
||||
|
||||
static void
|
||||
psref_debug_release(struct psref *psref)
|
||||
{
|
||||
int s;
|
||||
|
||||
s = splserial();
|
||||
if (__predict_true(psref->psref_debug != NULL)) {
|
||||
struct psref_debug_item *prdi = psref->psref_debug;
|
||||
prdi->prdi_psref = NULL;
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
|
||||
void
|
||||
psref_debug_barrier(void)
|
||||
{
|
||||
struct psref_debug *prd;
|
||||
struct lwp *l = curlwp;
|
||||
int s, i;
|
||||
|
||||
prd = lwp_getspecific(psref_debug_lwp_key);
|
||||
if (__predict_false(prd == NULL))
|
||||
return;
|
||||
|
||||
s = splserial();
|
||||
for (i = 0; i < prd->prd_refs_peek; i++) {
|
||||
struct psref_debug_item *prdi = &prd->prd_items[i];
|
||||
if (__predict_true(prdi->prdi_psref == NULL))
|
||||
continue;
|
||||
panic("psref leaked: lwp(%p) acquired at %p", l, prdi->prdi_caller);
|
||||
}
|
||||
prd->prd_refs_peek = 0; /* Reset the counter */
|
||||
splx(s);
|
||||
}
|
||||
#endif /* PSREF_DEBUG */
|
||||
|
10
sys/net/if.c
10
sys/net/if.c
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: if.c,v 1.452 2019/05/15 02:56:48 ozaki-r Exp $ */
|
||||
/* $NetBSD: if.c,v 1.453 2019/05/17 03:34:26 ozaki-r Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
|
||||
@ -90,7 +90,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.452 2019/05/15 02:56:48 ozaki-r Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.453 2019/05/17 03:34:26 ozaki-r Exp $");
|
||||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "opt_inet.h"
|
||||
@ -1863,6 +1863,7 @@ void
|
||||
ifa_acquire(struct ifaddr *ifa, struct psref *psref)
|
||||
{
|
||||
|
||||
PSREF_DEBUG_FILL_RETURN_ADDRESS(psref);
|
||||
psref_acquire(psref, &ifa->ifa_psref, ifa_psref_class);
|
||||
}
|
||||
|
||||
@ -2739,6 +2740,7 @@ if_get(const char *name, struct psref *psref)
|
||||
if (if_is_deactivated(ifp))
|
||||
continue;
|
||||
if (strcmp(ifp->if_xname, name) == 0) {
|
||||
PSREF_DEBUG_FILL_RETURN_ADDRESS(psref);
|
||||
psref_acquire(psref, &ifp->if_psref,
|
||||
ifnet_psref_class);
|
||||
goto out;
|
||||
@ -2802,8 +2804,10 @@ if_get_byindex(u_int idx, struct psref *psref)
|
||||
|
||||
s = pserialize_read_enter();
|
||||
ifp = if_byindex(idx);
|
||||
if (__predict_true(ifp != NULL))
|
||||
if (__predict_true(ifp != NULL)) {
|
||||
PSREF_DEBUG_FILL_RETURN_ADDRESS(psref);
|
||||
psref_acquire(psref, &ifp->if_psref, ifnet_psref_class);
|
||||
}
|
||||
pserialize_read_exit(s);
|
||||
|
||||
return ifp;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: route.c,v 1.218 2019/04/29 11:57:22 roy Exp $ */
|
||||
/* $NetBSD: route.c,v 1.219 2019/05/17 03:34:26 ozaki-r Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
|
||||
@ -97,7 +97,7 @@
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: route.c,v 1.218 2019/04/29 11:57:22 roy Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: route.c,v 1.219 2019/05/17 03:34:26 ozaki-r Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#ifdef RTFLUSH_DEBUG
|
||||
@ -2077,6 +2077,8 @@ rtcache_ref(struct rtentry *rt, struct route *ro)
|
||||
#ifdef NET_MPSAFE
|
||||
RTCACHE_PSREF_TRACE(rt, ro);
|
||||
ro->ro_bound = curlwp_bind();
|
||||
/* XXX Use a real caller's address */
|
||||
PSREF_DEBUG_FILL_RETURN_ADDRESS(&ro->ro_psref);
|
||||
psref_acquire(&ro->ro_psref, &rt->rt_psref, rt_psref_class);
|
||||
#endif
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sysproxy.c,v 1.6 2019/04/19 01:52:55 ozaki-r Exp $ */
|
||||
/* $NetBSD: sysproxy.c,v 1.7 2019/05/17 03:34:26 ozaki-r Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010, 2011 Antti Kantee. All Rights Reserved.
|
||||
@ -26,7 +26,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: sysproxy.c,v 1.6 2019/04/19 01:52:55 ozaki-r Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: sysproxy.c,v 1.7 2019/05/17 03:34:26 ozaki-r Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/filedesc.h>
|
||||
@ -36,6 +36,7 @@ __KERNEL_RCSID(0, "$NetBSD: sysproxy.c,v 1.6 2019/04/19 01:52:55 ozaki-r Exp $")
|
||||
#include <sys/systm.h>
|
||||
#include <sys/xcall.h>
|
||||
#include <sys/lockdebug.h>
|
||||
#include <sys/psref.h>
|
||||
|
||||
#define _RUMP_SYSPROXY
|
||||
#include <rump/rumpuser.h>
|
||||
@ -77,6 +78,7 @@ hyp_syscall(int num, void *arg, long *retval)
|
||||
/* Sanity checks (from mi_userret) */
|
||||
LOCKDEBUG_BARRIER(NULL, 0);
|
||||
KASSERT(l->l_nopreempt == 0);
|
||||
PSREF_DEBUG_BARRIER();
|
||||
KASSERT(l->l_psrefs == 0);
|
||||
|
||||
return rv;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lwproc.c,v 1.41 2019/03/09 09:02:38 hannken Exp $ */
|
||||
/* $NetBSD: lwproc.c,v 1.42 2019/05/17 03:34:26 ozaki-r Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010, 2011 Antti Kantee. All Rights Reserved.
|
||||
@ -28,7 +28,7 @@
|
||||
#define RUMP__CURLWP_PRIVATE
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: lwproc.c,v 1.41 2019/03/09 09:02:38 hannken Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: lwproc.c,v 1.42 2019/05/17 03:34:26 ozaki-r Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/atomic.h>
|
||||
@ -43,6 +43,7 @@ __KERNEL_RCSID(0, "$NetBSD: lwproc.c,v 1.41 2019/03/09 09:02:38 hannken Exp $");
|
||||
#include <sys/queue.h>
|
||||
#include <sys/resourcevar.h>
|
||||
#include <sys/uidinfo.h>
|
||||
#include <sys/psref.h>
|
||||
|
||||
#include <rump-sys/kern.h>
|
||||
|
||||
@ -372,6 +373,7 @@ lwproc_makelwp(struct proc *p, struct lwp *l, bool doswitch, bool procmake)
|
||||
|
||||
lwp_update_creds(l);
|
||||
lwp_initspecific(l);
|
||||
PSREF_DEBUG_INIT_LWP(l);
|
||||
|
||||
membar_enter();
|
||||
lwproc_curlwpop(RUMPUSER_LWP_CREATE, l);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rump.c,v 1.333 2019/03/29 02:09:14 christos Exp $ */
|
||||
/* $NetBSD: rump.c,v 1.334 2019/05/17 03:34:26 ozaki-r Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007-2011 Antti Kantee. All Rights Reserved.
|
||||
@ -26,7 +26,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.333 2019/03/29 02:09:14 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.334 2019/05/17 03:34:26 ozaki-r Exp $");
|
||||
|
||||
#include <sys/systm.h>
|
||||
#define ELFSIZE ARCH_ELFSIZE
|
||||
@ -74,6 +74,7 @@ __KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.333 2019/03/29 02:09:14 christos Exp $");
|
||||
#include <sys/cprng.h>
|
||||
#include <sys/rnd.h>
|
||||
#include <sys/ktrace.h>
|
||||
#include <sys/psref.h>
|
||||
|
||||
#include <rump-sys/kern.h>
|
||||
#include <rump-sys/dev.h>
|
||||
@ -344,6 +345,9 @@ rump_init(void)
|
||||
lwpinit_specificdata();
|
||||
lwp_initspecific(&lwp0);
|
||||
|
||||
/* Must be called after lwpinit_specificdata */
|
||||
psref_init();
|
||||
|
||||
threadpools_init();
|
||||
|
||||
loginit();
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lwp.h,v 1.182 2019/04/19 01:52:55 ozaki-r Exp $ */
|
||||
/* $NetBSD: lwp.h,v 1.183 2019/05/17 03:34:26 ozaki-r Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001, 2006, 2007, 2008, 2009, 2010
|
||||
@ -357,6 +357,7 @@ void *lwp_getspecific(specificdata_key_t);
|
||||
void *_lwp_getspecific_by_lwp(lwp_t *, specificdata_key_t);
|
||||
#endif
|
||||
void lwp_setspecific(specificdata_key_t, void *);
|
||||
void lwp_setspecific_by_lwp(lwp_t *, specificdata_key_t, void *);
|
||||
|
||||
/* Syscalls. */
|
||||
int lwp_park(clockid_t, int, struct timespec *, const void *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: psref.h,v 1.3 2017/12/11 02:33:17 knakahara Exp $ */
|
||||
/* $NetBSD: psref.h,v 1.4 2019/05/17 03:34:27 ozaki-r Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2016 The NetBSD Foundation, Inc.
|
||||
@ -32,6 +32,10 @@
|
||||
#ifndef _SYS_PSREF_H
|
||||
#define _SYS_PSREF_H
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "opt_psref_debug.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
@ -70,14 +74,15 @@ struct psref_target {
|
||||
*/
|
||||
struct psref {
|
||||
SLIST_ENTRY(psref) psref_entry;
|
||||
/* To keep ABI with LIST_ENTRY(psref) version. */
|
||||
void *psref_unused0;
|
||||
void *psref_debug; /* For debugging */
|
||||
const struct psref_target *psref_target;
|
||||
struct lwp *psref_lwp;
|
||||
struct cpu_info *psref_cpu;
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
void psref_init(void);
|
||||
|
||||
struct psref_class *
|
||||
psref_class_create(const char *, int);
|
||||
void psref_class_destroy(struct psref_class *);
|
||||
@ -94,6 +99,30 @@ void psref_copy(struct psref *, const struct psref *,
|
||||
|
||||
/* For use only in assertions. */
|
||||
bool psref_held(const struct psref_target *, struct psref_class *);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef PSREF_DEBUG
|
||||
void psref_debug_barrier(void);
|
||||
void psref_debug_init_lwp(struct lwp *);
|
||||
|
||||
#define PSREF_DEBUG_BARRIER() psref_debug_barrier()
|
||||
#define PSREF_DEBUG_INIT_LWP(l) psref_debug_init_lwp((l))
|
||||
#define PSREF_DEBUG_FILL_RETURN_ADDRESS0(psref, addr) do { \
|
||||
(psref)->psref_debug = (addr); \
|
||||
} while (0)
|
||||
#define PSREF_DEBUG_FILL_RETURN_ADDRESS(psref) do { \
|
||||
PSREF_DEBUG_FILL_RETURN_ADDRESS0(psref, __builtin_return_address(0));\
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define PSREF_DEBUG_BARRIER() __nothing
|
||||
#define PSREF_DEBUG_INIT_LWP(l) __nothing
|
||||
#define PSREF_DEBUG_FILL_RETURN_ADDRESS0(psref, addr) __nothing
|
||||
#define PSREF_DEBUG_FILL_RETURN_ADDRESS(psref) __nothing
|
||||
|
||||
#endif /* PSREF_DEBUG */
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* _SYS_PSREF_H */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: userret.h,v 1.27 2019/04/19 01:52:55 ozaki-r Exp $ */
|
||||
/* $NetBSD: userret.h,v 1.28 2019/05/17 03:34:27 ozaki-r Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 2000, 2003, 2006, 2008 The NetBSD Foundation, Inc.
|
||||
@ -67,6 +67,7 @@
|
||||
|
||||
#include <sys/lockdebug.h>
|
||||
#include <sys/intr.h>
|
||||
#include <sys/psref.h>
|
||||
|
||||
/*
|
||||
* Define the MI code needed before returning to user mode, for
|
||||
@ -114,6 +115,7 @@ mi_userret(struct lwp *l)
|
||||
|
||||
LOCKDEBUG_BARRIER(NULL, 0);
|
||||
KASSERT(l->l_nopreempt == 0);
|
||||
PSREF_DEBUG_BARRIER();
|
||||
KASSERT(l->l_psrefs == 0);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user