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);
 }
 

Reply via email to