Module Name:    src
Committed By:   pooka
Date:           Thu Oct 15 00:28:47 UTC 2009

Modified Files:
        src/sys/rump/librump/rumpkern: Makefile.rumpkern emul.c locks.c
            ltsleep.c misc_stub.c percpu.c rump.c rump_private.h
        src/sys/rump/librump/rumpkern/arch/i386: rumpcpu.c
        src/sys/rump/librump/rumpuser: rumpuser_int.h rumpuser_pth.c
Added Files:
        src/sys/rump/librump/rumpkern: scheduler.c

Log Message:
Add initial work on a rump virtual cpu scheduler.  This is necessary
for kernel code which has been written to avoid MP contention by
using cpu-local storage (most prominently, select and pool_cache).

Instead of always assuming rump_cpu, the scheduler must now be run
(and unrun) on all entry points into rump.  Likewise, rumpuser
unruns and re-runs the scheduler around each potentially blocking
operation.  As an optimization, I modified some locking primitives
to try to get the lock without blocking before releasing the cpu.

Also, ltsleep was modified to assume that it is never called without
the biglock held and made to use the biglock as the sleep interlock.
Otherwise there is just too much drama with deadlocks.  If some
kernel code wants to call ltsleep without the biglock, then, *snif*,
it's no longer supported and rump and should be modified to support
newstyle locks anyway.


To generate a diff of this commit:
cvs rdiff -u -r1.51 -r1.52 src/sys/rump/librump/rumpkern/Makefile.rumpkern
cvs rdiff -u -r1.100 -r1.101 src/sys/rump/librump/rumpkern/emul.c
cvs rdiff -u -r1.28 -r1.29 src/sys/rump/librump/rumpkern/locks.c
cvs rdiff -u -r1.18 -r1.19 src/sys/rump/librump/rumpkern/ltsleep.c
cvs rdiff -u -r1.23 -r1.24 src/sys/rump/librump/rumpkern/misc_stub.c
cvs rdiff -u -r1.5 -r1.6 src/sys/rump/librump/rumpkern/percpu.c
cvs rdiff -u -r1.123 -r1.124 src/sys/rump/librump/rumpkern/rump.c
cvs rdiff -u -r1.30 -r1.31 src/sys/rump/librump/rumpkern/rump_private.h
cvs rdiff -u -r0 -r1.1 src/sys/rump/librump/rumpkern/scheduler.c
cvs rdiff -u -r1.5 -r1.6 src/sys/rump/librump/rumpkern/arch/i386/rumpcpu.c
cvs rdiff -u -r1.3 -r1.4 src/sys/rump/librump/rumpuser/rumpuser_int.h
cvs rdiff -u -r1.35 -r1.36 src/sys/rump/librump/rumpuser/rumpuser_pth.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/Makefile.rumpkern
diff -u src/sys/rump/librump/rumpkern/Makefile.rumpkern:1.51 src/sys/rump/librump/rumpkern/Makefile.rumpkern:1.52
--- src/sys/rump/librump/rumpkern/Makefile.rumpkern:1.51	Wed Oct 14 17:29:19 2009
+++ src/sys/rump/librump/rumpkern/Makefile.rumpkern	Thu Oct 15 00:28:46 2009
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile.rumpkern,v 1.51 2009/10/14 17:29:19 pooka Exp $
+#	$NetBSD: Makefile.rumpkern,v 1.52 2009/10/15 00:28:46 pooka Exp $
 #
 
 .include "${RUMPTOP}/Makefile.rump"
@@ -15,7 +15,7 @@
 # Source modules, first the ones specifically implemented for librump.
 # 
 SRCS=	rump.c emul.c intr.c locks.c ltsleep.c percpu.c pool.c	\
-	sleepq.c sysproxy_socket.c vm.c
+	scheduler.c sleepq.c sysproxy_socket.c vm.c
 
 SRCS+=	rumpkern_if_wrappers.c
 
@@ -71,8 +71,9 @@
 #
 # If archdir exists, it is required to provide:
 # 1) kobj_reloc() and kobj_machdep()
-# 2) ...?
-# 3) PROFIT!
+# 2) rump_cpu_bootstrap()
+# 3) ...?
+# 4) PROFIT!
 #
 
 #
