diff options
author | jhb <jhb@FreeBSD.org> | 2003-11-03 21:06:54 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2003-11-03 21:06:54 +0000 |
commit | cb9d92d08a0d2bd70a0f41d9d09876eacfa5485d (patch) | |
tree | 47ad851749ec1bdf5c3188802729a147016abca2 | |
parent | d4fb13c8f3b33967ad21f6f766a515c18306ae73 (diff) | |
download | FreeBSD-src-cb9d92d08a0d2bd70a0f41d9d09876eacfa5485d.zip FreeBSD-src-cb9d92d08a0d2bd70a0f41d9d09876eacfa5485d.tar.gz |
Revert the critical section implementation to disable interrupts via
cli/sti now that we support many more than 32 interrupt sources.
-rw-r--r-- | sys/i386/i386/critical.c | 133 | ||||
-rw-r--r-- | sys/i386/include/critical.h | 21 |
2 files changed, 9 insertions, 145 deletions
diff --git a/sys/i386/i386/critical.c b/sys/i386/i386/critical.c index 8c24387..325d97a 100644 --- a/sys/i386/i386/critical.c +++ b/sys/i386/i386/critical.c @@ -30,144 +30,17 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/systm.h> -#include <sys/signalvar.h> -#include <sys/kernel.h> -#include <sys/lock.h> -#include <sys/mutex.h> -#include <sys/pcpu.h> #include <sys/proc.h> -#include <sys/sysctl.h> -#include <sys/ucontext.h> -#include <machine/clock.h> #include <machine/critical.h> -#ifdef SMP -#include <machine/privatespace.h> -#include <machine/smp.h> -#else -/* - * XXX this mess to get sched_ithd() and call_fast_unpend() - */ -#include <sys/bus.h> -#include <machine/apic.h> -#include <machine/frame.h> -#include <i386/isa/icu.h> -#include <i386/isa/intr_machdep.h> -#endif - -void i386_unpend(void); /* NOTE: not static, called from assembly */ - -/* - * cpu_unpend() - called from critical_exit() inline after quick - * interrupt-pending check. - */ -void -cpu_unpend(void) -{ - register_t eflags; - struct thread *td; - - td = curthread; - eflags = intr_disable(); - if (PCPU_GET(int_pending)) { - ++td->td_intr_nesting_level; - i386_unpend(); - --td->td_intr_nesting_level; - } - intr_restore(eflags); -} - /* * cpu_critical_fork_exit() - cleanup after fork - */ -void -cpu_critical_fork_exit(void) -{ - - enable_intr(); -} - -/* - * Called from cpu_unpend or called from the assembly vector code - * to process any interrupts which may have occured while we were in - * a critical section. - * - * - interrupts must be disabled - * - td_critnest must be 0 - * - td_intr_nesting_level must be incremented by the caller * - * NOT STATIC (called from assembly) + * Enable interrupts in the saved copy of eflags. */ void -i386_unpend(void) +cpu_critical_fork_exit(void) { - struct clockframe frame; - - frame.cf_cs = SEL_KPL; - frame.cf_eip = (register_t)i386_unpend; - frame.cf_eflags = PSL_KERNEL; - KASSERT(curthread->td_critnest == 0, ("unpend critnest != 0")); - KASSERT((read_eflags() & PSL_I) == 0, ("unpend interrupts enabled1")); - curthread->td_critnest = 1; - for (;;) { - u_int32_t mask; - int irq; - - /* - * Fast interrupts have priority - */ - if ((mask = PCPU_GET(fpending)) != 0) { - irq = bsfl(mask); - PCPU_SET(fpending, mask & ~(1 << irq)); - call_fast_unpend(irq); - KASSERT((read_eflags() & PSL_I) == 0, - ("unpend interrupts enabled2 %d", irq)); - continue; - } - - /* - * Threaded interrupts come next - */ - if ((mask = PCPU_GET(ipending)) != 0) { - irq = bsfl(mask); - PCPU_SET(ipending, mask & ~(1 << irq)); - sched_ithd((void *)irq); - KASSERT((read_eflags() & PSL_I) == 0, - ("unpend interrupts enabled3 %d", irq)); - continue; - } - /* - * Software interrupts and delayed IPIs are last - * - * XXX give the bits #defined names. see also - * isa/xxx_vector.s - */ - if ((mask = PCPU_GET(spending)) != 0) { - irq = bsfl(mask); - PCPU_SET(spending, mask & ~(1 << irq)); - switch(irq) { - case 0: /* bit 0 - hardclock */ - hardclock_process(&frame); - break; - case 1: /* bit 1 - statclock */ - if (profprocs != 0) - profclock(&frame); - if (pscnt == psdiv) - statclock(&frame); - break; - } - KASSERT((read_eflags() & PSL_I) == 0, - ("unpend interrupts enabled4 %d", irq)); - continue; - } - break; - } - /* - * Interrupts are still disabled, we can safely clear int_pending - * and td_critnest. - */ - KASSERT((read_eflags() & PSL_I) == 0, ("unpend interrupts enabled5")); - PCPU_SET(int_pending, 0); - curthread->td_critnest = 0; + curthread->td_md.md_savecrit = read_eflags() | PSL_I; } diff --git a/sys/i386/include/critical.h b/sys/i386/include/critical.h index 689d039..5a14f70 100644 --- a/sys/i386/include/critical.h +++ b/sys/i386/include/critical.h @@ -44,7 +44,6 @@ __BEGIN_DECLS /* * Prototypes - see <arch>/<arch>/critical.c */ -void cpu_unpend(void); void cpu_critical_fork_exit(void); #ifdef __GNUC__ @@ -59,7 +58,11 @@ void cpu_critical_fork_exit(void); * However, as a side effect any interrupts occuring while td_critnest * is non-zero will be deferred. */ -#define cpu_critical_enter() +static __inline void +cpu_critical_enter(void) +{ + curthread->td_md.md_savecrit = intr_disable(); +} /* * cpu_critical_exit: @@ -75,19 +78,7 @@ void cpu_critical_fork_exit(void); static __inline void cpu_critical_exit(void) { - /* - * We may have to schedule pending interrupts. Create - * conditions similar to an interrupt context and call - * unpend(). - * - * note: we do this even if we are in an interrupt - * nesting level. Deep nesting is protected by - * critical_*() and if we conditionalized it then we - * would have to check int_pending again whenever - * we decrement td_intr_nesting_level to 0. - */ - if (PCPU_GET(int_pending)) - cpu_unpend(); + intr_restore(curthread->td_md.md_savecrit); } #else /* !__GNUC__ */ |