Module Name: src Committed By: snj Date: Mon Sep 28 01:38:24 UTC 2009
Modified Files: src/sys/kern [netbsd-5]: kern_turnstile.c Log Message: Pull up following revision(s) (requested by bouyer in ticket #1028): sys/kern/kern_turnstile.c: revision 1.25 via patch PR kern/41923: assertion "cur != owner" failed In the for(;;) loop of turnstile_block(), the lock owner can change while cur's lock is released (cur's lock is also the tschain_t's mutex). Remove the KASSERT about owner being invariant and try to deal with the fact that the owner can change instead. http://mail-index.netbsd.org/tech-kern/2009/08/24/msg005957.html and followups. To generate a diff of this commit: cvs rdiff -u -r1.23 -r1.23.4.1 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.23 src/sys/kern/kern_turnstile.c:1.23.4.1 --- src/sys/kern/kern_turnstile.c:1.23 Tue Aug 12 14:13:34 2008 +++ src/sys/kern/kern_turnstile.c Mon Sep 28 01:38:24 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_turnstile.c,v 1.23 2008/08/12 14:13:34 thorpej Exp $ */ +/* $NetBSD: kern_turnstile.c,v 1.23.4.1 2009/09/28 01:38:24 snj Exp $ */ /*- * Copyright (c) 2002, 2006, 2007 The NetBSD Foundation, Inc. @@ -60,7 +60,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_turnstile.c,v 1.23 2008/08/12 14:13:34 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_turnstile.c,v 1.23.4.1 2009/09/28 01:38:24 snj Exp $"); #include <sys/param.h> #include <sys/lockdebug.h> @@ -253,6 +253,7 @@ sq = &ts->ts_sleepq[q]; ts->ts_waiters[q]++; sleepq_enter(sq, l, &tc->tc_mutex); + /* now tc->tc_mutex is also cur->l_mutex and l->l_mutex */ LOCKDEBUG_BARRIER(&tc->tc_mutex, 1); l->l_kpriority = true; obase = l->l_kpribase; @@ -275,6 +276,7 @@ * compiling a kernel with LOCKDEBUG to pinpoint the problem. */ prio = lwp_eprio(l); + for (;;) { bool dolock; @@ -285,9 +287,24 @@ if (owner == NULL) break; - KASSERT(l != owner); - KASSERT(cur != owner); + /* 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 + */ + break; + } + if (l == owner) { + /* owner has changed, restart from curlwp */ + lwp_unlock(l); + l = cur; + lwp_lock(l); + prio = lwp_eprio(l); + continue; + } + if (l->l_mutex != owner->l_mutex) dolock = true; else @@ -295,6 +312,10 @@ if (dolock && !lwp_trylock(owner)) { /* * 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. */ lwp_unlock(l); l = cur;