diff options
author | jasone <jasone@FreeBSD.org> | 2000-09-07 01:33:02 +0000 |
---|---|---|
committer | jasone <jasone@FreeBSD.org> | 2000-09-07 01:33:02 +0000 |
commit | 769e0f974d8929599ba599ac496510fffc90ff34 (patch) | |
tree | 9387522900085835de81e7830e570ef3f6b3ea80 /sys/i386/isa/ipl_funcs.c | |
parent | acf1927de02afda4855ec278b1128fd9446405ea (diff) | |
download | FreeBSD-src-769e0f974d8929599ba599ac496510fffc90ff34.zip FreeBSD-src-769e0f974d8929599ba599ac496510fffc90ff34.tar.gz |
Major update to the way synchronization is done in the kernel. Highlights
include:
* Mutual exclusion is used instead of spl*(). See mutex(9). (Note: The
alpha port is still in transition and currently uses both.)
* Per-CPU idle processes.
* Interrupts are run in their own separate kernel threads and can be
preempted (i386 only).
Partially contributed by: BSDi (BSD/OS)
Submissions by (at least): cp, dfr, dillon, grog, jake, jhb, sheldonh
Diffstat (limited to 'sys/i386/isa/ipl_funcs.c')
-rw-r--r-- | sys/i386/isa/ipl_funcs.c | 267 |
1 files changed, 44 insertions, 223 deletions
diff --git a/sys/i386/isa/ipl_funcs.c b/sys/i386/isa/ipl_funcs.c index d27d97f..14eb240 100644 --- a/sys/i386/isa/ipl_funcs.c +++ b/sys/i386/isa/ipl_funcs.c @@ -27,11 +27,13 @@ */ #include <sys/param.h> +#include <sys/bus.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/sysctl.h> #include <machine/ipl.h> -#include <machine/globals.h> +#include <sys/proc.h> +#include <i386/isa/icu.h> #include <i386/isa/intr_machdep.h> /* @@ -45,236 +47,55 @@ void name(void) \ { \ atomic_set_int(var, bits); \ + sched_ithd((void *) SOFTINTR); \ } -DO_SETBITS(setdelayed, &ipending, loadandclear(&idelayed)) +DO_SETBITS(setdelayed, &spending, loadandclear(&idelayed)) +DO_SETBITS(setsoftcamnet,&spending, SWI_CAMNET_PENDING) +DO_SETBITS(setsoftcambio,&spending, SWI_CAMBIO_PENDING) +DO_SETBITS(setsoftclock, &spending, SWI_CLOCK_PENDING) +DO_SETBITS(setsoftnet, &spending, SWI_NET_PENDING) +DO_SETBITS(setsofttty, &spending, SWI_TTY_PENDING) +DO_SETBITS(setsoftvm, &spending, SWI_VM_PENDING) +DO_SETBITS(setsofttq, &spending, SWI_TQ_PENDING) -DO_SETBITS(setsoftcamnet,&ipending, SWI_CAMNET_PENDING) -DO_SETBITS(setsoftcambio,&ipending, SWI_CAMBIO_PENDING) -DO_SETBITS(setsoftclock, &ipending, SWI_CLOCK_PENDING) -DO_SETBITS(setsoftnet, &ipending, SWI_NET_PENDING) -DO_SETBITS(setsofttty, &ipending, SWI_TTY_PENDING) -DO_SETBITS(setsoftvm, &ipending, SWI_VM_PENDING) -DO_SETBITS(setsofttq, &ipending, SWI_TQ_PENDING) - -DO_SETBITS(schedsoftcamnet, &idelayed, SWI_CAMNET_PENDING) -DO_SETBITS(schedsoftcambio, &idelayed, SWI_CAMBIO_PENDING) -DO_SETBITS(schedsoftnet, &idelayed, SWI_NET_PENDING) -DO_SETBITS(schedsofttty, &idelayed, SWI_TTY_PENDING) -DO_SETBITS(schedsoftvm, &idelayed, SWI_VM_PENDING) -DO_SETBITS(schedsofttq, &idelayed, SWI_TQ_PENDING) +/* + * We don't need to schedule soft interrupts any more, it happens + * automatically. + */ +#define schedsoftcamnet +#define schedsoftcambio +#define schedsoftnet +#define schedsofttty +#define schedsoftvm +#define schedsofttq unsigned softclockpending(void) { - return (ipending & SWI_CLOCK_PENDING); + return (spending & SWI_CLOCK_PENDING); } /* - * Support for SPL assertions. - */ - -#ifdef INVARIANT_SUPPORT - -#define SPLASSERT_IGNORE 0 -#define SPLASSERT_LOG 1 -#define SPLASSERT_PANIC 2 - -static int splassertmode = SPLASSERT_LOG; -SYSCTL_INT(_kern, OID_AUTO, splassertmode, CTLFLAG_RW, - &splassertmode, 0, "Set the mode of SPLASSERT"); - -static void -init_splassertmode(void *ignored) -{ - TUNABLE_INT_FETCH("kern.splassertmode", 0, splassertmode); -} -SYSINIT(param, SI_SUB_TUNABLES, SI_ORDER_ANY, init_splassertmode, NULL); - -static void -splassertfail(char *str, const char *msg, char *name, int level) -{ - switch (splassertmode) { - case SPLASSERT_IGNORE: - break; - case SPLASSERT_LOG: - printf(str, msg, name, level); - printf("\n"); - break; - case SPLASSERT_PANIC: - panic(str, msg, name, level); - break; - } -} - -#define GENSPLASSERT(NAME, MODIFIER) \ -void \ -NAME##assert(const char *msg) \ -{ \ - if ((cpl & (MODIFIER)) != (MODIFIER)) \ - splassertfail("%s: not %s, cpl == %#x", \ - msg, __XSTRING(NAME) + 3, cpl); \ -} -#else -#define GENSPLASSERT(NAME, MODIFIER) -#endif - -/************************************************************************ - * GENERAL SPL CODE * - ************************************************************************ - * - * Implement splXXX(), spl0(), splx(), and splq(). splXXX() disables a - * set of interrupts (e.g. splbio() disables interrupts relating to - * device I/O) and returns the previous interrupt mask. splx() restores - * the previous interrupt mask, spl0() is a special case which enables - * all interrupts and is typically used inside i386/i386 swtch.s and - * fork_trampoline. splq() is a generic version of splXXX(). - * - * The SPL routines mess around with the 'cpl' global, which masks - * interrupts. Interrupts are not *actually* masked. What happens is - * that if an interrupt masked by the cpl occurs, the appropriate bit - * in 'ipending' is set and the interrupt is defered. When we clear - * bits in the cpl we must check to see if any ipending interrupts have - * been unmasked and issue the synchronously, which is what the splz() - * call does. - * - * Because the cpl is often saved and restored in a nested fashion, cpl - * modifications are only allowed in the SMP case when the MP lock is held - * to prevent multiple processes from tripping over each other's masks. - * The cpl is saved when you do a context switch (mi_switch()) and restored - * when your process gets cpu again. - * - * An interrupt routine is allowed to modify the cpl as long as it restores - * it prior to returning (thus the interrupted mainline code doesn't notice - * anything amiss). For the SMP case, the interrupt routine must hold - * the MP lock for any cpl manipulation. - * - * Likewise, due to the deterministic nature of cpl modifications, we do - * NOT need to use locked instructions to modify it. + * Dummy spl calls. The only reason for these is to not break + * all the code which expects to call them. */ - -#ifndef SMP - -#define GENSPL(NAME, OP, MODIFIER, PC) \ -GENSPLASSERT(NAME, MODIFIER) \ -unsigned NAME(void) \ -{ \ - unsigned x; \ - \ - x = cpl; \ - cpl OP MODIFIER; \ - return (x); \ -} - -void -spl0(void) -{ - cpl = 0; - if (ipending) - splz(); -} - -void -splx(unsigned ipl) -{ - cpl = ipl; - if (ipending & ~ipl) - splz(); -} - -intrmask_t -splq(intrmask_t mask) -{ - intrmask_t tmp = cpl; - cpl |= mask; - return (tmp); -} - -#else /* !SMP */ - -#include <machine/smp.h> -#include <machine/smptests.h> - -/* - * SMP CASE - * - * Mostly the same as the non-SMP case now, but it didn't used to be - * this clean. - */ - -#define GENSPL(NAME, OP, MODIFIER, PC) \ -GENSPLASSERT(NAME, MODIFIER) \ -unsigned NAME(void) \ -{ \ - unsigned x; \ - \ - x = cpl; \ - cpl OP MODIFIER; \ - \ - return (x); \ -} - -/* - * spl0() - unmask all interrupts - * - * The MP lock must be held on entry - * This routine may only be called from mainline code. - */ -void -spl0(void) -{ - KASSERT(inside_intr == 0, ("spl0: called from interrupt")); - cpl = 0; - if (ipending) - splz(); -} - -/* - * splx() - restore previous interrupt mask - * - * The MP lock must be held on entry - */ - -void -splx(unsigned ipl) -{ - cpl = ipl; - if (inside_intr == 0 && (ipending & ~cpl) != 0) - splz(); -} - - -/* - * splq() - blocks specified interrupts - * - * The MP lock must be held on entry - */ -intrmask_t -splq(intrmask_t mask) -{ - intrmask_t tmp = cpl; - cpl |= mask; - return (tmp); -} - -#endif /* !SMP */ - -/* Finally, generate the actual spl*() functions */ - -/* NAME: OP: MODIFIER: PC: */ -GENSPL(splbio, |=, bio_imask, 2) -GENSPL(splcam, |=, cam_imask, 7) -GENSPL(splclock, =, HWI_MASK | SWI_MASK, 3) -GENSPL(splhigh, =, HWI_MASK | SWI_MASK, 4) -GENSPL(splimp, |=, net_imask, 5) -GENSPL(splnet, |=, SWI_NET_MASK, 6) -GENSPL(splsoftcam, |=, SWI_CAMBIO_MASK | SWI_CAMNET_MASK, 8) -GENSPL(splsoftcambio, |=, SWI_CAMBIO_MASK, 9) -GENSPL(splsoftcamnet, |=, SWI_CAMNET_MASK, 10) -GENSPL(splsoftclock, =, SWI_CLOCK_MASK, 11) -GENSPL(splsofttty, |=, SWI_TTY_MASK, 12) -GENSPL(splsoftvm, |=, SWI_VM_MASK, 16) -GENSPL(splsofttq, |=, SWI_TQ_MASK, 17) -GENSPL(splstatclock, |=, stat_imask, 13) -GENSPL(spltty, |=, tty_imask, 14) -GENSPL(splvm, |=, net_imask | bio_imask | cam_imask, 15) +void spl0 (void) {} +void splx (intrmask_t x) {} +intrmask_t splq(intrmask_t mask) {return 0; } +intrmask_t splbio(void) {return 0; } +intrmask_t splcam(void) {return 0; } +intrmask_t splclock(void) {return 0; } +intrmask_t splhigh(void) {return 0; } +intrmask_t splimp(void) {return 0; } +intrmask_t splnet(void) {return 0; } +intrmask_t splsoftcam(void) {return 0; } +intrmask_t splsoftcambio(void) {return 0; } +intrmask_t splsoftcamnet(void) {return 0; } +intrmask_t splsoftclock(void) {return 0; } +intrmask_t splsofttty(void) {return 0; } +intrmask_t splsoftvm(void) {return 0; } +intrmask_t splsofttq(void) {return 0; } +intrmask_t splstatclock(void) {return 0; } +intrmask_t spltty(void) {return 0; } +intrmask_t splvm(void) {return 0; } |