kernel - Enhanced lockmgr debugging, panic in double unlock
authorMatthew Dillon <dillon@apollo.backplane.com>
Thu, 1 Dec 2011 23:24:01 +0000 (15:24 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Thu, 1 Dec 2011 23:24:01 +0000 (15:24 -0800)
* Panic if an attempt is made to unlock a lock which is not locked.

* Add some additinal debugging (disabled)

sys/kern/kern_lock.c
sys/kern/vfs_lock.c
sys/kern/vfs_vnops.c
sys/sys/vnode.h

index 10f13ec..f08f364 100644 (file)
@@ -487,6 +487,8 @@ lkmatch1:
                                    td->td_lockmgr_stack_id[i] > 0
                                ) {
                                        td->td_lockmgr_stack_id[i]--;
+                                       lkp->lk_filename = file;
+                                       lkp->lk_lineno = line;
                                        break;
                                }
                        }
@@ -494,6 +496,8 @@ lkmatch1:
                } else if (lkp->lk_flags & LK_SHARE_NONZERO) {
                        dowakeup += shareunlock(lkp, 1);
                        COUNT(td, -1);
+               } else {
+                       panic("lockmgr: LK_RELEASE: no lock held");
                }
                if (lkp->lk_flags & LK_WAIT_NONZERO)
                        ++dowakeup;
index db7423b..52a9a99 100644 (file)
@@ -572,6 +572,18 @@ vget(struct vnode *vp, int flags)
        return(error);
 }
 
+#ifdef DEBUG_VPUT
+
+void
+debug_vput(struct vnode *vp, const char *filename, int line)
+{
+       kprintf("vput(%p) %s:%d\n", vp, filename, line);
+       vn_unlock(vp);
+       vrele(vp);
+}
+
+#else
+
 /*
  * MPSAFE
  */
@@ -582,6 +594,8 @@ vput(struct vnode *vp)
        vrele(vp);
 }
 
+#endif
+
 /*
  * XXX The vx_*() locks should use auxrefs, not the main reference counter.
  *
index 60f3237..27ac2b1 100644 (file)
@@ -1003,15 +1003,25 @@ debug_vn_lock(struct vnode *vp, int flags, const char *filename, int line)
        return (error);
 }
 
-/*
- * MPSAFE
- */
+#ifdef DEBUG_VN_UNLOCK
+
+void
+debug_vn_unlock(struct vnode *vp, const char *filename, int line)
+{
+       kprintf("vn_unlock from %s:%d\n", filename, line);
+       lockmgr(&vp->v_lock, LK_RELEASE);
+}
+
+#else
+
 void
 vn_unlock(struct vnode *vp)
 {
        lockmgr(&vp->v_lock, LK_RELEASE);
 }
 
+#endif
+
 /*
  * MPSAFE
  */
index 8d0008b..24796fc 100644 (file)
@@ -450,17 +450,25 @@ int       vn_cache_strategy(struct vnode *vp, struct bio *bio);
 int    vn_close (struct vnode *vp, int flags);
 void   vn_gone (struct vnode *vp);
 int    vn_isdisk (struct vnode *vp, int *errp);
-int    vn_lock (struct vnode *vp, int flags);
 int    vn_islocked (struct vnode *vp);
 int    vn_islocked_unlock (struct vnode *vp);
 void   vn_islocked_relock (struct vnode *vp, int vpls);
+int    vn_lock (struct vnode *vp, int flags);
 void   vn_unlock (struct vnode *vp);
+
 #ifdef DEBUG_LOCKS
 int    debug_vn_lock (struct vnode *vp, int flags,
                const char *filename, int line);
 #define vn_lock(vp,flags)      debug_vn_lock(vp, flags, __FILE__, __LINE__)
 #endif
 
+/*#define DEBUG_VN_UNLOCK*/
+#ifdef DEBUG_VN_UNLOCK
+void   debug_vn_unlock (struct vnode *vp,
+               const char *filename, int line);
+#define vn_unlock(vp)          debug_vn_unlock(vp, __FILE__, __LINE__)
+#endif
+
 int    vn_get_namelen(struct vnode *, int *);
 void   vn_setspecops (struct file *fp);
 int    vn_fullpath (struct proc *p, struct vnode *vn, char **retbuf, char **freebuf, int guess);
@@ -525,6 +533,12 @@ void       vrele (struct vnode *vp);
 void   vsetflags (struct vnode *vp, int flags);
 void   vclrflags (struct vnode *vp, int flags);
 
+/*#define DEBUG_VPUT*/
+#ifdef DEBUG_VPUT
+void   debug_vput (struct vnode *vp, const char *filename, int line);
+#define vput(vp)               debug_vput(vp, __FILE__, __LINE__)
+#endif
+
 void   vfs_subr_init(void);
 void   vfs_mount_init(void);
 void   vfs_lock_init(void);