Author: mmacy
Date: Sun Jun 24 18:57:06 2018
New Revision: 335605
URL: https://svnweb.freebsd.org/changeset/base/335605

Log:
  fix assert and conditionally allow mutexes to be held across 
epoch_wait_preempt

Modified:
  head/sys/kern/subr_epoch.c
  head/sys/sys/epoch.h

Modified: head/sys/kern/subr_epoch.c
==============================================================================
--- head/sys/kern/subr_epoch.c  Sun Jun 24 15:22:38 2018        (r335604)
+++ head/sys/kern/subr_epoch.c  Sun Jun 24 18:57:06 2018        (r335605)
@@ -375,9 +375,11 @@ epoch_block_handler_preempt(struct ck_epoch *global __
        struct turnstile *ts;
        struct lock_object *lock;
        int spincount, gen;
+       int locksheld __unused;
 
        record = __containerof(cr, struct epoch_record, er_record);
        td = curthread;
+       locksheld = td->td_locks;
        spincount = 0;
        counter_u64_add(block_count, 1);
        if (record->er_cpuid != curcpu) {
@@ -470,8 +472,8 @@ epoch_block_handler_preempt(struct ck_epoch *global __
                                turnstile_unlock(ts, lock);
                        thread_lock(td);
                        critical_exit();
-                       KASSERT(td->td_locks == 0,
-                           ("%d locks held", td->td_locks));
+                       KASSERT(td->td_locks == locksheld,
+                           ("%d extra locks held", td->td_locks - locksheld));
                }
        }
        /*
@@ -499,23 +501,20 @@ epoch_wait_preempt(epoch_t epoch)
        int old_cpu;
        int old_pinned;
        u_char old_prio;
-#ifdef INVARIANTS
-       int locks;
+       int locks __unused;
 
-       locks = curthread->td_locks;
-#endif
-
        MPASS(cold || epoch != NULL);
        INIT_CHECK(epoch);
-
-       MPASS(epoch->e_flags & EPOCH_PREEMPT);
-       WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
-           "epoch_wait() can sleep");
-
        td = curthread;
+#ifdef INVARIANTS
+       locks = curthread->td_locks;
+       MPASS(epoch->e_flags & EPOCH_PREEMPT);
+       if ((epoch->e_flags & EPOCH_LOCKED) == 0)
+               WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
+                   "epoch_wait() can be long running");
        KASSERT(td->td_epochnest == 0, ("epoch_wait() in the middle of an epoch 
section"));
+#endif
        thread_lock(td);
-
        DROP_GIANT();
 
        old_cpu = PCPU_GET(cpuid);

Modified: head/sys/sys/epoch.h
==============================================================================
--- head/sys/sys/epoch.h        Sun Jun 24 15:22:38 2018        (r335604)
+++ head/sys/sys/epoch.h        Sun Jun 24 18:57:06 2018        (r335605)
@@ -39,6 +39,7 @@ struct epoch;
 typedef struct epoch *epoch_t;
 
 #define EPOCH_PREEMPT 0x1
+#define EPOCH_LOCKED 0x2
 
 extern epoch_t global_epoch;
 extern epoch_t global_epoch_preempt;
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to