@@ -90,7 +91,7 @@
 .include "${ARCHDIR}/Makefile.inc"
 .PATH:	${ARCHDIR}
 .else
-SRCS+=	kobj_stubs.c
+SRCS+=	kobj_stubs.c rumpcpu_generic.c
 .endif
 
 # include libkern source files

Index: src/sys/rump/librump/rumpkern/emul.c
diff -u src/sys/rump/librump/rumpkern/emul.c:1.100 src/sys/rump/librump/rumpkern/emul.c:1.101
--- src/sys/rump/librump/rumpkern/emul.c:1.100	Wed Oct 14 18:18:53 2009
+++ src/sys/rump/librump/rumpkern/emul.c	Thu Oct 15 00:28:46 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: emul.c,v 1.100 2009/10/14 18:18:53 pooka Exp $	*/
+/*	$NetBSD: emul.c,v 1.101 2009/10/15 00:28:46 pooka Exp $	*/
 
 /*
  * Copyright (c) 2007 Antti Kantee.  All Rights Reserved.
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: emul.c,v 1.100 2009/10/14 18:18:53 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: emul.c,v 1.101 2009/10/15 00:28:46 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/malloc.h>
@@ -73,7 +73,6 @@
 dev_t rootdev;
 int physmem = 256*256; /* 256 * 1024*1024 / 4k, PAGE_SIZE not always set */
 int doing_shutdown;
-int ncpu = 1;
 const int schedppq = 1;
 int hardclock_ticks;
 bool mp_online = false;
@@ -370,14 +369,18 @@
 	void (*f)(void *);
 	void *thrarg;
 
+	/* schedule ourselves first */
 	f = k->f;
 	thrarg = k->arg;
 	rumpuser_set_curlwp(k->mylwp);
-	kmem_free(k, sizeof(struct kthdesc));
+	rump_schedule();
 
+	kmem_free(k, sizeof(struct kthdesc));
 	if ((curlwp->l_pflag & LP_MPSAFE) == 0)
 		KERNEL_LOCK(1, NULL);
+
 	f(thrarg);
+
 	panic("unreachable, should kthread_exit()");
 }
 
@@ -458,6 +461,7 @@
 	if ((curlwp->l_pflag & LP_MPSAFE) == 0)
 		KERNEL_UNLOCK_ONE(NULL);
 	rump_clear_curlwp();
+	rump_unschedule();
 	rumpuser_thread_exit();
 }
 

Index: src/sys/rump/librump/rumpkern/locks.c
diff -u src/sys/rump/librump/rumpkern/locks.c:1.28 src/sys/rump/librump/rumpkern/locks.c:1.29
--- src/sys/rump/librump/rumpkern/locks.c:1.28	Fri Oct  2 09:56:08 2009
+++ src/sys/rump/librump/rumpkern/locks.c	Thu Oct 15 00:28:46 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: locks.c,v 1.28 2009/10/02 09:56:08 pooka Exp $	*/
+/*	$NetBSD: locks.c,v 1.29 2009/10/15 00:28:46 pooka Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -55,7 +55,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: locks.c,v 1.28 2009/10/02 09:56:08 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: locks.c,v 1.29 2009/10/15 00:28:46 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -300,12 +300,53 @@
  */
 
 static volatile int lockcnt;
+
+bool
+kernel_biglocked()
+{
+
+	return rumpuser_mutex_held(rump_giantlock) && lockcnt > 0;
+}
+
+void
+kernel_unlock_allbutone(int *countp)
+{
+	int minusone = lockcnt-1;
+
+	KASSERT(kernel_biglocked());
+	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;
+}
+
+void
+kernel_ununlock_allbutone(int nlocks)
+{
+
+	KASSERT(rumpuser_mutex_held(rump_giantlock) && lockcnt == 0);
+	lockcnt = 1;
+	_kernel_lock(nlocks);
+}
+
 void
 _kernel_lock(int nlocks)
 {
 
 	while (nlocks--) {
-		rumpuser_mutex_enter(rump_giantlock);
+		if (!rumpuser_mutex_tryenter(rump_giantlock)) {
+			rump_unschedule();
+			rumpuser_mutex_enter_nowrap(rump_giantlock);
+			rump_schedule();
+		}
 		lockcnt++;
 	}
 }
