Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/rump/librump/rumpkern Hash out soft interrupts to be a l...
details: https://anonhg.NetBSD.org/src/rev/2e55df76a211
branches: trunk
changeset: 748910:2e55df76a211
user: pooka <pooka%NetBSD.org@localhost>
date: Mon Nov 09 19:16:18 2009 +0000
description:
Hash out soft interrupts to be a little closer to real softints:
* split them into levels
* allow only one per level to be active at a time
* fire softints only when we are unscheduling from a CPU instead
of immediately in softint_schedule(). this will later morph
into return from interrupt, but that part isn't done yet.
diffstat:
sys/rump/librump/rumpkern/intr.c | 133 ++++++++++++++++--------------
sys/rump/librump/rumpkern/rump_private.h | 6 +-
sys/rump/librump/rumpkern/scheduler.c | 7 +-
3 files changed, 80 insertions(+), 66 deletions(-)
diffs (truncated from 304 to 300 lines):
diff -r 47bffe117a5e -r 2e55df76a211 sys/rump/librump/rumpkern/intr.c
--- a/sys/rump/librump/rumpkern/intr.c Mon Nov 09 19:02:49 2009 +0000
+++ b/sys/rump/librump/rumpkern/intr.c Mon Nov 09 19:16:18 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: intr.c,v 1.19 2009/11/06 15:22:16 pooka Exp $ */
+/* $NetBSD: intr.c,v 1.20 2009/11/09 19:16:18 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.19 2009/11/06 15:22:16 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.20 2009/11/09 19:16:18 pooka Exp $");
#include <sys/param.h>
#include <sys/cpu.h>
@@ -47,46 +47,21 @@
#define SI_MPSAFE 0x01
#define SI_ONLIST 0x02
#define SI_KILLME 0x04
+
struct softint {
void (*si_func)(void *);
void *si_arg;
int si_flags;
+ int si_level;
LIST_ENTRY(softint) si_entries;
};
-static LIST_HEAD(, softint) si_pending = LIST_HEAD_INITIALIZER(si_pending);
-static kmutex_t si_mtx;
-static kcondvar_t si_cv;
-#define INTRTHREAD_DEFAULT 2
-#define INTRTHREAD_MAX 20
-static int wrkidle, wrktotal;
-
-static void sithread(void *);
-
-static void
-makeworker(bool bootstrap)
-{
- int rv;
-
- if (wrktotal > INTRTHREAD_MAX) {
- /* XXX: ratecheck */
- printf("maximum interrupt threads (%d) reached\n",
- INTRTHREAD_MAX);
- return;
- }
- rv = kthread_create(PRI_NONE, KTHREAD_MPSAFE | KTHREAD_INTR, NULL,
- sithread, NULL, NULL, "rumpsi");
- if (rv) {
- if (bootstrap)
- panic("intr thread creation failed %d", rv);
- else
- printf("intr thread creation failed %d\n", rv);
- } else {
- wrkidle++;
- wrktotal++;
- }
-}
+static struct rumpuser_mtx *si_mtx;
+static 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;
@@ -160,7 +135,9 @@
}
/*
- * run a scheduled soft interrupt
+ * Soft interrupt execution thread. Note that we run without a CPU
+ * context until we start processing the interrupt. This is to avoid
+ * lock recursion.
*/
static void
sithread(void *arg)
@@ -169,62 +146,78 @@
void (*func)(void *) = NULL;
void *funarg;
bool mpsafe;
+ int mylevel = (uintptr_t)arg;
+ struct softint_lev *si_lvl;
- mutex_enter(&si_mtx);
+ rump_unschedule();
+
+ si_lvl = &softints[mylevel];
+ rumpuser_mutex_enter_nowrap(si_mtx);
for (;;) {
- if (!LIST_EMPTY(&si_pending)) {
- si = LIST_FIRST(&si_pending);
+ if (!LIST_EMPTY(&si_lvl->si_pending)) {
+ si = LIST_FIRST(&si_lvl->si_pending);
func = si->si_func;
funarg = si->si_arg;
mpsafe = si->si_flags & SI_MPSAFE;
si->si_flags &= ~SI_ONLIST;
LIST_REMOVE(si, si_entries);
- if (si->si_flags & SI_KILLME)
+ if (si->si_flags & SI_KILLME) {
+ rumpuser_mutex_exit(si_mtx);
+ rump_schedule();
softint_disestablish(si);
+ rump_unschedule();
+ rumpuser_mutex_enter_nowrap(si_mtx);
+ continue;
+ }
} else {
- cv_wait(&si_cv, &si_mtx);
+ rumpuser_cv_wait_nowrap(si_lvl->si_cv, si_mtx);
continue;
}
- wrkidle--;
- if (__predict_false(wrkidle == 0))
- makeworker(false);
- mutex_exit(&si_mtx);
+ rumpuser_mutex_exit(si_mtx);
+ rump_schedule();
if (!mpsafe)
KERNEL_LOCK(1, curlwp);
func(funarg);
if (!mpsafe)
KERNEL_UNLOCK_ONE(curlwp);
+ rump_unschedule();
- mutex_enter(&si_mtx);
- wrkidle++;
+ rumpuser_mutex_enter_nowrap(si_mtx);
}
+
+ panic("sithread unreachable");
}
void
softint_init(struct cpu_info *ci)
{
- int rv;
+ int rv, i;
- mutex_init(&si_mtx, MUTEX_DEFAULT, IPL_NONE);
- cv_init(&si_cv, "intrw8"); /* cv of temporary w8ness */
+ rumpuser_mutex_init(&si_mtx);
+ for (i = 0; i < SOFTINT_COUNT; i++) {
+ rumpuser_cv_init(&softints[i].si_cv);
+ LIST_INIT(&softints[i].si_pending);
+ }
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);
+ }
+
rumpuser_mutex_enter(clockmtx);
- rv = kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL, doclock,
- NULL, NULL, "rumpclk");
+ rv = kthread_create(PRI_NONE, KTHREAD_MPSAFE | KTHREAD_INTR,
+ NULL, doclock, NULL, NULL, "rumpclk");
if (rv)
panic("clock thread creation failed: %d", rv);
- mutex_enter(&si_mtx);
- while (wrktotal < INTRTHREAD_DEFAULT) {
- makeworker(true);
- }
- mutex_exit(&si_mtx);
/* make sure we have a clocktime before returning */
rumpuser_cv_wait(clockcv, clockmtx);
@@ -251,6 +244,8 @@
si->si_func = func;
si->si_arg = arg;
si->si_flags = flags & SOFTINT_MPSAFE ? SI_MPSAFE : 0;
+ si->si_level = flags & SOFTINT_LVLMASK;
+ KASSERT(si->si_level < SOFTINT_COUNT);
return si;
}
@@ -263,13 +258,13 @@
if (!rump_threads) {
si->si_func(si->si_arg);
} else {
- mutex_enter(&si_mtx);
+ rumpuser_mutex_enter(si_mtx);
if (!(si->si_flags & SI_ONLIST)) {
- LIST_INSERT_HEAD(&si_pending, si, si_entries);
+ LIST_INSERT_HEAD(&softints[si->si_level].si_pending,
+ si, si_entries);
si->si_flags |= SI_ONLIST;
}
- cv_signal(&si_cv);
- mutex_exit(&si_mtx);
+ rumpuser_mutex_exit(si_mtx);
}
}
@@ -279,13 +274,28 @@
{
struct softint *si = cook;
+ rumpuser_mutex_enter(si_mtx);
if (si->si_flags & SI_ONLIST) {
si->si_flags |= SI_KILLME;
return;
}
+ rumpuser_mutex_exit(si_mtx);
kmem_free(si, sizeof(*si));
}
+void
+rump_softint_run(struct cpu_info *ci)
+{
+ int i;
+
+ rumpuser_mutex_enter_nowrap(si_mtx);
+ for (i = 0; i < SOFTINT_COUNT; i++) {
+ if (!LIST_EMPTY(&softints[i].si_pending))
+ rumpuser_cv_signal(softints[i].si_cv);
+ }
+ rumpuser_mutex_exit(si_mtx);
+}
+
bool
cpu_intr_p(void)
{
@@ -293,10 +303,9 @@
return false;
}
-/* yea, we lie a bit for now */
bool
cpu_softintr_p(void)
{
- return false;
+ return curlwp->l_pflag & LP_INTR;
}
diff -r 47bffe117a5e -r 2e55df76a211 sys/rump/librump/rumpkern/rump_private.h
--- a/sys/rump/librump/rumpkern/rump_private.h Mon Nov 09 19:02:49 2009 +0000
+++ b/sys/rump/librump/rumpkern/rump_private.h Mon Nov 09 19:16:18 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rump_private.h,v 1.34 2009/10/16 00:14:53 pooka Exp $ */
+/* $NetBSD: rump_private.h,v 1.35 2009/11/09 19:17:42 pooka Exp $ */
/*
* Copyright (c) 2007 Antti Kantee. All Rights Reserved.
@@ -31,7 +31,7 @@
#define _SYS_RUMP_PRIVATE_H_
#include <sys/param.h>
-#include <sys/systm.h>
+#include <sys/cpu.h>
#include <sys/lwp.h>
#include <sys/proc.h>
#include <sys/systm.h>
@@ -101,4 +101,6 @@
void kernel_unlock_allbutone(int *);
void kernel_ununlock_allbutone(int);
+void rump_softint_run(struct cpu_info *);
+
#endif /* _SYS_RUMP_PRIVATE_H_ */
diff -r 47bffe117a5e -r 2e55df76a211 sys/rump/librump/rumpkern/scheduler.c
--- a/sys/rump/librump/rumpkern/scheduler.c Mon Nov 09 19:02:49 2009 +0000
+++ b/sys/rump/librump/rumpkern/scheduler.c Mon Nov 09 19:16:18 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: scheduler.c,v 1.6 2009/11/06 16:15:16 pooka Exp $ */
+/* $NetBSD: scheduler.c,v 1.7 2009/11/09 19:16:18 pooka Exp $ */
/*
* Copyright (c) 2009 Antti Kantee. All Rights Reserved.
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: scheduler.c,v 1.6 2009/11/06 16:15:16 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: scheduler.c,v 1.7 2009/11/09 19:16:18 pooka Exp $");
#include <sys/param.h>
#include <sys/cpu.h>
@@ -182,6 +182,9 @@
struct cpu_info *ci;
ci = l->l_cpu;
+ if ((l->l_pflag & LP_INTR) == 0)
+ rump_softint_run(ci);
Home |
Main Index |
Thread Index |
Old Index