svn commit: r303938 - projects/hps_head/sys/kern

Hans Petter Selasky hselasky at FreeBSD.org
Wed Aug 10 18:53:12 UTC 2016


Author: hselasky
Date: Wed Aug 10 18:53:10 2016
New Revision: 303938
URL: https://svnweb.freebsd.org/changeset/base/303938

Log:
  Solve a LOR between the callout mutex and the sleepqueue mutex after
  recent changes. This is solved by making a custom msleep_spin()
  implementation where the sleepqueue mutex is locked first.

Modified:
  projects/hps_head/sys/kern/kern_timeout.c

Modified: projects/hps_head/sys/kern/kern_timeout.c
==============================================================================
--- projects/hps_head/sys/kern/kern_timeout.c	Wed Aug 10 18:45:26 2016	(r303937)
+++ projects/hps_head/sys/kern/kern_timeout.c	Wed Aug 10 18:53:10 2016	(r303938)
@@ -1266,22 +1266,36 @@ callout_drain(struct callout *c)
 	retval = callout_async_drain(c, &callout_drain_function);
 
 	if (retval == CALLOUT_RET_DRAINING) {
+		void *ident = &callout_drain_function;
 		struct callout_cpu *cc;
 		int direct;
+		int busy;
 
 		CTR3(KTR_CALLOUT, "need to drain %p func %p arg %p",
 		    c, c->c_func, c->c_arg);
 
-		cc = callout_lock(c);
-		direct = ((c->c_flags & CALLOUT_DIRECT) != 0);
-
-		/* Wait for drain to complete */
-		while (cc_exec_curr(cc, direct) == c) {
-			msleep_spin(&callout_drain_function,
-			    (struct mtx *)&cc->cc_lock, "codrain", 0);
-		}
+		do {
+			/*
+			 * The sleepq_lock() is lower rank than the
+			 * callout_lock() and must be locked first:
+			 */
+			sleepq_lock(ident);
+			cc = callout_lock(c);
+			direct = ((c->c_flags & CALLOUT_DIRECT) != 0);
+			busy = (cc_exec_curr(cc, direct) == c);
+			CC_UNLOCK(cc);
+			DROP_GIANT();
+
+			if (busy && !SCHEDULER_STOPPED()) {
+				/* Wait for drain to complete */
+				sleepq_add(ident, &cc->cc_lock.lock_object, "codrain", SLEEPQ_SLEEP, 0);
+				sleepq_wait(ident, 0);
+			} else {
+				sleepq_release(ident);
+			}
 
-		CC_UNLOCK(cc);
+			PICKUP_GIANT();
+		} while (busy);
 	}
 
 	CTR4(KTR_CALLOUT, "%s: %p func %p arg %p",


More information about the svn-src-projects mailing list