@@ -336,6 +377,24 @@
 	}
 }
 
+void
+rump_user_unschedule(int nlocks, int *countp)
+{
+
+	_kernel_unlock(nlocks, countp);
+	rump_unschedule();
+}
+
+void
+rump_user_schedule(int nlocks)
+{
+
+	rump_schedule();
+
+	if (nlocks)
+		_kernel_lock(nlocks);
+}
+
 struct kmutexobj {
 	kmutex_t	mo_lock;
 	u_int		mo_refcnt;

Index: src/sys/rump/librump/rumpkern/ltsleep.c
diff -u src/sys/rump/librump/rumpkern/ltsleep.c:1.18 src/sys/rump/librump/rumpkern/ltsleep.c:1.19
--- src/sys/rump/librump/rumpkern/ltsleep.c:1.18	Sun Oct  4 17:40:34 2009
+++ src/sys/rump/librump/rumpkern/ltsleep.c	Thu Oct 15 00:28:46 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: ltsleep.c,v 1.18 2009/10/04 17:40:34 pooka Exp $	*/
+/*	$NetBSD: ltsleep.c,v 1.19 2009/10/15 00:28:46 pooka Exp $	*/
 
 /*
  * Copyright (c) 2007 Antti Kantee.  All Rights Reserved.
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ltsleep.c,v 1.18 2009/10/04 17:40:34 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ltsleep.c,v 1.19 2009/10/15 00:28:46 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/proc.h>
@@ -42,12 +42,11 @@
 
 struct ltsleeper {
 	wchan_t id;
-	kcondvar_t cv;
+	struct rumpuser_cv *cv;
 	LIST_ENTRY(ltsleeper) entries;
 };
 
 static LIST_HEAD(, ltsleeper) sleepers = LIST_HEAD_INITIALIZER(sleepers);
-static kmutex_t sleepermtx;
 
 kcondvar_t lbolt; /* Oh Kath Ra */
 
@@ -59,24 +58,19 @@
 	int nlocks;
 
 	lts.id = ident;
-	cv_init(&lts.cv, NULL);
+	rumpuser_cv_init(&lts.cv);
 
-	while (!mutex_tryenter(&sleepermtx))
-		continue;
-	KERNEL_UNLOCK_ALL(curlwp, &nlocks);
 	if (slock)
 		simple_unlock(slock);
 	LIST_INSERT_HEAD(&sleepers, &lts, entries);
+	kernel_unlock_allbutone(&nlocks);
 
-	/* protected by sleepermtx */
-	cv_wait(&lts.cv, &sleepermtx);
+	/* protected by biglock */
+	rumpuser_cv_wait(lts.cv, rump_giantlock);
 
 	LIST_REMOVE(&lts, entries);
-	mutex_exit(&sleepermtx);
-
-	cv_destroy(&lts.cv);
-
-	KERNEL_LOCK(nlocks, curlwp);
+	rumpuser_cv_destroy(lts.cv);
+	kernel_ununlock_allbutone(nlocks);
 
 	if (slock && (prio & PNORELOCK) == 0)
 		simple_lock(slock);
@@ -92,23 +86,18 @@
 	int nlocks;
 
 	lts.id = ident;
-	cv_init(&lts.cv, NULL);
+	rumpuser_cv_init(&lts.cv);
 
-	while (!mutex_tryenter(&sleepermtx))
-		continue;
-	KERNEL_UNLOCK_ALL(curlwp, &nlocks);
+	mutex_exit(lock);
 	LIST_INSERT_HEAD(&sleepers, &lts, entries);
+	kernel_unlock_allbutone(&nlocks);
 
-	/* protected by sleepermtx */
-	mutex_exit(lock);
-	cv_wait(&lts.cv, &sleepermtx);
+	/* protected by biglock */
+	rumpuser_cv_wait(lts.cv, rump_giantlock);
 
 	LIST_REMOVE(&lts, entries);
-	mutex_exit(&sleepermtx);
-
-	cv_destroy(&lts.cv);
-
-	KERNEL_LOCK(nlocks, curlwp);
+	rumpuser_cv_destroy(lts.cv);
+	kernel_ununlock_allbutone(nlocks);
 
 	if ((prio & PNORELOCK) == 0)
 		mutex_enter(lock);
@@ -117,41 +106,34 @@
 }
 
 static void
