Module Name: src Committed By: pooka Date: Thu May 2 19:15:02 UTC 2013
Modified Files: src/lib/librumpuser: rumpuser.3 rumpuser_pth.c rumpuser_pth_dummy.c src/sys/rump/include/machine: cpu.h src/sys/rump/include/rump: rumpuser.h src/sys/rump/librump/rumpkern: lwproc.c rump.c scheduler.c threads.c src/sys/rump/librump/rumpkern/arch/i386: rumpcpu.c Log Message: Inform the rump kernel hypervisor of valid thread contexts so that the implementation can allocate and release storage for them in an optimal fashion, if necessary. To generate a diff of this commit: cvs rdiff -u -r1.5 -r1.6 src/lib/librumpuser/rumpuser.3 cvs rdiff -u -r1.22 -r1.23 src/lib/librumpuser/rumpuser_pth.c cvs rdiff -u -r1.12 -r1.13 src/lib/librumpuser/rumpuser_pth_dummy.c cvs rdiff -u -r1.15 -r1.16 src/sys/rump/include/machine/cpu.h cvs rdiff -u -r1.100 -r1.101 src/sys/rump/include/rump/rumpuser.h cvs rdiff -u -r1.21 -r1.22 src/sys/rump/librump/rumpkern/lwproc.c cvs rdiff -u -r1.266 -r1.267 src/sys/rump/librump/rumpkern/rump.c cvs rdiff -u -r1.32 -r1.33 src/sys/rump/librump/rumpkern/scheduler.c cvs rdiff -u -r1.20 -r1.21 src/sys/rump/librump/rumpkern/threads.c cvs rdiff -u -r1.10 -r1.11 src/sys/rump/librump/rumpkern/arch/i386/rumpcpu.c 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.3 diff -u src/lib/librumpuser/rumpuser.3:1.5 src/lib/librumpuser/rumpuser.3:1.6 --- src/lib/librumpuser/rumpuser.3:1.5 Thu May 2 15:32:19 2013 +++ src/lib/librumpuser/rumpuser.3 Thu May 2 19:14:59 2013 @@ -1,4 +1,4 @@ -.\" $NetBSD: rumpuser.3,v 1.5 2013/05/02 15:32:19 pooka Exp $ +.\" $NetBSD: rumpuser.3,v 1.6 2013/05/02 19:14:59 pooka Exp $ .\" .\" Copyright (c) 2013 Antti Kantee. All rights reserved. .\" @@ -450,25 +450,53 @@ The cookie matches the value from .Fn rumpuser_thread_create . .Pp .Ft void -.Fn rumpuser_set_curlwp "struct lwp *l" +.Fn rumpuser_curlwpop "enum rumplwpop op" "struct lwp *l" .Pp +Manipulate the hypervisor's thread context database. +The possible operations are create, destroy and set as specified by +.Fa op : +.Bl -tag -width "XRUMPUSER_LWP_DESTROY" +.It Dv RUMPUSER_LWP_CREATE +Inform the hypervisor that +.Fa l +is now a valid thread context which may be set. +A currently valid value of +.Fa l +may not be specified. +This operation is informational and does not mandate any action +from the hypervisor. +.It Dv RUMPUSER_LWP_DESTROY +Inform the hypervisor that +.Fa l +is no longer a valid thread context. +This means that it may no longer be set as the current context. +A currently set context or an invalid one may not be destroyed. +This operation is informational and does not mandate any action +from the hypervisor. +.It Dv RUMPUSER_LWP_SET Set .Fa l -as the rump kernel thread context for the calling host thread. +as the current host thread's rump kernel context. The value .Dv NULL means that an existing rump kernel context (which must exist) must be cleared. +.El .Pp .Ft struct lwp * -.Fn rumpuser_get_curlwp "void" +.Fn rumpuser_curlwp "void" .Pp -Retrieve the rump kernel thread context previously set by -.Fn rumpuser_set_curlwp . -This routine can be called when a context does not exist and +Retrieve the rump kernel thread context associated with the current host +thread, as set by +.Fn rumpuser_curlwpop . +This routine may be called when a context is not set and the routine must return .Dv NULL in that case. +This interface is expected to be called very often. +Any optimizations pertaining to the execution speed of this routine +should be done in +.Fn rumpuser_curlwpop . .Pp .Ft void .Fn rumpuser_seterrno "int errno" Index: src/lib/librumpuser/rumpuser_pth.c diff -u src/lib/librumpuser/rumpuser_pth.c:1.22 src/lib/librumpuser/rumpuser_pth.c:1.23 --- src/lib/librumpuser/rumpuser_pth.c:1.22 Thu May 2 16:49:08 2013 +++ src/lib/librumpuser/rumpuser_pth.c Thu May 2 19:14:59 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: rumpuser_pth.c,v 1.22 2013/05/02 16:49:08 pooka Exp $ */ +/* $NetBSD: rumpuser_pth.c,v 1.23 2013/05/02 19:14:59 pooka Exp $ */ /* * Copyright (c) 2007-2010 Antti Kantee. All Rights Reserved. @@ -28,9 +28,11 @@ #include "rumpuser_port.h" #if !defined(lint) -__RCSID("$NetBSD: rumpuser_pth.c,v 1.22 2013/05/02 16:49:08 pooka Exp $"); +__RCSID("$NetBSD: rumpuser_pth.c,v 1.23 2013/05/02 19:14:59 pooka Exp $"); #endif /* !lint */ +#include <sys/queue.h> + #include <assert.h> #include <errno.h> #include <fcntl.h> @@ -53,14 +55,14 @@ struct rumpuser_mtx { int flags; }; -#define RURW_AMWRITER(rw) (rw->writer == rumpuser_get_curlwp() \ +#define RURW_AMWRITER(rw) (rw->writer == rumpuser_curlwp() \ && rw->readers == -1) #define RURW_HASREAD(rw) (rw->readers > 0) #define RURW_SETWRITE(rw) \ do { \ assert(rw->readers == 0); \ - rw->writer = rumpuser_get_curlwp(); \ + rw->writer = rumpuser_curlwp(); \ rw->readers = -1; \ } while (/*CONSTCOND*/0) #define RURW_CLRWRITE(rw) \ @@ -193,7 +195,7 @@ mtxenter(struct rumpuser_mtx *mtx) return; assert(mtx->owner == NULL); - mtx->owner = rumpuser_get_curlwp(); + mtx->owner = rumpuser_curlwp(); } static void @@ -460,17 +462,106 @@ rumpuser_cv_has_waiters(struct rumpuser_ * curlwp */ +/* + * the if0'd curlwp implementation is not used by this hypervisor, + * but serves as test code to check that the intended usage works. + */ +#if 0 +struct rumpuser_lwp { + struct lwp *l; + LIST_ENTRY(rumpuser_lwp) l_entries; +}; +static LIST_HEAD(, rumpuser_lwp) lwps = LIST_HEAD_INITIALIZER(lwps); +static pthread_mutex_t lwplock = PTHREAD_MUTEX_INITIALIZER; + void -rumpuser_set_curlwp(struct lwp *l) +rumpuser_curlwpop(enum rumplwpop op, struct lwp *l) { + struct rumpuser_lwp *rl, *rliter; - assert(pthread_getspecific(curlwpkey) == NULL || l == NULL); - pthread_setspecific(curlwpkey, l); + switch (op) { + case RUMPUSER_LWP_CREATE: + rl = malloc(sizeof(*rl)); + rl->l = l; + pthread_mutex_lock(&lwplock); + LIST_FOREACH(rliter, &lwps, l_entries) { + if (rliter->l == l) { + fprintf(stderr, "LWP_CREATE: %p exists\n", l); + abort(); + } + } + LIST_INSERT_HEAD(&lwps, rl, l_entries); + pthread_mutex_unlock(&lwplock); + break; + case RUMPUSER_LWP_DESTROY: + pthread_mutex_lock(&lwplock); + LIST_FOREACH(rl, &lwps, l_entries) { + if (rl->l == l) + break; + } + if (!rl) { + fprintf(stderr, "LWP_DESTROY: %p does not exist\n", l); + abort(); + } + LIST_REMOVE(rl, l_entries); + pthread_mutex_unlock(&lwplock); + free(rl); + break; + case RUMPUSER_LWP_SET: + assert(pthread_getspecific(curlwpkey) == NULL || l == NULL); + + if (l) { + pthread_mutex_lock(&lwplock); + LIST_FOREACH(rl, &lwps, l_entries) { + if (rl->l == l) + break; + } + if (!rl) { + fprintf(stderr, + "LWP_SET: %p does not exist\n", l); + abort(); + } + pthread_mutex_unlock(&lwplock); + } else { + rl = NULL; + } + + pthread_setspecific(curlwpkey, rl); + break; + } } struct lwp * -rumpuser_get_curlwp(void) +rumpuser_curlwp(void) +{ + struct rumpuser_lwp *rl; + + rl = pthread_getspecific(curlwpkey); + return rl ? rl->l : NULL; +} + +#else + +void +rumpuser_curlwpop(enum rumplwpop op, struct lwp *l) +{ + + switch (op) { + case RUMPUSER_LWP_CREATE: + break; + case RUMPUSER_LWP_DESTROY: + break; + case RUMPUSER_LWP_SET: + assert(pthread_getspecific(curlwpkey) == NULL || l == NULL); + pthread_setspecific(curlwpkey, l); + break; + } +} + +struct lwp * +rumpuser_curlwp(void) { return pthread_getspecific(curlwpkey); } +#endif Index: src/lib/librumpuser/rumpuser_pth_dummy.c diff -u src/lib/librumpuser/rumpuser_pth_dummy.c:1.12 src/lib/librumpuser/rumpuser_pth_dummy.c:1.13 --- src/lib/librumpuser/rumpuser_pth_dummy.c:1.12 Tue Apr 30 13:37:03 2013 +++ src/lib/librumpuser/rumpuser_pth_dummy.c Thu May 2 19:14:59 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: rumpuser_pth_dummy.c,v 1.12 2013/04/30 13:37:03 pooka Exp $ */ +/* $NetBSD: rumpuser_pth_dummy.c,v 1.13 2013/05/02 19:14:59 pooka Exp $ */ /* * Copyright (c) 2009 Antti Kantee. All Rights Reserved. @@ -29,7 +29,7 @@ #include <sys/cdefs.h> #if !defined(lint) -__RCSID("$NetBSD: rumpuser_pth_dummy.c,v 1.12 2013/04/30 13:37:03 pooka Exp $"); +__RCSID("$NetBSD: rumpuser_pth_dummy.c,v 1.13 2013/05/02 19:14:59 pooka Exp $"); #endif /* !lint */ #include <sys/time.h> @@ -283,14 +283,21 @@ rumpuser_cv_has_waiters(struct rumpuser_ */ void -rumpuser_set_curlwp(struct lwp *l) +rumpuser_curlwpop(enum rumplwpop op, struct lwp *l) { - curlwp = l; + switch (op) { + case RUMPUSER_LWP_CREATE: + case RUMPUSER_LWP_DESTROY: + break; + case RUMPUSER_LWP_SET: + curlwp = l; + break; + } } struct lwp * -rumpuser_get_curlwp(void) +rumpuser_curlwp(void) { return curlwp; Index: src/sys/rump/include/machine/cpu.h diff -u src/sys/rump/include/machine/cpu.h:1.15 src/sys/rump/include/machine/cpu.h:1.16 --- src/sys/rump/include/machine/cpu.h:1.15 Mon Mar 21 16:41:08 2011 +++ src/sys/rump/include/machine/cpu.h Thu May 2 19:15:00 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.h,v 1.15 2011/03/21 16:41:08 pooka Exp $ */ +/* $NetBSD: cpu.h,v 1.16 2013/05/02 19:15:00 pooka Exp $ */ /* * Copyright (c) 2008-2011 Antti Kantee. All Rights Reserved. @@ -73,8 +73,8 @@ static __inline void cpu_handle_ipi(void void __syncicache(void *, size_t); #endif -struct lwp *rumpuser_get_curlwp(void); -#define curlwp rumpuser_get_curlwp() +struct lwp *rumpuser_curlwp(void); +#define curlwp rumpuser_curlwp() #define curcpu() (curlwp->l_cpu) #define cpu_number() (cpu_index(curcpu)) Index: src/sys/rump/include/rump/rumpuser.h diff -u src/sys/rump/include/rump/rumpuser.h:1.100 src/sys/rump/include/rump/rumpuser.h:1.101 --- src/sys/rump/include/rump/rumpuser.h:1.100 Tue Apr 30 16:03:44 2013 +++ src/sys/rump/include/rump/rumpuser.h Thu May 2 19:15:01 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: rumpuser.h,v 1.100 2013/04/30 16:03:44 pooka Exp $ */ +/* $NetBSD: rumpuser.h,v 1.101 2013/05/02 19:15:01 pooka Exp $ */ /* * Copyright (c) 2007-2013 Antti Kantee. All Rights Reserved. @@ -164,8 +164,9 @@ int rumpuser_thread_create(void *(*f)(v void rumpuser_thread_exit(void) __dead; int rumpuser_thread_join(void *); -void rumpuser_set_curlwp(struct lwp *); -struct lwp *rumpuser_get_curlwp(void); +enum rumplwpop { RUMPUSER_LWP_CREATE, RUMPUSER_LWP_DESTROY, RUMPUSER_LWP_SET }; +void rumpuser_curlwpop(enum rumplwpop, struct lwp *); +struct lwp *rumpuser_curlwp(void); struct rumpuser_mtx; #define RUMPUSER_MTX_SPIN 0x01 Index: src/sys/rump/librump/rumpkern/lwproc.c diff -u src/sys/rump/librump/rumpkern/lwproc.c:1.21 src/sys/rump/librump/rumpkern/lwproc.c:1.22 --- src/sys/rump/librump/rumpkern/lwproc.c:1.21 Sun Apr 28 23:19:33 2013 +++ src/sys/rump/librump/rumpkern/lwproc.c Thu May 2 19:15:01 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: lwproc.c,v 1.21 2013/04/28 23:19:33 pooka Exp $ */ +/* $NetBSD: lwproc.c,v 1.22 2013/05/02 19:15:01 pooka Exp $ */ /* * Copyright (c) 2010, 2011 Antti Kantee. All Rights Reserved. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: lwproc.c,v 1.21 2013/04/28 23:19:33 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: lwproc.c,v 1.22 2013/05/02 19:15:01 pooka Exp $"); #include <sys/param.h> #include <sys/atomic.h> @@ -196,7 +196,7 @@ lwproc_freelwp(struct lwp *l) KASSERT(p != &proc0); p->p_stat = SDEAD; } - cv_broadcast(&p->p_lwpcv); /* nobody sleeps on this in rump? */ + cv_broadcast(&p->p_lwpcv); /* nobody sleeps on this in a rump kernel? */ kauth_cred_free(l->l_cred); mutex_exit(p->p_lock); @@ -208,6 +208,8 @@ lwproc_freelwp(struct lwp *l) kmem_free(l->l_name, MAXCOMLEN); lwp_finispecific(l); + rumpuser_curlwpop(RUMPUSER_LWP_DESTROY, l); + membar_exit(); kmem_free(l, sizeof(*l)); if (p->p_stat == SDEAD) @@ -241,6 +243,8 @@ lwproc_makelwp(struct proc *p, struct lw lwp_update_creds(l); lwp_initspecific(l); + membar_enter(); + rumpuser_curlwpop(RUMPUSER_LWP_CREATE, l); if (doswitch) { rump_lwproc_switch(l); } @@ -348,13 +352,13 @@ rump_lwproc_switch(struct lwp *newlwp) fd_free(); } - rumpuser_set_curlwp(NULL); + rumpuser_curlwpop(RUMPUSER_LWP_SET, NULL); newlwp->l_cpu = newlwp->l_target_cpu = l->l_cpu; newlwp->l_mutex = l->l_mutex; newlwp->l_pflag |= LP_RUNNING; - rumpuser_set_curlwp(newlwp); + rumpuser_curlwpop(RUMPUSER_LWP_SET, newlwp); /* * Check if the thread should get a signal. This is Index: src/sys/rump/librump/rumpkern/rump.c diff -u src/sys/rump/librump/rumpkern/rump.c:1.266 src/sys/rump/librump/rumpkern/rump.c:1.267 --- src/sys/rump/librump/rumpkern/rump.c:1.266 Tue Apr 30 16:03:44 2013 +++ src/sys/rump/librump/rumpkern/rump.c Thu May 2 19:15:01 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: rump.c,v 1.266 2013/04/30 16:03:44 pooka Exp $ */ +/* $NetBSD: rump.c,v 1.267 2013/05/02 19:15:01 pooka Exp $ */ /* * Copyright (c) 2007-2011 Antti Kantee. All Rights Reserved. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.266 2013/04/30 16:03:44 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.267 2013/05/02 19:15:01 pooka Exp $"); #include <sys/systm.h> #define ELFSIZE ARCH_ELFSIZE @@ -288,7 +288,10 @@ rump_init(void) l->l_lid = 1; l->l_cpu = l->l_target_cpu = rump_cpu; l->l_fd = &filedesc0; - rumpuser_set_curlwp(l); + + /* lwp0 isn't created like other threads, so notify hypervisor here */ + rumpuser_curlwpop(RUMPUSER_LWP_CREATE, l); + rumpuser_curlwpop(RUMPUSER_LWP_SET, l); rumpuser_mutex_init(&rump_giantlock, RUMPUSER_MTX_SPIN); ksyms_init(); @@ -342,7 +345,7 @@ rump_init(void) rump_scheduler_init(numcpu); /* revert temporary context and schedule a semireal context */ - rumpuser_set_curlwp(NULL); + rumpuser_curlwpop(RUMPUSER_LWP_SET, NULL); initproc = &proc0; /* borrow proc0 before we get initproc started */ rump_schedule(); bootlwp = curlwp; Index: src/sys/rump/librump/rumpkern/scheduler.c diff -u src/sys/rump/librump/rumpkern/scheduler.c:1.32 src/sys/rump/librump/rumpkern/scheduler.c:1.33 --- src/sys/rump/librump/rumpkern/scheduler.c:1.32 Sat Apr 27 22:26:57 2013 +++ src/sys/rump/librump/rumpkern/scheduler.c Thu May 2 19:15:01 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: scheduler.c,v 1.32 2013/04/27 22:26:57 pooka Exp $ */ +/* $NetBSD: scheduler.c,v 1.33 2013/05/02 19:15:01 pooka Exp $ */ /* * Copyright (c) 2010, 2011 Antti Kantee. All Rights Reserved. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: scheduler.c,v 1.32 2013/04/27 22:26:57 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: scheduler.c,v 1.33 2013/05/02 19:15:01 pooka Exp $"); #include <sys/param.h> #include <sys/atomic.h> @@ -225,7 +225,8 @@ lwp0rele(void) /* * rump_schedule: ensure that the calling host thread has a valid lwp context. - * ie. ensure that rumpuser_get_curlwp() != NULL. + * ie. ensure that curlwp != NULL. Also, ensure that there + * a 1:1 mapping between the lwp and rump kernel cpu. */ void rump_schedule() @@ -239,7 +240,7 @@ rump_schedule() * for this case -- anyone who cares about performance will * start a real thread. */ - if (__predict_true((l = rumpuser_get_curlwp()) != NULL)) { + if (__predict_true((l = rumpuser_curlwp()) != NULL)) { rump_schedule_cpu(l); LWP_CACHE_CREDS(l, l->l_proc); } else { @@ -247,7 +248,7 @@ rump_schedule() /* schedule cpu and use lwp0 */ rump_schedule_cpu(&lwp0); - rumpuser_set_curlwp(&lwp0); + rumpuser_curlwpop(RUMPUSER_LWP_SET, &lwp0); /* allocate thread, switch to it, and release lwp0 */ l = rump__lwproc_alloclwp(initproc); @@ -364,7 +365,7 @@ rump_schedule_cpu_interlock(struct lwp * void rump_unschedule() { - struct lwp *l = rumpuser_get_curlwp(); + struct lwp *l = rumpuser_curlwp(); #ifdef DIAGNOSTIC int nlock; @@ -398,10 +399,10 @@ rump_unschedule() lwp0.l_mutex = &unruntime_lock; lwp0.l_pflag &= ~LP_RUNNING; lwp0rele(); - rumpuser_set_curlwp(NULL); + rumpuser_curlwpop(RUMPUSER_LWP_SET, NULL); } else if (__predict_false(l->l_flag & LW_RUMP_CLEAR)) { - rumpuser_set_curlwp(NULL); + rumpuser_curlwpop(RUMPUSER_LWP_SET, NULL); l->l_flag &= ~LW_RUMP_CLEAR; } } Index: src/sys/rump/librump/rumpkern/threads.c diff -u src/sys/rump/librump/rumpkern/threads.c:1.20 src/sys/rump/librump/rumpkern/threads.c:1.21 --- src/sys/rump/librump/rumpkern/threads.c:1.20 Tue Apr 30 13:29:28 2013 +++ src/sys/rump/librump/rumpkern/threads.c Thu May 2 19:15:01 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: threads.c,v 1.20 2013/04/30 13:29:28 pooka Exp $ */ +/* $NetBSD: threads.c,v 1.21 2013/05/02 19:15:01 pooka Exp $ */ /* * Copyright (c) 2007-2009 Antti Kantee. All Rights Reserved. @@ -29,7 +29,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: threads.c,v 1.20 2013/04/30 13:29:28 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: threads.c,v 1.21 2013/05/02 19:15:01 pooka Exp $"); #include <sys/param.h> #include <sys/atomic.h> @@ -73,7 +73,7 @@ threadbouncer(void *arg) } /* schedule ourselves */ - rumpuser_set_curlwp(l); + rumpuser_curlwpop(RUMPUSER_LWP_SET, l); rump_schedule(); /* free dance struct */ Index: src/sys/rump/librump/rumpkern/arch/i386/rumpcpu.c diff -u src/sys/rump/librump/rumpkern/arch/i386/rumpcpu.c:1.10 src/sys/rump/librump/rumpkern/arch/i386/rumpcpu.c:1.11 --- src/sys/rump/librump/rumpkern/arch/i386/rumpcpu.c:1.10 Tue Feb 19 09:04:54 2013 +++ src/sys/rump/librump/rumpkern/arch/i386/rumpcpu.c Thu May 2 19:15:01 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: rumpcpu.c,v 1.10 2013/02/19 09:04:54 martin Exp $ */ +/* $NetBSD: rumpcpu.c,v 1.11 2013/05/02 19:15:01 pooka Exp $ */ /* * Copyright (c) 2008 Antti Kantee. All Rights Reserved. @@ -29,7 +29,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rumpcpu.c,v 1.10 2013/02/19 09:04:54 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rumpcpu.c,v 1.11 2013/05/02 19:15:01 pooka Exp $"); #include <sys/param.h> @@ -65,7 +65,7 @@ struct lwp * x86_curlwp() { - return rumpuser_get_curlwp(); + return rumpuser_curlwp(); } void