Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Add a kernel_lock_plug_leak() that drops any holds and t...



details:   https://anonhg.NetBSD.org/src/rev/403f10544e48
branches:  trunk
changeset: 744223:403f10544e48
user:      ad <ad%NetBSD.org@localhost>
date:      Mon Jan 27 21:05:43 2020 +0000

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

diffstat:

 sys/kern/kern_lock.c |  35 +++++++++++++++++++++++++++++++++--
 sys/sys/lock.h       |   4 +++-
 2 files changed, 36 insertions(+), 3 deletions(-)

diffs (85 lines):

diff -r da953ebc7666 -r 403f10544e48 sys/kern/kern_lock.c
--- a/sys/kern/kern_lock.c      Mon Jan 27 20:54:59 2020 +0000
+++ b/sys/kern/kern_lock.c      Mon Jan 27 21:05:43 2020 +0000
@@ -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 @@
 #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 @@
        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 @@
 {
        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
+}
diff -r da953ebc7666 -r 403f10544e48 sys/sys/lock.h
--- a/sys/sys/lock.h    Mon Jan 27 20:54:59 2020 +0000
+++ b/sys/sys/lock.h    Mon Jan 27 21:05:43 2020 +0000
@@ -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 @@
 
 extern __cpu_simple_lock_t kernel_lock[];
 
+void   kernel_lock_plug_leak(void);
+
 #endif /* _KERNEL */
 
 #endif /* _SYS_LOCK_H_ */



Home | Main Index | Thread Index | Old Index