-do_wakeup(wchan_t ident, void (*wakeupfn)(kcondvar_t *))
+do_wakeup(wchan_t ident, void (*wakeupfn)(struct rumpuser_cv *))
 {
 	struct ltsleeper *ltsp;
-	int nlocks;
 
-	while (!mutex_tryenter(&sleepermtx)) {
-		KERNEL_UNLOCK_ALL(curlwp, &nlocks);
-		yield();
-		KERNEL_LOCK(nlocks, curlwp);
-	}
+	KASSERT(kernel_biglocked());
 	LIST_FOREACH(ltsp, &sleepers, entries) {
 		if (ltsp->id == ident) {
-			wakeupfn(&ltsp->cv);
+			wakeupfn(ltsp->cv);
 		}
 	}
-	mutex_exit(&sleepermtx);
 }
 
 void
 wakeup(wchan_t ident)
 {
 
-	do_wakeup(ident, cv_broadcast);
+	do_wakeup(ident, rumpuser_cv_broadcast);
 }
 
 void
 wakeup_one(wchan_t ident)
 {
 
-	do_wakeup(ident, cv_signal);
+	do_wakeup(ident, rumpuser_cv_signal);
 }
 
 void
 rump_sleepers_init(void)
 {
 
-	mutex_init(&sleepermtx, MUTEX_DEFAULT, 0);
 }

Index: src/sys/rump/librump/rumpkern/misc_stub.c
diff -u src/sys/rump/librump/rumpkern/misc_stub.c:1.23 src/sys/rump/librump/rumpkern/misc_stub.c:1.24
--- src/sys/rump/librump/rumpkern/misc_stub.c:1.23	Fri Oct  2 18:50:15 2009
+++ src/sys/rump/librump/rumpkern/misc_stub.c	Thu Oct 15 00:28:46 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: misc_stub.c,v 1.23 2009/10/02 18:50:15 elad Exp $	*/
+/*	$NetBSD: misc_stub.c,v 1.24 2009/10/15 00:28:46 pooka Exp $	*/
 
 /*
  * Copyright (c) 2007 Antti Kantee.  All Rights Reserved.
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: misc_stub.c,v 1.23 2009/10/02 18:50:15 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: misc_stub.c,v 1.24 2009/10/15 00:28:46 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/cpu.h>
@@ -68,14 +68,6 @@
 	return;
 }
 
-struct cpu_info *
-cpu_lookup(u_int index)
-{
-	extern struct cpu_info rump_cpu;
-
-	return &rump_cpu;
-}
-
 int
 syscall_establish(const struct emul *em, const struct syscall_package *sp)
 {

Index: src/sys/rump/librump/rumpkern/percpu.c
diff -u src/sys/rump/librump/rumpkern/percpu.c:1.5 src/sys/rump/librump/rumpkern/percpu.c:1.6
--- src/sys/rump/librump/rumpkern/percpu.c:1.5	Wed Mar 18 10:22:44 2009
+++ src/sys/rump/librump/rumpkern/percpu.c	Thu Oct 15 00:28:46 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: percpu.c,v 1.5 2009/03/18 10:22:44 cegger Exp $	*/
+/*	$NetBSD: percpu.c,v 1.6 2009/10/15 00:28:46 pooka Exp $	*/
 
 /*
  * Copyright (c) 2008 Antti Kantee.  All Rights Reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: percpu.c,v 1.5 2009/03/18 10:22:44 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: percpu.c,v 1.6 2009/10/15 00:28:46 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/kmem.h>
@@ -83,5 +83,5 @@
 percpu_foreach(percpu_t *pc, percpu_callback_t cb, void *arg)
 {
 
-	cb(pc, arg, &rump_cpu);
+	cb(pc, arg, rump_cpu);
 }

Index: src/sys/rump/librump/rumpkern/rump.c
diff -u src/sys/rump/librump/rumpkern/rump.c:1.123 src/sys/rump/librump/rumpkern/rump.c:1.124
--- src/sys/rump/librump/rumpkern/rump.c:1.123	Wed Oct 14 18:18:53 2009
+++ src/sys/rump/librump/rumpkern/rump.c	Thu Oct 15 00:28:46 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: rump.c,v 1.123 2009/10/14 18:18:53 pooka Exp $	*/
+/*	$NetBSD: rump.c,v 1.124 2009/10/15 00:28:46 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.123 2009/10/14 18:18:53 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.124 2009/10/15 00:28:46 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -85,7 +85,6 @@
 };
 struct pstats rump_stats;
 struct plimit rump_limits;
-struct cpu_info rump_cpu;
 struct filedesc rump_filedesc0;
 struct proclist allproc;
 char machine[] = "rump";
@@ -206,7 +205,8 @@
 	if (rumpuser_getenv("RUMP_THREADS", buf, sizeof(buf), &error) == 0) {
 		rump_threads = *buf != '0';
 	}
-	rumpuser_thrinit(_kernel_lock, _kernel_unlock, rump_threads);
+	rumpuser_thrinit(rump_user_schedule, rump_user_unschedule,
+	    rump_threads);
 
 	mutex_init(&tty_lock, MUTEX_DEFAULT, IPL_NONE);
 	rumpuser_mutex_recursive_init(&rump_giantlock);
@@ -241,7 +241,6 @@
 	l->l_cred = rump_cred_suserget();
 	l->l_proc = p;
 	l->l_lid = 1;
-	l->l_cpu = &rump_cpu;
 	LIST_INIT(&allproc);
 	LIST_INSERT_HEAD(&allproc, &proc0, p_list);
 	proc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
@@ -250,8 +249,11 @@
 	rump_limits.pl_rlimit[RLIMIT_NOFILE].rlim_cur = RLIM_INFINITY;
 	rump_limits.pl_rlimit[RLIMIT_SBSIZE].rlim_cur = RLIM_INFINITY;
 
+	rump_scheduler_init();
+	rump_schedule();
+
 	callout_startup();
-	callout_init_cpu(&rump_cpu);
+	callout_init_cpu(rump_cpu);
 
 	sysctl_init();
 	kqueue_init();
@@ -260,7 +262,7 @@
 	percpu_init();
 	fd_sys_init();
 	module_init();
-	softint_init(&rump_cpu);
+	softint_init(rump_cpu);
 	devsw_init();
 
 	/* these do nothing if not present */
