Module Name: src Committed By: pooka Date: Fri Sep 4 16:41:39 UTC 2009
Modified Files: src/sys/rump/librump/rumpkern: ltsleep.c Log Message: Actually, we cannot release the megalock before we take sleepermtx, since that opens a race window for non-mpsafe code, so do it after. Additionally, we cannot call mutex_enter() for sleepermtx, since ltsleep/mtsleep should not block (i.e. release kernel lock) before actually blocking, so busyloop in mutex_tryenter(). Finally, when waking up, take kernel lock back only *after* releasing sleepermtx to avoid deadlock against another thread holding the kernel lock and wanting sleepermtx. To generate a diff of this commit: cvs rdiff -u -r1.15 -r1.16 src/sys/rump/librump/rumpkern/ltsleep.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/rump/librump/rumpkern/ltsleep.c diff -u src/sys/rump/librump/rumpkern/ltsleep.c:1.15 src/sys/rump/librump/rumpkern/ltsleep.c:1.16 --- src/sys/rump/librump/rumpkern/ltsleep.c:1.15 Fri Sep 4 13:58:57 2009 +++ src/sys/rump/librump/rumpkern/ltsleep.c Fri Sep 4 16:41:39 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: ltsleep.c,v 1.15 2009/09/04 13:58:57 pooka Exp $ */ +/* $NetBSD: ltsleep.c,v 1.16 2009/09/04 16:41:39 pooka Exp $ */ /* * Copyright (c) 2007 Antti Kantee. All Rights Reserved. @@ -29,7 +29,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ltsleep.c,v 1.15 2009/09/04 13:58:57 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ltsleep.c,v 1.16 2009/09/04 16:41:39 pooka Exp $"); #include <sys/param.h> #include <sys/proc.h> @@ -58,12 +58,12 @@ struct ltsleeper lts; int nlocks; - KERNEL_UNLOCK_ALL(curlwp, &nlocks); - lts.id = ident; cv_init(<s.cv, NULL); - mutex_enter(&sleepermtx); + while (!mutex_tryenter(&sleepermtx)) + continue; + KERNEL_UNLOCK_ALL(curlwp, &nlocks); if (slock) simple_unlock(slock); LIST_INSERT_HEAD(&sleepers, <s, entries); @@ -76,10 +76,11 @@ cv_destroy(<s.cv); + KERNEL_LOCK(nlocks, curlwp); + if (slock && (prio & PNORELOCK) == 0) simple_lock(slock); - KERNEL_LOCK(nlocks, curlwp); return 0; } @@ -90,12 +91,12 @@ struct ltsleeper lts; int nlocks; - KERNEL_UNLOCK_ALL(curlwp, &nlocks); - lts.id = ident; cv_init(<s.cv, NULL); - mutex_enter(&sleepermtx); + while (!mutex_tryenter(&sleepermtx)) + continue; + KERNEL_UNLOCK_ALL(curlwp, &nlocks); LIST_INSERT_HEAD(&sleepers, <s, entries); /* protected by sleepermtx */ @@ -107,10 +108,11 @@ cv_destroy(<s.cv); + KERNEL_LOCK(nlocks, curlwp); + if ((prio & PNORELOCK) == 0) mutex_enter(lock); - KERNEL_LOCK(nlocks, curlwp); return 0; }