Module Name: src Committed By: ozaki-r Date: Fri May 17 03:34:27 UTC 2019
Modified Files: src/sys/conf: files src/sys/kern: init_main.c kern_exit.c kern_lwp.c kern_softint.c subr_lwp_specificdata.c subr_psref.c src/sys/net: if.c route.c src/sys/rump/kern/lib/libsysproxy: sysproxy.c src/sys/rump/librump/rumpkern: lwproc.c rump.c src/sys/sys: lwp.h psref.h userret.h Log Message: 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 To generate a diff of this commit: cvs rdiff -u -r1.1235 -r1.1236 src/sys/conf/files cvs rdiff -u -r1.503 -r1.504 src/sys/kern/init_main.c cvs rdiff -u -r1.274 -r1.275 src/sys/kern/kern_exit.c cvs rdiff -u -r1.200 -r1.201 src/sys/kern/kern_lwp.c cvs rdiff -u -r1.46 -r1.47 src/sys/kern/kern_softint.c cvs rdiff -u -r1.3 -r1.4 src/sys/kern/subr_lwp_specificdata.c cvs rdiff -u -r1.12 -r1.13 src/sys/kern/subr_psref.c cvs rdiff -u -r1.452 -r1.453 src/sys/net/if.c cvs rdiff -u -r1.218 -r1.219 src/sys/net/route.c cvs rdiff -u -r1.6 -r1.7 src/sys/rump/kern/lib/libsysproxy/sysproxy.c cvs rdiff -u -r1.41 -r1.42 src/sys/rump/librump/rumpkern/lwproc.c cvs rdiff -u -r1.333 -r1.334 src/sys/rump/librump/rumpkern/rump.c cvs rdiff -u -r1.182 -r1.183 src/sys/sys/lwp.h cvs rdiff -u -r1.3 -r1.4 src/sys/sys/psref.h cvs rdiff -u -r1.27 -r1.28 src/sys/sys/userret.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/conf/files diff -u src/sys/conf/files:1.1235 src/sys/conf/files:1.1236 --- src/sys/conf/files:1.1235 Fri Apr 26 10:11:03 2019 +++ src/sys/conf/files Fri May 17 03:34:26 2019 @@ -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_DEVNA defflag LOCKDEBUG defflag SYSCALL_DEBUG defflag opt_kstack.h KSTACK_CHECK_MAGIC +defflag PSREF_DEBUG # memory (ram) disk options # Index: src/sys/kern/init_main.c diff -u src/sys/kern/init_main.c:1.503 src/sys/kern/init_main.c:1.504 --- src/sys/kern/init_main.c:1.503 Wed Feb 20 10:07:27 2019 +++ src/sys/kern/init_main.c Fri May 17 03:34:26 2019 @@ -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(); Index: src/sys/kern/kern_exit.c diff -u src/sys/kern/kern_exit.c:1.274 src/sys/kern/kern_exit.c:1.275 --- src/sys/kern/kern_exit.c:1.274 Fri Mar 1 09:02:03 2019 +++ src/sys/kern/kern_exit.c Fri May 17 03:34:26 2019 @@ -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, #include <sys/lwpctl.h> #include <sys/atomic.h> #include <sys/sdt.h> +#include <sys/psref.h> #include <uvm/uvm_extern.h> Index: src/sys/kern/kern_lwp.c diff -u src/sys/kern/kern_lwp.c:1.200 src/sys/kern/kern_lwp.c:1.201 --- src/sys/kern/kern_lwp.c:1.200 Fri May 3 22:34:21 2019 +++ src/sys/kern/kern_lwp.c Fri May 17 03:34:26 2019 @@ -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 #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_ 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; Index: src/sys/kern/kern_softint.c diff -u src/sys/kern/kern_softint.c:1.46 src/sys/kern/kern_softint.c:1.47 --- src/sys/kern/kern_softint.c:1.46 Fri Apr 19 01:52:55 2019 +++ src/sys/kern/kern_softint.c Fri May 17 03:34:26 2019 @@ -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, sh->sh_flags ^= SOFTINT_ACTIVE; } + PSREF_DEBUG_BARRIER(); + if (havelock) { KERNEL_UNLOCK_ONE(l); } Index: src/sys/kern/subr_lwp_specificdata.c diff -u src/sys/kern/subr_lwp_specificdata.c:1.3 src/sys/kern/subr_lwp_specificdata.c:1.4 --- src/sys/kern/subr_lwp_specificdata.c:1.3 Fri Oct 25 16:17:35 2013 +++ src/sys/kern/subr_lwp_specificdata.c Fri May 17 03:34:26 2019 @@ -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, 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); +} Index: src/sys/kern/subr_psref.c diff -u src/sys/kern/subr_psref.c:1.12 src/sys/kern/subr_psref.c:1.13 --- src/sys/kern/subr_psref.c:1.12 Fri Apr 19 01:52:55 2019 +++ src/sys/kern/subr_psref.c Fri May 17 03:34:26 2019 @@ -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 #include <sys/psref.h> #include <sys/queue.h> #include <sys/xcall.h> +#include <sys/lwp.h> SLIST_HEAD(psref_head, psref); @@ -108,6 +109,44 @@ struct psref_cpu { }; /* + * 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) * * Create a new passive reference class, with the given wchan name @@ -279,9 +318,12 @@ psref_acquire(struct psref *psref, const 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 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 stru 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 *ta 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 */ Index: src/sys/net/if.c diff -u src/sys/net/if.c:1.452 src/sys/net/if.c:1.453 --- src/sys/net/if.c:1.452 Wed May 15 02:56:48 2019 +++ src/sys/net/if.c Fri May 17 03:34:26 2019 @@ -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 *p 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 * 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; Index: src/sys/net/route.c diff -u src/sys/net/route.c:1.218 src/sys/net/route.c:1.219 --- src/sys/net/route.c:1.218 Mon Apr 29 11:57:22 2019 +++ src/sys/net/route.c Fri May 17 03:34:26 2019 @@ -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 r #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 } Index: src/sys/rump/kern/lib/libsysproxy/sysproxy.c diff -u src/sys/rump/kern/lib/libsysproxy/sysproxy.c:1.6 src/sys/rump/kern/lib/libsysproxy/sysproxy.c:1.7 --- src/sys/rump/kern/lib/libsysproxy/sysproxy.c:1.6 Fri Apr 19 01:52:55 2019 +++ src/sys/rump/kern/lib/libsysproxy/sysproxy.c Fri May 17 03:34:26 2019 @@ -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 #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 *re /* Sanity checks (from mi_userret) */ LOCKDEBUG_BARRIER(NULL, 0); KASSERT(l->l_nopreempt == 0); + PSREF_DEBUG_BARRIER(); KASSERT(l->l_psrefs == 0); return rv; Index: src/sys/rump/librump/rumpkern/lwproc.c diff -u src/sys/rump/librump/rumpkern/lwproc.c:1.41 src/sys/rump/librump/rumpkern/lwproc.c:1.42 --- src/sys/rump/librump/rumpkern/lwproc.c:1.41 Sat Mar 9 09:02:38 2019 +++ src/sys/rump/librump/rumpkern/lwproc.c Fri May 17 03:34:26 2019 @@ -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 #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 lw lwp_update_creds(l); lwp_initspecific(l); + PSREF_DEBUG_INIT_LWP(l); membar_enter(); lwproc_curlwpop(RUMPUSER_LWP_CREATE, l); Index: src/sys/rump/librump/rumpkern/rump.c diff -u src/sys/rump/librump/rumpkern/rump.c:1.333 src/sys/rump/librump/rumpkern/rump.c:1.334 --- src/sys/rump/librump/rumpkern/rump.c:1.333 Fri Mar 29 02:09:14 2019 +++ src/sys/rump/librump/rumpkern/rump.c Fri May 17 03:34:26 2019 @@ -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.3 #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(); Index: src/sys/sys/lwp.h diff -u src/sys/sys/lwp.h:1.182 src/sys/sys/lwp.h:1.183 --- src/sys/sys/lwp.h:1.182 Fri Apr 19 01:52:55 2019 +++ src/sys/sys/lwp.h Fri May 17 03:34:26 2019 @@ -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 *); Index: src/sys/sys/psref.h diff -u src/sys/sys/psref.h:1.3 src/sys/sys/psref.h:1.4 --- src/sys/sys/psref.h:1.3 Mon Dec 11 02:33:17 2017 +++ src/sys/sys/psref.h Fri May 17 03:34:27 2019 @@ -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 st /* 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 */ Index: src/sys/sys/userret.h diff -u src/sys/sys/userret.h:1.27 src/sys/sys/userret.h:1.28 --- src/sys/sys/userret.h:1.27 Fri Apr 19 01:52:55 2019 +++ src/sys/sys/userret.h Fri May 17 03:34:27 2019 @@ -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); }