Module Name:    src
Committed By:   yamt
Date:           Fri Jun 15 13:51:41 UTC 2012

Modified Files:
        src/sys/kern: kern_turnstile.c

Log Message:
comments and assertions.
no functional changes.


To generate a diff of this commit:
cvs rdiff -u -r1.31 -r1.32 src/sys/kern/kern_turnstile.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/kern_turnstile.c
diff -u src/sys/kern/kern_turnstile.c:1.31 src/sys/kern/kern_turnstile.c:1.32
--- src/sys/kern/kern_turnstile.c:1.31	Fri Dec  2 12:31:53 2011
+++ src/sys/kern/kern_turnstile.c	Fri Jun 15 13:51:40 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_turnstile.c,v 1.31 2011/12/02 12:31:53 yamt Exp $	*/
+/*	$NetBSD: kern_turnstile.c,v 1.32 2012/06/15 13:51:40 yamt Exp $	*/
 
 /*-
  * Copyright (c) 2002, 2006, 2007, 2009 The NetBSD Foundation, Inc.
@@ -60,7 +60,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_turnstile.c,v 1.31 2011/12/02 12:31:53 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_turnstile.c,v 1.32 2012/06/15 13:51:40 yamt Exp $");
 
 #include <sys/param.h>
 #include <sys/lockdebug.h>
@@ -199,7 +199,9 @@ turnstile_exit(wchan_t obj)
  *
  *	Lend our priority to lwps on the blocking chain.
  *
- *
+ *	If the current owner of the lock (l->l_wchan, set by sleepq_enqueue)
+ *	has a priority lower than ours (lwp_eprio(l)), lend our priority to
+ *	him to avoid priority inversions.
  */
 
 static void
@@ -225,29 +227,37 @@ turnstile_lendpri(lwp_t *cur)
 		if (l->l_wchan == NULL)
 			break;
 
+		/*
+		 * Ask syncobj the owner of the lock.
+		 */
 		owner = (*l->l_syncobj->sobj_owner)(l->l_wchan);
 		if (owner == NULL)
 			break;
 
-		/* The owner may have changed as we have dropped the tc lock */
+		/*
+		 * The owner may have changed as we have dropped the tc lock.
+		 */
 		if (cur == owner) {
 			/*
-			 * we own the lock: stop here, sleepq_block()
-			 * should wake up immediatly
+			 * We own the lock: stop here, sleepq_block()
+			 * should wake up immediatly.
 			 */
 			break;
 		}
-		if (l->l_mutex != owner->l_mutex)
-			dolock = true;
-		else
-			dolock = false;
+		/*
+		 * Acquire owner->l_mutex if we don't have it yet.
+		 * Because we already have another LWP lock (l->l_mutex) held,
+		 * we need to play a try lock dance to avoid deadlock.
+		 */
+		dolock = l->l_mutex != owner->l_mutex;
 		if (l == owner || (dolock && !lwp_trylock(owner))) {
 			/*
-			 * restart from curlwp.
+			 * The owner was changed behind us or trylock failed.
+			 * Restart from curlwp.
+			 *
 			 * Note that there may be a livelock here:
-			 * the owner may try grabing cur's lock (which is
-			 * the tc lock) while we're trying to grab
-			 * the owner's lock.
+			 * the owner may try grabing cur's lock (which is the
+			 * tc lock) while we're trying to grab the owner's lock.
 			 */
 			lwp_unlock(l);
 			l = cur;
@@ -255,11 +265,20 @@ turnstile_lendpri(lwp_t *cur)
 			prio = lwp_eprio(l);
 			continue;
 		}
+		/*
+		 * If the owner's priority is already higher than ours,
+		 * there's nothing to do anymore.
+		 */
 		if (prio <= lwp_eprio(owner)) {
 			if (dolock)
 				lwp_unlock(owner);
 			break;
 		}
+		/*
+		 * Lend our priority to the 'owner' LWP.
+		 *
+		 * Update lenders info for turnstile_unlendpri.
+		 */
 		ts = l->l_ts;
 		KASSERT(ts->ts_inheritor == owner || ts->ts_inheritor == NULL);
 		if (ts->ts_inheritor == NULL) {
@@ -273,6 +292,7 @@ turnstile_lendpri(lwp_t *cur)
 		}
 		if (dolock)
 			lwp_unlock(l);
+		LOCKDEBUG_BARRIER(owner->l_mutex, 1);
 		l = owner;
 	}
 	LOCKDEBUG_BARRIER(l->l_mutex, 1);

Reply via email to