Module Name: src
Committed By: pooka
Date: Tue Dec 1 09:50:51 UTC 2009
Modified Files:
src/sys/rump/librump/rumpkern: intr.c locks.c rump.c rump_private.h
scheduler.c threads.c
Log Message:
Almost there for virtual CPU MP support:
* support bound kernel threads
* bind softint threads to specific virtual cpus
+ remove now-unnecessary locks from softint code
Now, if we only had MI CPU_INFO_FOREACH() .... (hi rmind ;)
To generate a diff of this commit:
cvs rdiff -u -r1.21 -r1.22 src/sys/rump/librump/rumpkern/intr.c
cvs rdiff -u -r1.35 -r1.36 src/sys/rump/librump/rumpkern/locks.c
cvs rdiff -u -r1.142 -r1.143 src/sys/rump/librump/rumpkern/rump.c
cvs rdiff -u -r1.36 -r1.37 src/sys/rump/librump/rumpkern/rump_private.h
cvs rdiff -u -r1.7 -r1.8 src/sys/rump/librump/rumpkern/scheduler.c
cvs rdiff -u -r1.3 -r1.4 src/sys/rump/librump/rumpkern/threads.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/intr.c
diff -u src/sys/rump/librump/rumpkern/intr.c:1.21 src/sys/rump/librump/rumpkern/intr.c:1.22
--- src/sys/rump/librump/rumpkern/intr.c:1.21 Wed Nov 11 16:46:50 2009
+++ src/sys/rump/librump/rumpkern/intr.c Tue Dec 1 09:50:51 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: intr.c,v 1.21 2009/11/11 16:46:50 pooka Exp $ */
+/* $NetBSD: intr.c,v 1.22 2009/12/01 09:50:51 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.21 2009/11/11 16:46:50 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.22 2009/12/01 09:50:51 pooka Exp $");
#include <sys/param.h>
#include <sys/cpu.h>
@@ -58,10 +58,10 @@
};
static struct rumpuser_mtx *si_mtx;
-static struct softint_lev {
+struct softint_lev {
struct rumpuser_cv *si_cv;
LIST_HEAD(, softint) si_pending;
-} softints[SOFTINT_COUNT];
+};
/* rumpuser structures since we call rumpuser interfaces directly */
static struct rumpuser_cv *clockcv;
@@ -117,15 +117,17 @@
for (;;) {
callout_hardclock();
- if (++ticks == hz) {
- time_uptime++;
- ticks = 0;
- }
-
/* wait until the next tick. XXX: what if the clock changes? */
while (rumpuser_cv_timedwait(clockcv, clockmtx,
curtime.tv_sec, curtime.tv_nsec) == 0)
continue;
+
+ /* if !maincpu: continue */
+
+ if (++ticks == hz) {
+ time_uptime++;
+ ticks = 0;
+ }
clkgen++;
timespecadd(&clockup, &tick, &clockup);
@@ -147,11 +149,18 @@
void *funarg;
bool mpsafe;
int mylevel = (uintptr_t)arg;
- struct softint_lev *si_lvl;
+ struct softint_lev *si_lvlp, *si_lvl;
+ struct cpu_data *cd = &curcpu()->ci_data;
rump_unschedule();
- si_lvl = &softints[mylevel];
+ si_lvlp = cd->cpu_softcpu;
+ si_lvl = &si_lvlp[mylevel];
+
+ /*
+ * XXX: si_mtx is unnecessary, and should open an interface
+ * which allows to use schedmtx for the cv wait
+ */
rumpuser_mutex_enter_nowrap(si_mtx);
for (;;) {
if (!LIST_EMPTY(&si_lvl->si_pending)) {
@@ -191,38 +200,54 @@
}
void
+rump_intr_init()
+{
+
+ rumpuser_mutex_init(&si_mtx);
+ rumpuser_cv_init(&clockcv);
+ rumpuser_mutex_init(&clockmtx);
+}
+
+void
softint_init(struct cpu_info *ci)
{
+ struct cpu_data *cd = &ci->ci_data;
+ struct softint_lev *slev;
int rv, i;
- rumpuser_mutex_init(&si_mtx);
+ if (!rump_threads)
+ return;
+
+ slev = kmem_alloc(sizeof(struct softint_lev) * SOFTINT_COUNT, KM_SLEEP);
for (i = 0; i < SOFTINT_COUNT; i++) {
- rumpuser_cv_init(&softints[i].si_cv);
- LIST_INIT(&softints[i].si_pending);
+ rumpuser_cv_init(&slev[i].si_cv);
+ LIST_INIT(&slev[i].si_pending);
}
+ cd->cpu_softcpu = slev;
- rumpuser_cv_init(&clockcv);
- rumpuser_mutex_init(&clockmtx);
-
- /* XXX: should have separate "wanttimer" control */
- if (rump_threads) {
- for (i = 0; i < SOFTINT_COUNT; i++) {
- rv = kthread_create(PRI_NONE,
- KTHREAD_MPSAFE | KTHREAD_INTR, NULL,
- sithread, (void *)(uintptr_t)i,
- NULL, "rumpsi%d", i);
- }
+ for (i = 0; i < SOFTINT_COUNT; i++) {
+ rv = kthread_create(PRI_NONE,
+ KTHREAD_MPSAFE | KTHREAD_INTR, NULL,
+ sithread, (void *)(uintptr_t)i,
+ NULL, "rumpsi%d", i);
+ }
- rumpuser_mutex_enter(clockmtx);
- rv = kthread_create(PRI_NONE, KTHREAD_MPSAFE | KTHREAD_INTR,
- NULL, doclock, NULL, NULL, "rumpclk");
+ rumpuser_mutex_enter(clockmtx);
+ for (i = 0; i < ncpu; i++) {
+ rv = kthread_create(PRI_NONE,
+ KTHREAD_MPSAFE | KTHREAD_INTR,
+ cpu_lookup(i), doclock, NULL, NULL,
+ "rumpclk%d", i);
if (rv)
panic("clock thread creation failed: %d", rv);
-
- /* make sure we have a clocktime before returning */
- rumpuser_cv_wait(clockcv, clockmtx);
- rumpuser_mutex_exit(clockmtx);
}
+
+ /*
+ * Make sure we have a clocktime before returning.
+ * XXX: mp
+ */
+ rumpuser_cv_wait(clockcv, clockmtx);
+ rumpuser_mutex_exit(clockmtx);
}
/*
@@ -254,17 +279,17 @@
softint_schedule(void *arg)
{
struct softint *si = arg;
+ struct cpu_data *cd = &curcpu()->ci_data;
+ struct softint_lev *si_lvl = cd->cpu_softcpu;
if (!rump_threads) {
si->si_func(si->si_arg);
} else {
- rumpuser_mutex_enter(si_mtx);
if (!(si->si_flags & SI_ONLIST)) {
- LIST_INSERT_HEAD(&softints[si->si_level].si_pending,
+ LIST_INSERT_HEAD(&si_lvl[si->si_level].si_pending,
si, si_entries);
si->si_flags |= SI_ONLIST;
}
- rumpuser_mutex_exit(si_mtx);
}
}
@@ -286,14 +311,17 @@
void
rump_softint_run(struct cpu_info *ci)
{
+ struct cpu_data *cd = &ci->ci_data;
+ struct softint_lev *si_lvl = cd->cpu_softcpu;
int i;
- rumpuser_mutex_enter_nowrap(si_mtx);
+ if (!rump_threads)
+ return;
+
for (i = 0; i < SOFTINT_COUNT; i++) {
- if (!LIST_EMPTY(&softints[i].si_pending))
- rumpuser_cv_signal(softints[i].si_cv);
+ if (!LIST_EMPTY(&si_lvl[i].si_pending))
+ rumpuser_cv_signal(si_lvl[i].si_cv);
}
- rumpuser_mutex_exit(si_mtx);
}
bool
Index: src/sys/rump/librump/rumpkern/locks.c
diff -u src/sys/rump/librump/rumpkern/locks.c:1.35 src/sys/rump/librump/rumpkern/locks.c:1.36
--- src/sys/rump/librump/rumpkern/locks.c:1.35 Thu Nov 26 17:29:34 2009
+++ src/sys/rump/librump/rumpkern/locks.c Tue Dec 1 09:50:51 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: locks.c,v 1.35 2009/11/26 17:29:34 pooka Exp $ */
+/* $NetBSD: locks.c,v 1.36 2009/12/01 09:50:51 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.35 2009/11/26 17:29:34 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: locks.c,v 1.36 2009/12/01 09:50:51 pooka Exp $");
#include <sys/param.h>
#include <sys/kmem.h>
@@ -330,7 +330,7 @@
if (!rumpuser_mutex_tryenter(rump_giantlock)) {
struct lwp *l = curlwp;
- rump_unschedule_cpu(l);
+ rump_unschedule_cpu1(l);
rumpuser_mutex_enter_nowrap(rump_giantlock);
rump_schedule_cpu(l);
}
@@ -369,6 +369,10 @@
{
_kernel_unlock(nlocks, countp);
+ /*
+ * XXX: technically we should unschedule_cpu1() here, but that
+ * requires rump_intr_enter/exit to be implemented.
+ */
rump_unschedule_cpu(curlwp);
}
Index: src/sys/rump/librump/rumpkern/rump.c
diff -u src/sys/rump/librump/rumpkern/rump.c:1.142 src/sys/rump/librump/rumpkern/rump.c:1.143
--- src/sys/rump/librump/rumpkern/rump.c:1.142 Fri Nov 27 17:55:04 2009
+++ src/sys/rump/librump/rumpkern/rump.c Tue Dec 1 09:50:51 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: rump.c,v 1.142 2009/11/27 17:55:04 pooka Exp $ */
+/* $NetBSD: rump.c,v 1.143 2009/12/01 09:50:51 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.142 2009/11/27 17:55:04 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.143 2009/12/01 09:50:51 pooka Exp $");
#include <sys/param.h>
#include <sys/atomic.h>
@@ -60,6 +60,7 @@
#include <sys/tty.h>
#include <sys/uidinfo.h>
#include <sys/vmem.h>
+#include <sys/xcall.h>
#include <rump/rumpuser.h>
@@ -180,6 +181,7 @@
char buf[256];
struct proc *p;
struct lwp *l;
+ int i;
int error;
/* not reentrant */
@@ -209,6 +211,7 @@
}
rumpuser_thrinit(rump_user_schedule, rump_user_unschedule,
rump_threads);
+ rump_intr_init();
/* init minimal lwp/cpu context */
l = &lwp0;
@@ -233,6 +236,7 @@
uvm_ra_init();
mutex_obj_init();
+ callout_startup();
kprintf_init();
loginit();
@@ -266,9 +270,16 @@
rumpuser_set_curlwp(NULL);
rump_schedule();
- callout_startup();
- callout_init_cpu(rump_cpu);
- selsysinit(rump_cpu);
+ /* we are mostly go. do per-cpu subsystem init */
+ for (i = 0; i < ncpu; i++) {
+ struct cpu_info *ci = cpu_lookup(i);
+
+ callout_init_cpu(ci);
+ softint_init(ci);
+ xc_init_cpu(ci);
+ pool_cache_cpu_init(ci);
+ selsysinit(ci);
+ }
sysctl_init();
kqueue_init();
@@ -277,7 +288,6 @@
percpu_init();
fd_sys_init();
module_init();
- softint_init(rump_cpu);
devsw_init();
pipe_init();
Index: src/sys/rump/librump/rumpkern/rump_private.h
diff -u src/sys/rump/librump/rumpkern/rump_private.h:1.36 src/sys/rump/librump/rumpkern/rump_private.h:1.37
--- src/sys/rump/librump/rumpkern/rump_private.h:1.36 Thu Nov 26 20:58:51 2009
+++ src/sys/rump/librump/rumpkern/rump_private.h Tue Dec 1 09:50:51 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: rump_private.h,v 1.36 2009/11/26 20:58:51 pooka Exp $ */
+/* $NetBSD: rump_private.h,v 1.37 2009/12/01 09:50:51 pooka Exp $ */
/*
* Copyright (c) 2007 Antti Kantee. All Rights Reserved.
@@ -92,6 +92,7 @@
void rump_unschedule(void);
void rump_schedule_cpu(struct lwp *);
void rump_unschedule_cpu(struct lwp *);
+void rump_unschedule_cpu1(struct lwp *);
void rump_user_schedule(int);
void rump_user_unschedule(int, int *);
@@ -102,6 +103,7 @@
void kernel_unlock_allbutone(int *);
void kernel_ununlock_allbutone(int);
+void rump_intr_init(void);
void rump_softint_run(struct cpu_info *);
#endif /* _SYS_RUMP_PRIVATE_H_ */
Index: src/sys/rump/librump/rumpkern/scheduler.c
diff -u src/sys/rump/librump/rumpkern/scheduler.c:1.7 src/sys/rump/librump/rumpkern/scheduler.c:1.8
--- src/sys/rump/librump/rumpkern/scheduler.c:1.7 Mon Nov 9 19:16:18 2009
+++ src/sys/rump/librump/rumpkern/scheduler.c Tue Dec 1 09:50:51 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: scheduler.c,v 1.7 2009/11/09 19:16:18 pooka Exp $ */
+/* $NetBSD: scheduler.c,v 1.8 2009/12/01 09:50:51 pooka Exp $ */
/*
* Copyright (c) 2009 Antti Kantee. All Rights Reserved.
@@ -29,12 +29,13 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: scheduler.c,v 1.7 2009/11/09 19:16:18 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: scheduler.c,v 1.8 2009/12/01 09:50:51 pooka Exp $");
#include <sys/param.h>
#include <sys/cpu.h>
#include <sys/kmem.h>
#include <sys/mutex.h>
+#include <sys/namei.h>
#include <sys/queue.h>
#include <sys/select.h>
@@ -43,15 +44,21 @@
#include "rump_private.h"
/* should go for MAXCPUS at some point */
-static struct cpu_info rump_cpus[1];
+static struct cpu_info rump_cpus[MAXCPUS];
static struct rumpcpu {
struct cpu_info *rcpu_ci;
- SLIST_ENTRY(rumpcpu) rcpu_entries;
-} rcpu_storage[1];
+ int rcpu_flags;
+ struct rumpuser_cv *rcpu_cv;
+ LIST_ENTRY(rumpcpu) rcpu_entries;
+} rcpu_storage[MAXCPUS];
struct cpu_info *rump_cpu = &rump_cpus[0];
int ncpu = 1;
-static SLIST_HEAD(,rumpcpu) cpu_freelist = SLIST_HEAD_INITIALIZER(cpu_freelist);
+#define RCPU_WANTED 0x01 /* someone wants this specific CPU */
+#define RCPU_BUSY 0x02 /* CPU is busy */
+#define RCPU_FREELIST 0x04 /* CPU is on freelist */
+
+static LIST_HEAD(,rumpcpu) cpu_freelist = LIST_HEAD_INITIALIZER(cpu_freelist);
static struct rumpuser_mtx *schedmtx;
static struct rumpuser_cv *schedcv, *lwp0cv;
@@ -81,7 +88,9 @@
ci->ci_schedstate.spc_mutex =
mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
rcpu->rcpu_ci = ci;
- SLIST_INSERT_HEAD(&cpu_freelist, rcpu, rcpu_entries);
+ LIST_INSERT_HEAD(&cpu_freelist, rcpu, rcpu_entries);
+ rcpu->rcpu_flags = RCPU_FREELIST;
+ rumpuser_cv_init(&rcpu->rcpu_cv);
}
}
@@ -129,12 +138,36 @@
struct rumpcpu *rcpu;
rumpuser_mutex_enter_nowrap(schedmtx);
- while ((rcpu = SLIST_FIRST(&cpu_freelist)) == NULL)
- rumpuser_cv_wait_nowrap(schedcv, schedmtx);
- SLIST_REMOVE_HEAD(&cpu_freelist, rcpu_entries);
+ if (l->l_pflag & LP_BOUND) {
+ KASSERT(l->l_cpu != NULL);
+ rcpu = &rcpu_storage[l->l_cpu-&rump_cpus[0]];
+ if (rcpu->rcpu_flags & RCPU_BUSY) {
+ KASSERT((rcpu->rcpu_flags & RCPU_FREELIST) == 0);
+ while (rcpu->rcpu_flags & RCPU_BUSY) {
+ rcpu->rcpu_flags |= RCPU_WANTED;
+ rumpuser_cv_wait_nowrap(rcpu->rcpu_cv,
+ schedmtx);
+ }
+ rcpu->rcpu_flags &= ~RCPU_WANTED;
+ } else {
+ KASSERT(rcpu->rcpu_flags & (RCPU_FREELIST|RCPU_WANTED));
+ }
+ if (rcpu->rcpu_flags & RCPU_FREELIST) {
+ LIST_REMOVE(rcpu, rcpu_entries);
+ rcpu->rcpu_flags &= ~RCPU_FREELIST;
+ }
+ } else {
+ while ((rcpu = LIST_FIRST(&cpu_freelist)) == NULL) {
+ rumpuser_cv_wait_nowrap(schedcv, schedmtx);
+ }
+ KASSERT(rcpu->rcpu_flags & RCPU_FREELIST);
+ LIST_REMOVE(rcpu, rcpu_entries);
+ rcpu->rcpu_flags &= ~RCPU_FREELIST;
+ KASSERT(l->l_cpu == NULL);
+ l->l_cpu = rcpu->rcpu_ci;
+ }
+ rcpu->rcpu_flags |= RCPU_BUSY;
rumpuser_mutex_exit(schedmtx);
- KASSERT(l->l_cpu == NULL);
- l->l_cpu = rcpu->rcpu_ci;
l->l_mutex = rcpu->rcpu_ci->ci_schedstate.spc_mutex;
}
@@ -178,20 +211,41 @@
void
rump_unschedule_cpu(struct lwp *l)
{
+
+ if ((l->l_pflag & LP_INTR) == 0)
+ rump_softint_run(l->l_cpu);
+ rump_unschedule_cpu1(l);
+}
+
+void
+rump_unschedule_cpu1(struct lwp *l)
+{
struct rumpcpu *rcpu;
struct cpu_info *ci;
ci = l->l_cpu;
- if ((l->l_pflag & LP_INTR) == 0)
- rump_softint_run(ci);
-
- l->l_cpu = NULL;
+ if ((l->l_pflag & LP_BOUND) == 0) {
+ l->l_cpu = NULL;
+ }
rcpu = &rcpu_storage[ci-&rump_cpus[0]];
KASSERT(rcpu->rcpu_ci == ci);
+ KASSERT(rcpu->rcpu_flags & RCPU_BUSY);
rumpuser_mutex_enter_nowrap(schedmtx);
- SLIST_INSERT_HEAD(&cpu_freelist, rcpu, rcpu_entries);
- rumpuser_cv_signal(schedcv);
+ if (rcpu->rcpu_flags & RCPU_WANTED) {
+ /*
+ * The assumption is that there will usually be max 1
+ * thread waiting on the rcpu_cv, so broadcast is fine.
+ * (and the current structure requires it because of
+ * only a bitmask being used for wanting).
+ */
+ rumpuser_cv_broadcast(rcpu->rcpu_cv);
+ } else {
+ LIST_INSERT_HEAD(&cpu_freelist, rcpu, rcpu_entries);
+ rcpu->rcpu_flags |= RCPU_FREELIST;
+ rumpuser_cv_signal(schedcv);
+ }
+ rcpu->rcpu_flags &= ~RCPU_BUSY;
rumpuser_mutex_exit(schedmtx);
}
Index: src/sys/rump/librump/rumpkern/threads.c
diff -u src/sys/rump/librump/rumpkern/threads.c:1.3 src/sys/rump/librump/rumpkern/threads.c:1.4
--- src/sys/rump/librump/rumpkern/threads.c:1.3 Mon Nov 9 19:02:49 2009
+++ src/sys/rump/librump/rumpkern/threads.c Tue Dec 1 09:50:51 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: threads.c,v 1.3 2009/11/09 19:02:49 pooka Exp $ */
+/* $NetBSD: threads.c,v 1.4 2009/12/01 09:50:51 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.3 2009/11/09 19:02:49 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: threads.c,v 1.4 2009/12/01 09:50:51 pooka Exp $");
#include <sys/param.h>
#include <sys/kmem.h>
@@ -122,10 +122,7 @@
} else
panic("threads not available, setenv RUMP_THREADS 1");
}
-
KASSERT(fmt != NULL);
- if (ci != NULL)
- panic("%s: bounded threads not supported", __func__);
k = rumpuser_malloc(sizeof(struct kthdesc), 0);
k->f = func;
@@ -135,6 +132,10 @@
l->l_pflag |= LP_MPSAFE;
if (flags & KTHREAD_INTR)
l->l_pflag |= LP_INTR;
+ if (ci) {
+ l->l_pflag |= LP_BOUND;
+ l->l_cpu = ci;
+ }
rv = rumpuser_thread_create(threadbouncer, k, thrname);
if (rv)
return rv;