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;

Reply via email to