@@ -290,6 +292,11 @@
 		vmem_rehash_start();
 #endif
 
+	/*
+	 * Module bootstrap makes calls back into rump, so
+	 * unschedule before calling.
+	 */
+	rump_unschedule();
 	rumpuser_dl_module_bootstrap();
 
 	return 0;
@@ -425,10 +432,16 @@
 	l->l_lid = lid;
 	l->l_fd = p->p_fd;
 	l->l_mutex = RUMP_LMUTEX_MAGIC;
-	l->l_cpu = &rump_cpu;
+	l->l_cpu = NULL;
 
-	if (set)
+	/* give current cpu to new lwp */
+	if (set) {
+		struct cpu_info *saveci = curlwp->l_cpu;
+
+		curlwp->l_cpu = NULL;
 		rumpuser_set_curlwp(l);
+		curlwp->l_cpu = saveci;
+	}
 
 	return l;
 }
@@ -445,10 +458,13 @@
 void
 rump_clear_curlwp(void)
 {
+	struct cpu_info *ci;
 	struct lwp *l;
 	struct proc *p;
 
 	l = rumpuser_get_curlwp();
+	ci = l->l_cpu;
+	KASSERT(ci);
 	p = l->l_proc;
 	if (p->p_pid != 0) {
 		mutex_obj_free(p->p_lock);
@@ -458,7 +474,10 @@
 		kmem_free(p, sizeof(*p));
 	}
 	kmem_free(l, sizeof(*l));
+
+	/* lwp0 inherits current cpu.  quite XXX */
 	rumpuser_set_curlwp(NULL);
+	lwp0.l_cpu = ci; 
 }
 
 struct lwp *
