Module Name: src Committed By: ozaki-r Date: Fri Apr 19 01:52:56 UTC 2019
Modified Files: src/sys/kern: kern_lwp.c kern_softint.c subr_psref.c src/sys/rump/kern/lib/libsysproxy: sysproxy.c src/sys/sys: lwp.h userret.h Log Message: Implement a simple psref leak detector It detects leaks by counting up the number of held psref by an LWP and checking its zeroness at the end of syscalls and softint handlers. For the counter, a unused field of struct lwp is reused. The detector runs only if DIAGNOSTIC is turned on. To generate a diff of this commit: cvs rdiff -u -r1.196 -r1.197 src/sys/kern/kern_lwp.c cvs rdiff -u -r1.45 -r1.46 src/sys/kern/kern_softint.c cvs rdiff -u -r1.11 -r1.12 src/sys/kern/subr_psref.c cvs rdiff -u -r1.5 -r1.6 src/sys/rump/kern/lib/libsysproxy/sysproxy.c cvs rdiff -u -r1.181 -r1.182 src/sys/sys/lwp.h cvs rdiff -u -r1.26 -r1.27 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/kern/kern_lwp.c diff -u src/sys/kern/kern_lwp.c:1.196 src/sys/kern/kern_lwp.c:1.197 --- src/sys/kern/kern_lwp.c:1.196 Fri Mar 1 09:02:03 2019 +++ src/sys/kern/kern_lwp.c Fri Apr 19 01:52:55 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_lwp.c,v 1.196 2019/03/01 09:02:03 hannken Exp $ */ +/* $NetBSD: kern_lwp.c,v 1.197 2019/04/19 01:52:55 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.196 2019/03/01 09:02:03 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.197 2019/04/19 01:52:55 ozaki-r Exp $"); #include "opt_ddb.h" #include "opt_lockdebug.h" @@ -836,6 +836,7 @@ lwp_create(lwp_t *l1, proc_t *p2, vaddr_ l2->l_flag = 0; l2->l_pflag = LP_MPSAFE; TAILQ_INIT(&l2->l_ld_locks); + l2->l_psrefs = 0; /* * For vfork, borrow parent's lwpctl context if it exists. Index: src/sys/kern/kern_softint.c diff -u src/sys/kern/kern_softint.c:1.45 src/sys/kern/kern_softint.c:1.46 --- src/sys/kern/kern_softint.c:1.45 Thu Dec 28 03:39:48 2017 +++ src/sys/kern/kern_softint.c Fri Apr 19 01:52:55 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_softint.c,v 1.45 2017/12/28 03:39:48 msaitoh Exp $ */ +/* $NetBSD: kern_softint.c,v 1.46 2019/04/19 01:52:55 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.45 2017/12/28 03:39:48 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_softint.c,v 1.46 2019/04/19 01:52:55 ozaki-r Exp $"); #include <sys/param.h> #include <sys/proc.h> @@ -595,6 +595,9 @@ softint_execute(softint_t *si, lwp_t *l, KASSERTMSG(curcpu()->ci_mtx_count == 0, "%s: ci_mtx_count (%d) != 0, sh_func %p\n", __func__, curcpu()->ci_mtx_count, sh->sh_func); + /* Diagnostic: check that psrefs have not leaked. */ + KASSERTMSG(l->l_psrefs == 0, "%s: l_psrefs=%d, sh_func=%p\n", + __func__, l->l_psrefs, sh->sh_func); (void)splhigh(); KASSERT((sh->sh_flags & SOFTINT_ACTIVE) != 0); Index: src/sys/kern/subr_psref.c diff -u src/sys/kern/subr_psref.c:1.11 src/sys/kern/subr_psref.c:1.12 --- src/sys/kern/subr_psref.c:1.11 Thu Feb 1 03:17:00 2018 +++ src/sys/kern/subr_psref.c Fri Apr 19 01:52:55 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_psref.c,v 1.11 2018/02/01 03:17:00 ozaki-r Exp $ */ +/* $NetBSD: subr_psref.c,v 1.12 2019/04/19 01:52:55 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.11 2018/02/01 03:17:00 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_psref.c,v 1.12 2019/04/19 01:52:55 ozaki-r Exp $"); #include <sys/types.h> #include <sys/condvar.h> @@ -278,6 +278,10 @@ psref_acquire(struct psref *psref, const /* Release the CPU list and restore interrupts. */ percpu_putref(class->prc_percpu); splx(s); + +#ifdef DIAGNOSTIC + curlwp->l_psrefs++; +#endif } /* @@ -332,6 +336,11 @@ psref_release(struct psref *psref, const percpu_putref(class->prc_percpu); splx(s); +#ifdef DIAGNOSTIC + KASSERT(curlwp->l_psrefs > 0); + curlwp->l_psrefs--; +#endif + /* If someone is waiting for users to drain, notify 'em. */ if (__predict_false(target->prt_draining)) cv_broadcast(&class->prc_cv); @@ -388,6 +397,10 @@ psref_copy(struct psref *pto, const stru /* Release the CPU list and restore interrupts. */ percpu_putref(class->prc_percpu); splx(s); + +#ifdef DIAGNOSTIC + curlwp->l_psrefs++; +#endif } /* Index: src/sys/rump/kern/lib/libsysproxy/sysproxy.c diff -u src/sys/rump/kern/lib/libsysproxy/sysproxy.c:1.5 src/sys/rump/kern/lib/libsysproxy/sysproxy.c:1.6 --- src/sys/rump/kern/lib/libsysproxy/sysproxy.c:1.5 Thu Apr 18 08:31:44 2019 +++ src/sys/rump/kern/lib/libsysproxy/sysproxy.c Fri Apr 19 01:52:55 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: sysproxy.c,v 1.5 2019/04/18 08:31:44 ozaki-r Exp $ */ +/* $NetBSD: sysproxy.c,v 1.6 2019/04/19 01:52:55 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.5 2019/04/18 08:31:44 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sysproxy.c,v 1.6 2019/04/19 01:52:55 ozaki-r Exp $"); #include <sys/param.h> #include <sys/filedesc.h> @@ -77,6 +77,7 @@ hyp_syscall(int num, void *arg, long *re /* Sanity checks (from mi_userret) */ LOCKDEBUG_BARRIER(NULL, 0); KASSERT(l->l_nopreempt == 0); + KASSERT(l->l_psrefs == 0); return rv; } Index: src/sys/sys/lwp.h diff -u src/sys/sys/lwp.h:1.181 src/sys/sys/lwp.h:1.182 --- src/sys/sys/lwp.h:1.181 Fri Mar 1 09:02:03 2019 +++ src/sys/sys/lwp.h Fri Apr 19 01:52:55 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: lwp.h,v 1.181 2019/03/01 09:02:03 hannken Exp $ */ +/* $NetBSD: lwp.h,v 1.182 2019/04/19 01:52:55 ozaki-r Exp $ */ /* * Copyright (c) 2001, 2006, 2007, 2008, 2009, 2010 @@ -184,7 +184,7 @@ struct lwp { u_int l_cv_signalled; /* c: restarted by cv_signal() */ u_short l_shlocks; /* !: lockdebug: shared locks held */ u_short l_exlocks; /* !: lockdebug: excl. locks held */ - u_short l_unused; /* !: unused */ + u_short l_psrefs; /* !: count of psref held */ u_short l_blcnt; /* !: count of kernel_lock held */ int l_nopreempt; /* !: don't preempt me! */ u_int l_dopreempt; /* s: kernel preemption pending */ Index: src/sys/sys/userret.h diff -u src/sys/sys/userret.h:1.26 src/sys/sys/userret.h:1.27 --- src/sys/sys/userret.h:1.26 Sun Apr 7 07:54:53 2013 +++ src/sys/sys/userret.h Fri Apr 19 01:52:55 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: userret.h,v 1.26 2013/04/07 07:54:53 kiyohara Exp $ */ +/* $NetBSD: userret.h,v 1.27 2019/04/19 01:52:55 ozaki-r Exp $ */ /*- * Copyright (c) 1998, 2000, 2003, 2006, 2008 The NetBSD Foundation, Inc. @@ -114,6 +114,7 @@ mi_userret(struct lwp *l) LOCKDEBUG_BARRIER(NULL, 0); KASSERT(l->l_nopreempt == 0); + KASSERT(l->l_psrefs == 0); } #endif /* !_SYS_USERRET_H_ */