Module Name: src
Committed By: pooka
Date: Wed Dec 1 14:59:39 UTC 2010
Modified Files:
src/lib/librumpuser: rumpuser_pth.c
src/sys/rump/include/rump: rumpuser.h
src/sys/rump/librump/rumpkern: intr.c klock.c locks.c ltsleep.c rump.c
rump_private.h
Log Message:
Track lwp as the rumpuser mutex owner instead of pthread_t (this
is done in rumpuser for simplicity, since on the kernel side things
we assume we have only one pointer of space). As a side-effect,
we can no longer know if the current thread is holding on to a
mutex locked without curlwp context (basically all mutexes inited
outside of mutex_init()). The only thing that called rumpuser_mutex_held()
for a non-kmutex was the giant lock. So, instead implement recursive
locking for the giant lock in the rump kernel and get rid of the
now-unused recursive pthread mutex in the hypercall interface.
To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/lib/librumpuser/rumpuser_pth.c
cvs rdiff -u -r1.54 -r1.55 src/sys/rump/include/rump/rumpuser.h
cvs rdiff -u -r1.34 -r1.35 src/sys/rump/librump/rumpkern/intr.c
cvs rdiff -u -r1.2 -r1.3 src/sys/rump/librump/rumpkern/klock.c
cvs rdiff -u -r1.42 -r1.43 src/sys/rump/librump/rumpkern/locks.c
cvs rdiff -u -r1.27 -r1.28 src/sys/rump/librump/rumpkern/ltsleep.c
cvs rdiff -u -r1.207 -r1.208 src/sys/rump/librump/rumpkern/rump.c
cvs rdiff -u -r1.64 -r1.65 src/sys/rump/librump/rumpkern/rump_private.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/lib/librumpuser/rumpuser_pth.c
diff -u src/lib/librumpuser/rumpuser_pth.c:1.3 src/lib/librumpuser/rumpuser_pth.c:1.4
--- src/lib/librumpuser/rumpuser_pth.c:1.3 Mon May 31 23:09:30 2010
+++ src/lib/librumpuser/rumpuser_pth.c Wed Dec 1 14:59:37 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: rumpuser_pth.c,v 1.3 2010/05/31 23:09:30 pooka Exp $ */
+/* $NetBSD: rumpuser_pth.c,v 1.4 2010/12/01 14:59:37 pooka Exp $ */
/*
* Copyright (c) 2007-2010 Antti Kantee. All Rights Reserved.
@@ -27,7 +27,7 @@
#include <sys/cdefs.h>
#if !defined(lint)
-__RCSID("$NetBSD: rumpuser_pth.c,v 1.3 2010/05/31 23:09:30 pooka Exp $");
+__RCSID("$NetBSD: rumpuser_pth.c,v 1.4 2010/12/01 14:59:37 pooka Exp $");
#endif /* !lint */
#ifdef __linux__
@@ -62,22 +62,20 @@
} \
} while (/*CONSTCOND*/0)
-#define RUMTX_INCRECURSION(mtx) ((mtx)->recursion++)
-#define RUMTX_DECRECURSION(mtx) ((mtx)->recursion--)
struct rumpuser_mtx {
pthread_mutex_t pthmtx;
- pthread_t owner;
- unsigned recursion;
+ struct lwp *owner;
+ int iskmutex;
};
-#define RURW_AMWRITER(rw) (pthread_equal(rw->writer, pthread_self()) \
+#define RURW_AMWRITER(rw) (rw->writer == rumpuser_get_curlwp() \
&& rw->readers == -1)
#define RURW_HASREAD(rw) (rw->readers > 0)
#define RURW_SETWRITE(rw) \
do { \
assert(rw->readers == 0); \
- rw->writer = pthread_self(); \
+ rw->writer = rumpuser_get_curlwp(); \
rw->readers = -1; \
} while (/*CONSTCOND*/0)
#define RURW_CLRWRITE(rw) \
@@ -104,7 +102,7 @@
pthread_rwlock_t pthrw;
pthread_spinlock_t spin;
int readers;
- pthread_t writer;
+ struct lwp *writer;
};
struct rumpuser_cv {
@@ -277,11 +275,19 @@
pthread_mutexattr_destroy(&att);
(*mtx)->owner = NULL;
- (*mtx)->recursion = 0;
+ (*mtx)->iskmutex = 0;
}
void
-rumpuser_mutex_recursive_init(struct rumpuser_mtx **mtx)
+rumpuser_mutex_init_kmutex(struct rumpuser_mtx **mtx)
+{
+
+ rumpuser_mutex_init(mtx);
+ (*mtx)->iskmutex = 1;
+}
+
+void
+rumpuser_mutex_init_krecursive(struct rumpuser_mtx **mtx)
{
pthread_mutexattr_t mattr;
@@ -291,7 +297,7 @@
NOFAIL(*mtx = malloc(sizeof(struct rumpuser_mtx)));
NOFAIL_ERRNO(pthread_mutex_init(&((*mtx)->pthmtx), &mattr));
(*mtx)->owner = NULL;
- (*mtx)->recursion = 0;
+ (*mtx)->iskmutex = 1;
pthread_mutexattr_destroy(&mattr);
}
@@ -300,21 +306,22 @@
mtxenter(struct rumpuser_mtx *mtx)
{
- if (mtx->recursion++ == 0) {
- assert(mtx->owner == NULL);
- mtx->owner = pthread_self();
- } else {
- assert(pthread_equal(mtx->owner, pthread_self()));
- }
+ if (!mtx->iskmutex)
+ return;
+
+ assert(mtx->owner == NULL);
+ mtx->owner = rumpuser_get_curlwp();
}
static void
mtxexit(struct rumpuser_mtx *mtx)
{
+ if (!mtx->iskmutex)
+ return;
+
assert(mtx->owner != NULL);
- if (--mtx->recursion == 0)
- mtx->owner = NULL;
+ mtx->owner = NULL;
}
void
@@ -367,7 +374,12 @@
rumpuser_mutex_held(struct rumpuser_mtx *mtx)
{
- return mtx->recursion && pthread_equal(mtx->owner, pthread_self());
+ if (__predict_false(!mtx->iskmutex)) {
+ printf("panic: rumpuser_mutex_held unsupported on non-kmtx\n");
+ abort();
+ }
+
+ return mtx->owner == rumpuser_get_curlwp();
}
void
@@ -481,7 +493,6 @@
cv->nwaiters++;
rumpuser__kunlock(0, &nlocks, mtx);
- assert(mtx->recursion == 1);
mtxexit(mtx);
NOFAIL_ERRNO(pthread_cond_wait(&cv->pthcv, &mtx->pthmtx));
mtxenter(mtx);
@@ -494,7 +505,6 @@
{
cv->nwaiters++;
- assert(mtx->recursion == 1);
mtxexit(mtx);
NOFAIL_ERRNO(pthread_cond_wait(&cv->pthcv, &mtx->pthmtx));
mtxenter(mtx);
Index: src/sys/rump/include/rump/rumpuser.h
diff -u src/sys/rump/include/rump/rumpuser.h:1.54 src/sys/rump/include/rump/rumpuser.h:1.55
--- src/sys/rump/include/rump/rumpuser.h:1.54 Tue Nov 30 14:23:24 2010
+++ src/sys/rump/include/rump/rumpuser.h Wed Dec 1 14:59:39 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: rumpuser.h,v 1.54 2010/11/30 14:23:24 pooka Exp $ */
+/* $NetBSD: rumpuser.h,v 1.55 2010/12/01 14:59:39 pooka Exp $ */
/*
* Copyright (c) 2007 Antti Kantee. All Rights Reserved.
@@ -126,7 +126,7 @@
struct rumpuser_mtx;
void rumpuser_mutex_init(struct rumpuser_mtx **);
-void rumpuser_mutex_recursive_init(struct rumpuser_mtx **);
+void rumpuser_mutex_init_kmutex(struct rumpuser_mtx **);
void rumpuser_mutex_enter(struct rumpuser_mtx *);
void rumpuser_mutex_enter_nowrap(struct rumpuser_mtx *);
int rumpuser_mutex_tryenter(struct rumpuser_mtx *);
Index: src/sys/rump/librump/rumpkern/intr.c
diff -u src/sys/rump/librump/rumpkern/intr.c:1.34 src/sys/rump/librump/rumpkern/intr.c:1.35
--- src/sys/rump/librump/rumpkern/intr.c:1.34 Tue Sep 7 18:25:38 2010
+++ src/sys/rump/librump/rumpkern/intr.c Wed Dec 1 14:59:38 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: intr.c,v 1.34 2010/09/07 18:25:38 pooka Exp $ */
+/* $NetBSD: intr.c,v 1.35 2010/12/01 14:59:38 pooka Exp $ */
/*
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.34 2010/09/07 18:25:38 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.35 2010/12/01 14:59:38 pooka Exp $");
#include <sys/param.h>
#include <sys/atomic.h>
@@ -119,7 +119,7 @@
rumpuser_cv_init(&clockcv);
rumpuser_mutex_init(&clockmtx);
- rumpuser_mutex_enter(clockmtx);
+ rumpuser_mutex_enter_nowrap(clockmtx);
for (;;) {
callout_hardclock();
Index: src/sys/rump/librump/rumpkern/klock.c
diff -u src/sys/rump/librump/rumpkern/klock.c:1.2 src/sys/rump/librump/rumpkern/klock.c:1.3
--- src/sys/rump/librump/rumpkern/klock.c:1.2 Tue May 18 15:16:10 2010
+++ src/sys/rump/librump/rumpkern/klock.c Wed Dec 1 14:59:38 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: klock.c,v 1.2 2010/05/18 15:16:10 pooka Exp $ */
+/* $NetBSD: klock.c,v 1.3 2010/12/01 14:59:38 pooka Exp $ */
/*
* Copyright (c) 2007-2010 Antti Kantee. All Rights Reserved.
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: klock.c,v 1.2 2010/05/18 15:16:10 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: klock.c,v 1.3 2010/12/01 14:59:38 pooka Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -42,57 +42,48 @@
* giant lock
*/
-static volatile int lockcnt;
-
-bool
-rump_kernel_isbiglocked()
-{
-
- return rumpuser_mutex_held(rump_giantlock) && lockcnt > 0;
-}
+struct rumpuser_mtx *rump_giantlock;
+static int giantcnt;
+static struct lwp *giantowner;
void
-rump_kernel_unlock_allbutone(int *countp)
+rump_kernel_bigwrap(int *nlocks)
{
- int minusone = lockcnt-1;
-
- KASSERT(rump_kernel_isbiglocked());
- if (minusone) {
- _kernel_unlock(minusone, countp);
- }
- KASSERT(lockcnt == 1);
- *countp = minusone;
- /*
- * We drop lockcnt to 0 since rumpuser doesn't know that the
- * kernel biglock is being used as the interlock for cv in
- * tsleep.
- */
- lockcnt = 0;
+ KASSERT(giantcnt > 0 && curlwp == giantowner);
+ giantowner = NULL;
+ *nlocks = giantcnt;
+ giantcnt = 0;
}
void
-rump_kernel_ununlock_allbutone(int nlocks)
+rump_kernel_bigunwrap(int nlocks)
{
- KASSERT(rumpuser_mutex_held(rump_giantlock) && lockcnt == 0);
- lockcnt = 1;
- _kernel_lock(nlocks);
+ KASSERT(giantowner == NULL);
+ giantowner = curlwp;
+ giantcnt = nlocks;
}
void
_kernel_lock(int nlocks)
{
+ struct lwp *l = curlwp;
- while (nlocks--) {
- if (!rumpuser_mutex_tryenter(rump_giantlock)) {
- struct lwp *l = curlwp;
-
- rump_unschedule_cpu1(l, NULL);
- rumpuser_mutex_enter_nowrap(rump_giantlock);
- rump_schedule_cpu(l);
+ while (nlocks) {
+ if (giantowner == l) {
+ giantcnt += nlocks;
+ nlocks = 0;
+ } else {
+ if (!rumpuser_mutex_tryenter(rump_giantlock)) {
+ rump_unschedule_cpu1(l, NULL);
+ rumpuser_mutex_enter_nowrap(rump_giantlock);
+ rump_schedule_cpu(l);
+ }
+ giantowner = l;
+ giantcnt = 1;
+ nlocks--;
}
- lockcnt++;
}
}
@@ -100,7 +91,7 @@
_kernel_unlock(int nlocks, int *countp)
{
- if (!rumpuser_mutex_held(rump_giantlock)) {
+ if (giantowner != curlwp) {
KASSERT(nlocks == 0);
if (countp)
*countp = 0;
@@ -108,16 +99,20 @@
}
if (countp)
- *countp = lockcnt;
+ *countp = giantcnt;
if (nlocks == 0)
- nlocks = lockcnt;
+ nlocks = giantcnt;
if (nlocks == -1) {
- KASSERT(lockcnt == 1);
+ KASSERT(giantcnt == 1);
nlocks = 1;
}
- KASSERT(nlocks <= lockcnt);
+ KASSERT(nlocks <= giantcnt);
while (nlocks--) {
- lockcnt--;
+ giantcnt--;
+ }
+
+ if (giantcnt == 0) {
+ giantowner = NULL;
rumpuser_mutex_exit(rump_giantlock);
}
}
Index: src/sys/rump/librump/rumpkern/locks.c
diff -u src/sys/rump/librump/rumpkern/locks.c:1.42 src/sys/rump/librump/rumpkern/locks.c:1.43
--- src/sys/rump/librump/rumpkern/locks.c:1.42 Wed Jun 9 07:54:13 2010
+++ src/sys/rump/librump/rumpkern/locks.c Wed Dec 1 14:59:38 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: locks.c,v 1.42 2010/06/09 07:54:13 pooka Exp $ */
+/* $NetBSD: locks.c,v 1.43 2010/12/01 14:59:38 pooka Exp $ */
/*
* Copyright (c) 2007, 2008 Antti Kantee. All Rights Reserved.
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: locks.c,v 1.42 2010/06/09 07:54:13 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: locks.c,v 1.43 2010/12/01 14:59:38 pooka Exp $");
#include <sys/param.h>
#include <sys/kmem.h>
@@ -60,7 +60,7 @@
CTASSERT(sizeof(kmutex_t) >= sizeof(void *));
- rumpuser_mutex_init((struct rumpuser_mtx **)mtx);
+ rumpuser_mutex_init_kmutex((struct rumpuser_mtx **)mtx);
}
void
Index: src/sys/rump/librump/rumpkern/ltsleep.c
diff -u src/sys/rump/librump/rumpkern/ltsleep.c:1.27 src/sys/rump/librump/rumpkern/ltsleep.c:1.28
--- src/sys/rump/librump/rumpkern/ltsleep.c:1.27 Mon May 31 23:18:33 2010
+++ src/sys/rump/librump/rumpkern/ltsleep.c Wed Dec 1 14:59:38 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: ltsleep.c,v 1.27 2010/05/31 23:18:33 pooka Exp $ */
+/* $NetBSD: ltsleep.c,v 1.28 2010/12/01 14:59:38 pooka Exp $ */
/*
* Copyright (c) 2009, 2010 Antti Kantee. All Rights Reserved.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ltsleep.c,v 1.27 2010/05/31 23:18:33 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ltsleep.c,v 1.28 2010/12/01 14:59:38 pooka Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -128,18 +128,19 @@
{
int rv, nlocks;
+ if (slock)
+ simple_unlock(slock);
+
/*
* Since we cannot use slock as the rumpuser interlock,
* require that everyone using this prehistoric interface
- * is biglocked.
+ * is biglocked. Wrap around the biglock and drop lockcnt,
+ * but retain the rumpuser mutex so that we can use it as an
+ * interlock to rumpuser_cv_wait().
*/
- KASSERT(rump_kernel_isbiglocked());
- if (slock)
- simple_unlock(slock);
-
- rump_kernel_unlock_allbutone(&nlocks);
+ rump_kernel_bigwrap(&nlocks);
rv = sleeper(ident, timo, NULL);
- rump_kernel_ununlock_allbutone(nlocks);
+ rump_kernel_bigunwrap(nlocks);
if (slock && (prio & PNORELOCK) == 0)
simple_lock(slock);
Index: src/sys/rump/librump/rumpkern/rump.c
diff -u src/sys/rump/librump/rumpkern/rump.c:1.207 src/sys/rump/librump/rumpkern/rump.c:1.208
--- src/sys/rump/librump/rumpkern/rump.c:1.207 Tue Nov 30 14:23:24 2010
+++ src/sys/rump/librump/rumpkern/rump.c Wed Dec 1 14:59:38 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: rump.c,v 1.207 2010/11/30 14:23:24 pooka Exp $ */
+/* $NetBSD: rump.c,v 1.208 2010/12/01 14:59:38 pooka Exp $ */
/*
* Copyright (c) 2007 Antti Kantee. All Rights Reserved.
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.207 2010/11/30 14:23:24 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.208 2010/12/01 14:59:38 pooka Exp $");
#include <sys/systm.h>
#define ELFSIZE ARCH_ELFSIZE
@@ -88,8 +88,6 @@
struct proc *initproc;
-struct rumpuser_mtx *rump_giantlock;
-
struct device rump_rootdev = {
.dv_class = DV_VIRTUAL
};
@@ -306,7 +304,7 @@
rumpuser_set_curlwp(l);
mutex_init(&tty_lock, MUTEX_DEFAULT, IPL_NONE);
- rumpuser_mutex_recursive_init(&rump_giantlock);
+ rumpuser_mutex_init(&rump_giantlock);
ksyms_init();
uvm_init();
evcnt_init();
Index: src/sys/rump/librump/rumpkern/rump_private.h
diff -u src/sys/rump/librump/rumpkern/rump_private.h:1.64 src/sys/rump/librump/rumpkern/rump_private.h:1.65
--- src/sys/rump/librump/rumpkern/rump_private.h:1.64 Sun Nov 21 22:01:15 2010
+++ src/sys/rump/librump/rumpkern/rump_private.h Wed Dec 1 14:59:38 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: rump_private.h,v 1.64 2010/11/21 22:01:15 pooka Exp $ */
+/* $NetBSD: rump_private.h,v 1.65 2010/12/01 14:59:38 pooka Exp $ */
/*
* Copyright (c) 2007 Antti Kantee. All Rights Reserved.
@@ -115,9 +115,8 @@
void rump_cpu_attach(struct cpu_info *);
-bool rump_kernel_isbiglocked(void);
-void rump_kernel_unlock_allbutone(int *);
-void rump_kernel_ununlock_allbutone(int);
+void rump_kernel_bigwrap(int *);
+void rump_kernel_bigunwrap(int);
void rump_tsleep_init(void);