Author: jhb
Date: Mon Jun  3 17:41:11 2013
New Revision: 251326
URL: http://svnweb.freebsd.org/changeset/base/251326

Log:
  - Fix a couple of inverted panic messages for shared/exclusive mismatches
    of a lock within a single thread.
  - Fix handling of interlocks in WITNESS by properly requiring the interlock
    to be held exactly once if it is specified.

Modified:
  head/sys/kern/kern_lock.c
  head/sys/kern/subr_witness.c

Modified: head/sys/kern/kern_lock.c
==============================================================================
--- head/sys/kern/kern_lock.c   Mon Jun  3 17:40:52 2013        (r251325)
+++ head/sys/kern/kern_lock.c   Mon Jun  3 17:41:11 2013        (r251326)
@@ -511,7 +511,7 @@ __lockmgr_args(struct lock *lk, u_int fl
        case LK_SHARED:
                if (LK_CAN_WITNESS(flags))
                        WITNESS_CHECKORDER(&lk->lock_object, LOP_NEWORDER,
-                           file, line, ilk);
+                           file, line, flags & LK_INTERLOCK ? ilk : NULL);
                for (;;) {
                        x = lk->lk_lock;
 
@@ -723,7 +723,8 @@ __lockmgr_args(struct lock *lk, u_int fl
        case LK_EXCLUSIVE:
                if (LK_CAN_WITNESS(flags))
                        WITNESS_CHECKORDER(&lk->lock_object, LOP_NEWORDER |
-                           LOP_EXCLUSIVE, file, line, ilk);
+                           LOP_EXCLUSIVE, file, line, flags & LK_INTERLOCK ?
+                           ilk : NULL);
 
                /*
                 * If curthread already holds the lock and this one is
@@ -1072,7 +1073,8 @@ __lockmgr_args(struct lock *lk, u_int fl
        case LK_DRAIN:
                if (LK_CAN_WITNESS(flags))
                        WITNESS_CHECKORDER(&lk->lock_object, LOP_NEWORDER |
-                           LOP_EXCLUSIVE, file, line, ilk);
+                           LOP_EXCLUSIVE, file, line, flags & LK_INTERLOCK ?
+                           ilk : NULL);
 
                /*
                 * Trying to drain a lock we already own will result in a

Modified: head/sys/kern/subr_witness.c
==============================================================================
--- head/sys/kern/subr_witness.c        Mon Jun  3 17:40:52 2013        
(r251325)
+++ head/sys/kern/subr_witness.c        Mon Jun  3 17:41:11 2013        
(r251326)
@@ -1053,7 +1053,7 @@ witness_checkorder(struct lock_object *l
 {
        struct lock_list_entry *lock_list, *lle;
        struct lock_instance *lock1, *lock2, *plock;
-       struct lock_class *class;
+       struct lock_class *class, *iclass;
        struct witness *w, *w1;
        struct thread *td;
        int i, j;
@@ -1119,7 +1119,7 @@ witness_checkorder(struct lock_object *l
                            fixup_filename(file), line);
                        printf("while exclusively locked from %s:%d\n",
                            fixup_filename(lock1->li_file), lock1->li_line);
-                       kassert_panic("share->excl");
+                       kassert_panic("excl->share");
                }
                if ((lock1->li_flags & LI_EXCLUSIVE) == 0 &&
                    (flags & LOP_EXCLUSIVE) != 0) {
@@ -1128,11 +1128,27 @@ witness_checkorder(struct lock_object *l
                            fixup_filename(file), line);
                        printf("while share locked from %s:%d\n",
                            fixup_filename(lock1->li_file), lock1->li_line);
-                       kassert_panic("excl->share");
+                       kassert_panic("share->excl");
                }
                return;
        }
 
+       /* Warn if the interlock is not locked exactly once. */
+       if (interlock != NULL) {
+               iclass = LOCK_CLASS(interlock);
+               lock1 = find_instance(lock_list, interlock);
+               if (lock1 == NULL)
+                       kassert_panic("interlock (%s) %s not locked @ %s:%d",
+                           iclass->lc_name, interlock->lo_name,
+                           flags & LOP_EXCLUSIVE ? "exclusive" : "shared",
+                           fixup_filename(file), line);
+               else if ((lock1->li_flags & LI_RECURSEMASK) != 0)
+                       kassert_panic("interlock (%s) %s recursed @ %s:%d",
+                           iclass->lc_name, interlock->lo_name,
+                           flags & LOP_EXCLUSIVE ? "exclusive" : "shared",
+                           fixup_filename(file), line);
+       }
+
        /*
         * Find the previously acquired lock, but ignore interlocks.
         */
@@ -1205,12 +1221,10 @@ witness_checkorder(struct lock_object *l
                        lock1 = &lle->ll_children[i];
 
                        /*
-                        * Ignore the interlock the first time we see it.
+                        * Ignore the interlock.
                         */
-                       if (interlock != NULL && interlock == lock1->li_lock) {
-                               interlock = NULL;
+                       if (interlock == lock1->li_lock)
                                continue;
-                       }
 
                        /*
                         * If this lock doesn't undergo witness checking,
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to