summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa/ipl_funcs.c
diff options
context:
space:
mode:
authorjasone <jasone@FreeBSD.org>2000-09-07 01:33:02 +0000
committerjasone <jasone@FreeBSD.org>2000-09-07 01:33:02 +0000
commit769e0f974d8929599ba599ac496510fffc90ff34 (patch)
tree9387522900085835de81e7830e570ef3f6b3ea80 /sys/i386/isa/ipl_funcs.c
parentacf1927de02afda4855ec278b1128fd9446405ea (diff)
downloadFreeBSD-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.c267
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; }
OpenPOWER on IntegriCloud