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