svn commit: r335605 - in head/sys: kern sys

Matt Macy mmacy at FreeBSD.org
Sun Jun 24 18:57:07 UTC 2018


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;


More information about the svn-src-head mailing list