@@ -574,13 +593,18 @@
 {
 	struct lwp *l;
 	struct sysent *callp;
+	int rv;
 
 	if (__predict_false(num >= SYS_NSYSENT))
 		return ENOSYS;
 
 	l = curlwp;
 	callp = rump_sysent + num;
-	return callp->sy_call(l, (void *)data, retval);
+	rump_schedule();
+	rv = callp->sy_call(l, (void *)data, retval);
+	rump_unschedule();
+
+	return rv;
 }
 
 rump_sysproxy_t rump_sysproxy = rump_sysproxy_local;
@@ -606,7 +630,7 @@
 }
 
 int
-rump_getversion()
+rump_getversion(void)
 {
 
 	return __NetBSD_Version__;

Index: src/sys/rump/librump/rumpkern/rump_private.h
diff -u src/sys/rump/librump/rumpkern/rump_private.h:1.30 src/sys/rump/librump/rumpkern/rump_private.h:1.31
--- src/sys/rump/librump/rumpkern/rump_private.h:1.30	Wed Oct 14 17:30:52 2009
+++ src/sys/rump/librump/rumpkern/rump_private.h	Thu Oct 15 00:28:46 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: rump_private.h,v 1.30 2009/10/14 17:30:52 pooka Exp $	*/
+/*	$NetBSD: rump_private.h,v 1.31 2009/10/15 00:28:46 pooka Exp $	*/
 
 /*
  * Copyright (c) 2007 Antti Kantee.  All Rights Reserved.
@@ -77,7 +77,7 @@
 rump_proc_vfs_init_fn rump_proc_vfs_init;
 rump_proc_vfs_release_fn rump_proc_vfs_release;
 
-extern struct cpu_info rump_cpu;
+extern struct cpu_info *rump_cpu;
 
 extern rump_sysproxy_t rump_sysproxy;
 extern void *rump_sysproxy_arg;
@@ -85,4 +85,16 @@
 int		rump_sysproxy_copyout(const void *, void *, size_t);
 int		rump_sysproxy_copyin(const void *, void *, size_t);
 
+void	rump_scheduler_init(void);
+void	rump_schedule(void);
+void	rump_unschedule(void);
+void	rump_user_schedule(int);
+void	rump_user_unschedule(int, int *);
+
+void	rump_cpu_bootstrap(struct cpu_info *);
+
+bool	kernel_biglocked(void);
+void	kernel_unlock_allbutone(int *);
+void	kernel_ununlock_allbutone(int);
+
 #endif /* _SYS_RUMP_PRIVATE_H_ */

Index: src/sys/rump/librump/rumpkern/arch/i386/rumpcpu.c
diff -u src/sys/rump/librump/rumpkern/arch/i386/rumpcpu.c:1.5 src/sys/rump/librump/rumpkern/arch/i386/rumpcpu.c:1.6
--- src/sys/rump/librump/rumpkern/arch/i386/rumpcpu.c:1.5	Wed Oct 14 18:18:53 2009
+++ src/sys/rump/librump/rumpkern/arch/i386/rumpcpu.c	Thu Oct 15 00:28:47 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: rumpcpu.c,v 1.5 2009/10/14 18:18:53 pooka Exp $	*/
+/*	$NetBSD: rumpcpu.c,v 1.6 2009/10/15 00:28:47 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.5 2009/10/14 18:18:53 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rumpcpu.c,v 1.6 2009/10/15 00:28:47 pooka Exp $");
 
 #include <sys/param.h>
 
@@ -37,13 +37,20 @@
 
 #include "rump_private.h"
 
-struct cpu_info *cpu_info_list = &rump_cpu;
+struct cpu_info *cpu_info_list;
+
+void
+rump_cpu_bootstrap(struct cpu_info *ci)
+{
+
+	cpu_info_list = ci;
+}
 
 struct cpu_info *
 x86_curcpu()
 {
 
-	return &rump_cpu;
+	return curlwp->l_cpu;
 }
 
 struct lwp *

Index: src/sys/rump/librump/rumpuser/rumpuser_int.h
diff -u src/sys/rump/librump/rumpuser/rumpuser_int.h:1.3 src/sys/rump/librump/rumpuser/rumpuser_int.h:1.4
--- src/sys/rump/librump/rumpuser/rumpuser_int.h:1.3	Wed Jan  7 22:50:08 2009
+++ src/sys/rump/librump/rumpuser/rumpuser_int.h	Thu Oct 15 00:28:47 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: rumpuser_int.h,v 1.3 2009/01/07 22:50:08 pooka Exp $	*/
+/*	$NetBSD: rumpuser_int.h,v 1.4 2009/10/15 00:28:47 pooka Exp $	*/
 
 /*
  * Copyright (c) 2008 Antti Kantee.  All Rights Reserved.
@@ -36,8 +36,7 @@
 	int nlocks;							\
 	rumpuser__kunlock(0, &nlocks);					\
 	a;								\
-	if (nlocks)							\
-		rumpuser__klock(nlocks);				\
+	rumpuser__klock(nlocks);					\
 } while (/*CONSTCOND*/0)
 
 #define DOCALL(rvtype, call)						\
