summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2003-11-03 21:06:54 +0000
committerjhb <jhb@FreeBSD.org>2003-11-03 21:06:54 +0000
commitcb9d92d08a0d2bd70a0f41d9d09876eacfa5485d (patch)
tree47ad851749ec1bdf5c3188802729a147016abca2
parentd4fb13c8f3b33967ad21f6f766a515c18306ae73 (diff)
downloadFreeBSD-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.c133
-rw-r--r--sys/i386/include/critical.h21
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__ */
OpenPOWER on IntegriCloud