Module Name: src Committed By: pooka Date: Sun Aug 15 21:28:33 UTC 2010
Modified Files: src/sys/rump/librump/rumpkern: intr.c Log Message: Implement softints properly: they need to have a schedulable entity per cpu. To generate a diff of this commit: cvs rdiff -u -r1.31 -r1.32 src/sys/rump/librump/rumpkern/intr.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.31 src/sys/rump/librump/rumpkern/intr.c:1.32 --- src/sys/rump/librump/rumpkern/intr.c:1.31 Tue Aug 10 21:32:38 2010 +++ src/sys/rump/librump/rumpkern/intr.c Sun Aug 15 21:28:33 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: intr.c,v 1.31 2010/08/10 21:32:38 pooka Exp $ */ +/* $NetBSD: intr.c,v 1.32 2010/08/15 21:28:33 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.31 2010/08/10 21:32:38 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.32 2010/08/15 21:28:33 pooka Exp $"); #include <sys/param.h> #include <sys/atomic.h> @@ -47,21 +47,28 @@ */ #define SI_MPSAFE 0x01 -#define SI_ONLIST 0x02 -#define SI_KILLME 0x04 +#define SI_KILLME 0x02 +struct softint_percpu; struct softint { void (*si_func)(void *); void *si_arg; int si_flags; int si_level; - LIST_ENTRY(softint) si_entries; + struct softint_percpu *si_entry; /* [0,ncpu-1] */ +}; + +struct softint_percpu { + struct softint *sip_parent; + bool sip_onlist; + + LIST_ENTRY(softint_percpu) sip_entries; }; struct softint_lev { struct rumpuser_cv *si_cv; - LIST_HEAD(, softint) si_pending; + LIST_HEAD(, softint_percpu) si_pending; }; kcondvar_t lbolt; /* Oh Kath Ra */ @@ -148,6 +155,7 @@ static void sithread(void *arg) { + struct softint_percpu *sip; struct softint *si; void (*func)(void *) = NULL; void *funarg; @@ -161,13 +169,15 @@ for (;;) { if (!LIST_EMPTY(&si_lvl->si_pending)) { - si = LIST_FIRST(&si_lvl->si_pending); + sip = LIST_FIRST(&si_lvl->si_pending); + si = sip->sip_parent; + func = si->si_func; funarg = si->si_arg; mpsafe = si->si_flags & SI_MPSAFE; - si->si_flags &= ~SI_ONLIST; - LIST_REMOVE(si, si_entries); + sip->sip_onlist = false; + LIST_REMOVE(sip, sip_entries); if (si->si_flags & SI_KILLME) { softint_disestablish(si); continue; @@ -247,6 +257,8 @@ softint_establish(u_int flags, void (*func)(void *), void *arg) { struct softint *si; + struct softint_percpu *sip; + int i; si = malloc(sizeof(*si), M_TEMP, M_WAITOK); si->si_func = func; @@ -254,6 +266,12 @@ si->si_flags = flags & SOFTINT_MPSAFE ? SI_MPSAFE : 0; si->si_level = flags & SOFTINT_LVLMASK; KASSERT(si->si_level < SOFTINT_COUNT); + si->si_entry = malloc(sizeof(*si->si_entry) * ncpu, + M_TEMP, M_WAITOK | M_ZERO); + for (i = 0; i < ncpu; i++) { + sip = &si->si_entry[i]; + sip->sip_parent = si; + } return si; } @@ -262,30 +280,40 @@ softint_schedule(void *arg) { struct softint *si = arg; + struct softint_percpu *sip = &si->si_entry[curcpu()->ci_index]; 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 { - if (!(si->si_flags & SI_ONLIST)) { + if (!sip->sip_onlist) { LIST_INSERT_HEAD(&si_lvl[si->si_level].si_pending, - si, si_entries); - si->si_flags |= SI_ONLIST; + sip, sip_entries); + sip->sip_onlist = true; } } } -/* flimsy disestablish: should wait for softints to finish */ +/* + * flimsy disestablish: should wait for softints to finish. + */ void softint_disestablish(void *cook) { struct softint *si = cook; + int i; - if (si->si_flags & SI_ONLIST) { - si->si_flags |= SI_KILLME; - return; + for (i = 0; i < ncpu; i++) { + struct softint_percpu *sip; + + sip = &si->si_entry[i]; + if (sip->sip_onlist) { + si->si_flags |= SI_KILLME; + return; + } } + free(si->si_entry, M_TEMP); free(si, M_TEMP); }