@@ -54,8 +53,7 @@
 	int nlocks;							\
 	rumpuser__kunlock(0, &nlocks);					\
 	rv = call;							\
-	if (nlocks)							\
-		rumpuser__klock(nlocks);				\
+	rumpuser__klock(nlocks);					\
 	if (rv == -1)							\
 		*error = errno;						\
 	else								\

Index: src/sys/rump/librump/rumpuser/rumpuser_pth.c
diff -u src/sys/rump/librump/rumpuser/rumpuser_pth.c:1.35 src/sys/rump/librump/rumpuser/rumpuser_pth.c:1.36
--- src/sys/rump/librump/rumpuser/rumpuser_pth.c:1.35	Tue Sep  8 20:04:03 2009
+++ src/sys/rump/librump/rumpuser/rumpuser_pth.c	Thu Oct 15 00:28:47 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: rumpuser_pth.c,v 1.35 2009/09/08 20:04:03 pooka Exp $	*/
+/*	$NetBSD: rumpuser_pth.c,v 1.36 2009/10/15 00:28:47 pooka Exp $	*/
 
 /*
  * Copyright (c) 2007 Antti Kantee.  All Rights Reserved.
@@ -30,7 +30,7 @@
 
 #include <sys/cdefs.h>
 #if !defined(lint)
-__RCSID("$NetBSD: rumpuser_pth.c,v 1.35 2009/09/08 20:04:03 pooka Exp $");
+__RCSID("$NetBSD: rumpuser_pth.c,v 1.36 2009/10/15 00:28:47 pooka Exp $");
 #endif /* !lint */
 
 #ifdef __linux__
@@ -291,7 +291,16 @@
 rumpuser_mutex_enter(struct rumpuser_mtx *mtx)
 {
 
-	KLOCK_WRAP(NOFAIL_ERRNO(pthread_mutex_lock(&mtx->pthmtx)));
+	if (pthread_mutex_trylock(&mtx->pthmtx) != 0)
+		KLOCK_WRAP(NOFAIL_ERRNO(pthread_mutex_lock(&mtx->pthmtx)));
+	mtxenter(mtx);
+}
+
+void
+rumpuser_mutex_enter_nowrap(struct rumpuser_mtx *mtx)
+{
+
+	NOFAIL_ERRNO(pthread_mutex_lock(&mtx->pthmtx));
 	mtxenter(mtx);
 }
 
@@ -347,10 +356,14 @@
 {
 
 	if (iswrite) {
-		KLOCK_WRAP(NOFAIL_ERRNO(pthread_rwlock_wrlock(&rw->pthrw)));
+		if (pthread_rwlock_trywrlock(&rw->pthrw) != 0)
+			KLOCK_WRAP(NOFAIL_ERRNO(
+			    pthread_rwlock_wrlock(&rw->pthrw)));
 		RURW_SETWRITE(rw);
 	} else {
-		KLOCK_WRAP(NOFAIL_ERRNO(pthread_rwlock_rdlock(&rw->pthrw)));
+		if (pthread_rwlock_tryrdlock(&rw->pthrw) != 0)
+			KLOCK_WRAP(NOFAIL_ERRNO(
+			    pthread_rwlock_rdlock(&rw->pthrw)));
 		RURW_INCREAD(rw);
 	}
 }
