kernel -- lockmgr debugging.
authorVenkatesh Srinivas <me@endeavour.zapto.org>
Tue, 25 Jan 2011 12:58:54 +0000 (04:58 -0800)
committerVenkatesh Srinivas <me@endeavour.zapto.org>
Tue, 25 Jan 2011 12:58:54 +0000 (04:58 -0800)
* Track exclusive lockmgr locks held by a thread in a per-td stack,
  td->td_lockmgr_stack[]. The stack also tracks the depth of the lockmgr
  recursion, if any.

* Move td->td_locks count from SIMPLELOCK_DEBUG to DEBUG_LOCKS; we have not
  used a simplelock to interlock lockmgr lock updates in a very long time.

sys/conf/options
sys/config/LINT
sys/kern/kern_lock.c
sys/sys/thread.h

index 6ac400b..e818a7c 100644 (file)
@@ -474,7 +474,6 @@ DEBUG_LOCKS         opt_global.h
 DEBUG_CRIT_SECTIONS    opt_global.h
 DIAGNOSTIC             opt_global.h
 INVARIANTS             opt_global.h
-SIMPLELOCK_DEBUG       opt_global.h
 VFS_BIO_DEBUG          opt_global.h
 DEBUG_INTERRUPTS       opt_global.h
 SOCKBUF_DEBUG          opt_global.h
index 3e8a786..dadcc15 100644 (file)
@@ -2845,7 +2845,6 @@ options   SCSI_NCR_MAX_SYNC=10000
 options        SCSI_NCR_MAX_WIDE=1
 options        SCSI_NCR_MYADDR=7
 options        SHOW_BUSYBUFS   # List buffers that prevent root unmount
-options        SIMPLELOCK_DEBUG
 options        SI_DEBUG
 options        SLIP_IFF_OPTS
 options        SOCKBUF_DEBUG
index 890ce07..da26055 100644 (file)
@@ -59,7 +59,7 @@
  * Locks provide shared/exclusive sychronization.
  */
 
-#ifdef SIMPLELOCK_DEBUG
+#ifdef DEBUG_LOCKS
 #define COUNT(td, x) (td)->td_locks += (x)
 #else
 #define COUNT(td, x)
