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);
 

Reply via email to