@@ -443,6 +456,18 @@
 	cv->nwaiters--;
 }
 
+void
+rumpuser_cv_wait_nowrap(struct rumpuser_cv *cv, struct rumpuser_mtx *mtx)
+{
+
+	cv->nwaiters++;
+	assert(mtx->recursion == 1);
+	mtxexit(mtx);
+	NOFAIL_ERRNO(pthread_cond_wait(&cv->pthcv, &mtx->pthmtx));
+	mtxenter(mtx);
+	cv->nwaiters--;
+}
+
 int
 rumpuser_cv_timedwait(struct rumpuser_cv *cv, struct rumpuser_mtx *mtx,
 	struct timespec *ts)

Added files:

Index: src/sys/rump/librump/rumpkern/scheduler.c
diff -u /dev/null src/sys/rump/librump/rumpkern/scheduler.c:1.1
--- /dev/null	Thu Oct 15 00:28:47 2009
+++ src/sys/rump/librump/rumpkern/scheduler.c	Thu Oct 15 00:28:46 2009
@@ -0,0 +1,116 @@
+/*      $NetBSD: scheduler.c,v 1.1 2009/10/15 00:28:46 pooka Exp $	*/
+
+/*
+ * Copyright (c) 2009 Antti Kantee.  All Rights Reserved.
+ *
+ * Development of this software was supported by
+ * The Finnish Cultural Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: scheduler.c,v 1.1 2009/10/15 00:28:46 pooka Exp $");
+
+#include <sys/param.h>
+#include <sys/cpu.h>
+#include <sys/mutex.h>
+#include <sys/queue.h>
+#include <sys/select.h>
+
+#include <rump/rumpuser.h>
+
+#include "rump_private.h"
+
+/* should go for MAXCPUS at some point */
+static struct cpu_info rump_cpus[1];
+static struct rumpcpu {
+	struct cpu_info *rcpu_ci;
+	SLIST_ENTRY(rumpcpu) rcpu_entries;
+} rcpu_storage[1];
+struct cpu_info *rump_cpu = &rump_cpus[0];
+int ncpu = 1;
+
+static SLIST_HEAD(,rumpcpu) cpu_freelist = SLIST_HEAD_INITIALIZER(cpu_freelist);
+static struct rumpuser_mtx *schedmtx;
+static struct rumpuser_cv *schedcv;
+
+struct cpu_info *
+cpu_lookup(u_int index)
+{
+
+	return &rump_cpus[index];
+}
+
+void
+rump_scheduler_init()
+{
+	struct rumpcpu *rcpu;
+	struct cpu_info *ci;
+	int i;
+
+	rumpuser_mutex_init(&schedmtx);
+	rumpuser_cv_init(&schedcv);
+	for (i = 0; i < ncpu; i++) {
+		rcpu = &rcpu_storage[i];
+		ci = &rump_cpus[i];
+		rump_cpu_bootstrap(ci);
+		rcpu->rcpu_ci = ci;
+		SLIST_INSERT_HEAD(&cpu_freelist, rcpu, rcpu_entries);
+	}
+}
+
+void
+rump_schedule()
+{
+	struct rumpcpu *rcpu;
+	struct lwp *l = curlwp;
+
+	KASSERT(l->l_cpu == NULL);
+	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);
+	rumpuser_mutex_exit(schedmtx);
+
+	l->l_cpu = rcpu->rcpu_ci;
+}
+
+void
+rump_unschedule()
+{
+	struct rumpcpu *rcpu;
+	struct cpu_info *ci;
+	struct lwp *l;
+
+	l = curlwp;
+	ci = l->l_cpu;
+	l->l_cpu = NULL;
+
+	rcpu = &rcpu_storage[ci-&rump_cpus[0]];
+	KASSERT(rcpu->rcpu_ci == ci);
+
+	rumpuser_mutex_enter_nowrap(schedmtx);
+	SLIST_INSERT_HEAD(&cpu_freelist, rcpu, rcpu_entries);
+	rumpuser_cv_signal(schedcv);
+	rumpuser_mutex_exit(schedmtx);
+}

Reply via email to