@@ -163,6 +163,9 @@ debuglockmgr(struct lock *lkp, u_int flags,
        int error;
        int extflags;
        int dowakeup;
+#ifdef DEBUG_LOCKS
+       int i;
+#endif
 
        error = 0;
        dowakeup = 0;
@@ -250,6 +253,18 @@ debuglockmgr(struct lock *lkp, u_int flags,
                        spin_unlock(&lkp->lk_spinlock);
                        panic("lockmgr: not holding exclusive lock");
                }
+
+#ifdef DEBUG_LOCKS
+               for (i = 0; i < LOCKMGR_DEBUG_ARRAY_SIZE; i++) {
+                       if (td->td_lockmgr_stack[i] == lkp &&
+                           td->td_lockmgr_stack_id[i] > 0
+                       ) {
+                               td->td_lockmgr_stack_id[i]--;
+                               break;
+                       }
+               }
+#endif
+
                sharelock(lkp, lkp->lk_exclusivecount);
                lkp->lk_exclusivecount = 0;
                lkp->lk_flags &= ~LK_HAVE_EXCL;
@@ -326,6 +341,31 @@ debuglockmgr(struct lock *lkp, u_int flags,
                        lkp->lk_filename = file;
                        lkp->lk_lineno = line;
                        lkp->lk_lockername = name;
+
+                       for (i = 0; i < LOCKMGR_DEBUG_ARRAY_SIZE; i++) {
+                               /*
+                                * Recursive lockmgr path
+                                */
+                               if (td->td_lockmgr_stack[i] == lkp &&
+                                   td->td_lockmgr_stack_id[i] != 0
+                               ) {
+                                       td->td_lockmgr_stack_id[i]++;
+                                       goto lkmatch2;
+                               }
+                      }
+
+                       for (i = 0; i < LOCKMGR_DEBUG_ARRAY_SIZE; i++) {
+                               /*
+                                * Use new lockmgr tracking slot
+                                */
+                               if (td->td_lockmgr_stack_id[i] == 0) {
+                                       td->td_lockmgr_stack_id[i]++;
+                                       td->td_lockmgr_stack[i] = lkp;
+                                       break;
+                               }
+                       }
+lkmatch2:
+                       ;
 #endif
                        COUNT(td, 1);
                        break;
@@ -395,9 +435,34 @@ debuglockmgr(struct lock *lkp, u_int flags,
                }
                lkp->lk_exclusivecount = 1;
 #if defined(DEBUG_LOCKS)
-                       lkp->lk_filename = file;
-                       lkp->lk_lineno = line;
-                       lkp->lk_lockername = name;
+               lkp->lk_filename = file;
+               lkp->lk_lineno = line;
+               lkp->lk_lockername = name;
+
+                for (i = 0; i < LOCKMGR_DEBUG_ARRAY_SIZE; i++) {
+                       /*
+                        * Recursive lockmgr path
+                        */
+                       if (td->td_lockmgr_stack[i] == lkp &&
+                           td->td_lockmgr_stack_id[i] != 0
+                       ) {
+                               td->td_lockmgr_stack_id[i]++;
+                               goto lkmatch1;
+                       }
+                }
+
+               for (i = 0; i < LOCKMGR_DEBUG_ARRAY_SIZE; i++) {
+                       /*
+                        * Use new lockmgr tracking slot
+                        */
+                       if (td->td_lockmgr_stack_id[i] == 0) {
+                               td->td_lockmgr_stack_id[i]++;
+                               td->td_lockmgr_stack[i] = lkp;
+                               break;
+                        }
+               }
+lkmatch1:
+               ;
 #endif
                COUNT(td, 1);
                break;
@@ -422,6 +487,16 @@ debuglockmgr(struct lock *lkp, u_int flags,
                        } else {
                                lkp->lk_exclusivecount--;
                        }
+#ifdef DEBUG_LOCKS
+                       for (i = 0; i < LOCKMGR_DEBUG_ARRAY_SIZE; i++) {
+                               if (td->td_lockmgr_stack[i] == lkp &&
+                                   td->td_lockmgr_stack_id[i] > 0
+                               ) {
+                                       td->td_lockmgr_stack_id[i]--;
+                                       break;
+                               }
+                       }
+#endif
                } else if (lkp->lk_flags & LK_SHARE_NONZERO) {
                        dowakeup += shareunlock(lkp, 1);
                        COUNT(td, -1);
index 139a229..7672e63 100644 (file)
@@ -28,6 +28,9 @@
 #ifndef _SYS_TIME_H_
 #include <sys/time.h>          /* struct timeval */
 #endif
+#ifndef _SYS_LOCK_H
+#include <sys/lock.h>
+#endif
 #ifndef _SYS_SPINLOCK_H_
 #include <sys/spinlock.h>
 #endif
@@ -290,6 +293,13 @@ struct thread {
    int         td_spinlock_stack_id[SPINLOCK_DEBUG_ARRAY_SIZE];
    struct spinlock *td_spinlock_stack[SPINLOCK_DEBUG_ARRAY_SIZE];
    void        *td_spinlock_caller_pc[SPINLOCK_DEBUG_ARRAY_SIZE];
+
+    /*
+     * Track lockmgr locks held; lk->lk_filename:lk->lk_lineno is the holder
+     */
+#define LOCKMGR_DEBUG_ARRAY_SIZE       8
+    int                td_lockmgr_stack_id[LOCKMGR_DEBUG_ARRAY_SIZE];
+    struct lock        *td_lockmgr_stack[LOCKMGR_DEBUG_ARRAY_SIZE];
 #endif
 };