Module Name:    src
Committed By:   ad
Date:           Mon Jan 27 21:05:43 UTC 2020

Modified Files:
        src/sys/kern: kern_lock.c
        src/sys/sys: lock.h

Log Message:
Add a kernel_lock_plug_leak() that drops any holds and tries to identify
the baddy.


To generate a diff of this commit:
cvs rdiff -u -r1.167 -r1.168 src/sys/kern/kern_lock.c
cvs rdiff -u -r1.87 -r1.88 src/sys/sys/lock.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_lock.c
diff -u src/sys/kern/kern_lock.c:1.167 src/sys/kern/kern_lock.c:1.168
--- src/sys/kern/kern_lock.c:1.167	Fri Jan 24 20:05:15 2020
+++ src/sys/kern/kern_lock.c	Mon Jan 27 21:05:43 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_lock.c,v 1.167 2020/01/24 20:05:15 ad Exp $	*/
+/*	$NetBSD: kern_lock.c,v 1.168 2020/01/27 21:05:43 ad Exp $	*/
 
 /*-
  * Copyright (c) 2002, 2006, 2007, 2008, 2009, 2020 The NetBSD Foundation, Inc.
@@ -31,7 +31,11 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_lock.c,v 1.167 2020/01/24 20:05:15 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_lock.c,v 1.168 2020/01/27 21:05:43 ad Exp $");
+
+#ifdef _KERNEL_OPT
+#include "opt_lockdebug.h"
+#endif
 
 #include <sys/param.h>
 #include <sys/proc.h>
@@ -45,6 +49,10 @@ __KERNEL_RCSID(0, "$NetBSD: kern_lock.c,
 #include <sys/lwp.h>
 #include <sys/pserialize.h>
 
+#if defined(DIAGNOSTIC) && !defined(LOCKDEBUG)
+#include <sys/ksyms.h>
+#endif
+
 #include <machine/lock.h>
 
 #include <dev/lockstat.h>
@@ -215,6 +223,9 @@ _kernel_lock(int nlocks)
 	membar_producer();
 	owant = ci->ci_biglock_wanted;
 	ci->ci_biglock_wanted = l;
+#if defined(DIAGNOSTIC) && !defined(LOCKDEBUG)
+	l->l_ld_wanted = __builtin_return_address(0);
+#endif
 
 	/*
 	 * Spin until we acquire the lock.  Once we have it, record the
@@ -330,3 +341,23 @@ _kernel_locked_p(void)
 {
 	return __SIMPLELOCK_LOCKED_P(kernel_lock);
 }
+
+void
+kernel_lock_plug_leak(void)
+{
+#ifndef LOCKDEBUG
+# ifdef DIAGNOSTIC
+	int biglocks = 0;
+	KERNEL_UNLOCK_ALL(curlwp, &biglocks);
+	if (biglocks != 0) {
+		const char *sym = "(unknown)";
+		ksyms_getname(NULL, &sym, (vaddr_t)curlwp->l_ld_wanted,
+		    KSYMS_CLOSEST|KSYMS_PROC|KSYMS_ANY);
+		printf("kernel_lock leak detected. last acquired: %s / %p\n",
+		    sym, curlwp->l_ld_wanted);
+	}
+# else
+	KERNEL_UNLOCK_ALL(curlwp, NULL);
+# endif
+#endif
+}

Index: src/sys/sys/lock.h
diff -u src/sys/sys/lock.h:1.87 src/sys/sys/lock.h:1.88
--- src/sys/sys/lock.h:1.87	Tue Jul 10 19:55:05 2018
+++ src/sys/sys/lock.h	Mon Jan 27 21:05:43 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: lock.h,v 1.87 2018/07/10 19:55:05 maya Exp $	*/
+/*	$NetBSD: lock.h,v 1.88 2020/01/27 21:05:43 ad Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2006, 2007 The NetBSD Foundation, Inc.
@@ -109,6 +109,8 @@ do {								\
 
 extern __cpu_simple_lock_t kernel_lock[];
 
+void	kernel_lock_plug_leak(void);
+
 #endif /* _KERNEL */
 
 #endif /* _SYS_LOCK_H_ */

Reply via email to