summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa/ipl_funcs.c
diff options
context:
space:
mode:
authorfsmp <fsmp@FreeBSD.org>1997-09-07 22:04:09 +0000
committerfsmp <fsmp@FreeBSD.org>1997-09-07 22:04:09 +0000
commit877f33cf608a56f37130585cbf62e69a7fa8867e (patch)
tree6c18f1143fc34dc43e409761227569d2ec2324bc /sys/i386/isa/ipl_funcs.c
parent6787a3eb7ff21685017eabc3972f4a5b24109e70 (diff)
downloadFreeBSD-src-877f33cf608a56f37130585cbf62e69a7fa8867e.zip
FreeBSD-src-877f33cf608a56f37130585cbf62e69a7fa8867e.tar.gz
General cleanup of the lock pushdown code. They are grouped and enabled
from machine/smptests.h: #define PUSHDOWN_LEVEL_1 #define PUSHDOWN_LEVEL_2 #define PUSHDOWN_LEVEL_3 #define PUSHDOWN_LEVEL_4_NOT
Diffstat (limited to 'sys/i386/isa/ipl_funcs.c')
-rw-r--r--sys/i386/isa/ipl_funcs.c239
1 files changed, 173 insertions, 66 deletions
diff --git a/sys/i386/isa/ipl_funcs.c b/sys/i386/isa/ipl_funcs.c
index 67463ee..5eda48b 100644
--- a/sys/i386/isa/ipl_funcs.c
+++ b/sys/i386/isa/ipl_funcs.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: ipl_funcs.c,v 1.6 1997/08/29 18:45:23 fsmp Exp $
+ * $Id: ipl_funcs.c,v 1.14 1997/09/05 20:22:10 smp Exp smp $
*/
#include <sys/types.h>
@@ -97,26 +97,24 @@ splx(unsigned ipl)
#else /* !SMP */
#include <machine/smp.h>
-extern int bspEarly; /* XXX */
+#include <machine/smptests.h>
-#ifdef REAL_IFCPL
+#ifndef SPL_DEBUG_POSTCODE
+#undef POSTCODE
+#undef POSTCODE_LO
+#undef POSTCODE_HI
+#define POSTCODE(X)
+#define POSTCODE_LO(X)
+#define POSTCODE_HI(X)
+#endif /* SPL_DEBUG_POSTCODE */
-#define IFCPL_LOCK() SCPL_LOCK()
-#define IFCPL_UNLOCK() SCPL_UNLOCK()
-
-#else /* REAL_IFCPL */
-
-#define IFCPL_LOCK()
-#define IFCPL_UNLOCK()
-
-#endif /* REAL_IFCPL */
/*
* The volatile bitmap variables must be set atomically. This normally
* involves using a machine-dependent bit-set or `or' instruction.
*/
-#define DO_SETBITS(name, var, bits) \
+#define DO_SETBITS(name, var, bits) \
void name(void) \
{ \
IFCPL_LOCK(); \
@@ -142,90 +140,185 @@ softclockpending(void)
x = ipending & SWI_CLOCK_PENDING;
IFCPL_UNLOCK();
- return x;
+ return (x);
}
-#ifdef notneeded
-#define GENSPL(name, set_cpl) \
-unsigned name(void) \
-{ \
- unsigned x; \
- \
- IFCPL_LOCK(); \
- x = cpl; \
- /* XXX test cil */ \
- set_cpl; \
- IFCPL_UNLOCK(); \
- \
- return (x); \
-}
-#endif /* notneeded */
-
/*
* This version has to check for bsp_apic_ready,
* as calling simple_lock() (ie ss_lock) before then deadlocks the system.
- * A sample count of GENSPLR calls before bsp_apic_ready was set: 2193
+ * A sample count of GENSPL calls before bsp_apic_ready was set: 2193
*/
-#define GENSPLR(name, set_cpl) \
-unsigned name(void) \
+
+#ifdef INTR_SPL
+
+#ifdef SPL_DEBUG
+#define MAXZ 100000000
+#define SPIN_COUNT unsigned z = 0;
+#define SPIN_SPL \
+ if (++z >= MAXZ) { \
+ bsp_apic_ready = 0; \
+ panic("\ncil: 0x%08x", cil); \
+ }
+#else /* SPL_DEBUG */
+#define SPIN_COUNT
+#define SPIN_SPL
+#endif /* SPL_DEBUG */
+
+#endif
+
+#ifdef INTR_SPL
+
+#define GENSPL(NAME, OP, MODIFIER, PC) \
+unsigned NAME(void) \
+{ \
+ unsigned x, y; \
+ SPIN_COUNT; \
+ \
+ if (!bsp_apic_ready) { \
+ x = cpl; \
+ cpl OP MODIFIER; \
+ return (x); \
+ } \
+ \
+ for (;;) { \
+ IFCPL_LOCK(); /* MP-safe */ \
+ x = y = cpl; /* current value */ \
+ POSTCODE(0x20 | PC); \
+ if (inside_intr) \
+ break; /* XXX only 1 INT allowed */ \
+ y OP MODIFIER; /* desired value */ \
+ if (cil & y) { /* not now */ \
+ IFCPL_UNLOCK(); /* allow cil to change */ \
+ while (cil & y) \
+ SPIN_SPL \
+ continue; /* try again */ \
+ } \
+ break; \
+ } \
+ cpl OP MODIFIER; /* make the change */ \
+ IFCPL_UNLOCK(); \
+ \
+ return (x); \
+}
+
+/* NAME: OP: MODIFIER: PC: */
+GENSPL(splbio, |=, bio_imask, 2)
+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(splsoftclock, =, SWI_CLOCK_MASK, 7)
+GENSPL(splsofttty, |=, SWI_TTY_MASK, 8)
+GENSPL(splstatclock, |=, stat_imask, 9)
+GENSPL(spltty, |=, tty_imask, 10)
+GENSPL(splvm, |=, net_imask | bio_imask, 11)
+
+#else /* INTR_SPL */
+
+#define GENSPL(NAME, set_cpl) \
+unsigned NAME(void) \
{ \
unsigned x; \
\
- if (bsp_apic_ready) \
+ if (!bsp_apic_ready) { \
+ x = cpl; \
+ set_cpl; \
+ } \
+ else { \
IFCPL_LOCK(); \
- x = cpl; \
- /* XXX test cil */ \
- set_cpl; \
- if (bsp_apic_ready) \
+ x = cpl; \
+ set_cpl; \
IFCPL_UNLOCK(); \
+ } \
\
return (x); \
}
-GENSPLR(splbio, cpl |= bio_imask)
-GENSPLR(splclock, cpl = HWI_MASK | SWI_MASK)
-GENSPLR(splhigh, cpl = HWI_MASK | SWI_MASK)
-GENSPLR(splimp, cpl |= net_imask)
-GENSPLR(splnet, cpl |= SWI_NET_MASK)
-GENSPLR(splsoftclock, cpl = SWI_CLOCK_MASK)
-GENSPLR(splsofttty, cpl |= SWI_TTY_MASK)
-GENSPLR(splstatclock, cpl |= stat_imask)
-GENSPLR(spltty, cpl |= tty_imask)
-GENSPLR(splvm, cpl |= net_imask | bio_imask)
+GENSPL(splbio, cpl |= bio_imask)
+GENSPL(splclock, cpl = HWI_MASK | SWI_MASK)
+GENSPL(splhigh, cpl = HWI_MASK | SWI_MASK)
+GENSPL(splimp, cpl |= net_imask)
+GENSPL(splnet, cpl |= SWI_NET_MASK)
+GENSPL(splsoftclock, cpl = SWI_CLOCK_MASK)
+GENSPL(splsofttty, cpl |= SWI_TTY_MASK)
+GENSPL(splstatclock, cpl |= stat_imask)
+GENSPL(spltty, cpl |= tty_imask)
+GENSPL(splvm, cpl |= net_imask | bio_imask)
+
+#endif /* INTR_SPL */
void
spl0(void)
{
+ int unpend;
+#ifdef INTR_SPL
+ SPIN_COUNT;
+
+ for (;;) {
+ IFCPL_LOCK();
+ POSTCODE_HI(0xc);
+ if (cil & SWI_AST_MASK) { /* not now */
+ IFCPL_UNLOCK(); /* allow cil to change */
+ while (cil & SWI_AST_MASK)
+ SPIN_SPL
+ continue; /* try again */
+ }
+ break;
+ }
+#else /* INTR_SPL */
IFCPL_LOCK();
+#endif /* INTR_SPL */
- /* XXX test cil */
cpl = SWI_AST_MASK;
- if (ipending & ~SWI_AST_MASK) {
- IFCPL_UNLOCK();
+ unpend = ipending & ~SWI_AST_MASK;
+ IFCPL_UNLOCK();
+
+ if (unpend && !inside_intr)
splz();
- }
- else
- IFCPL_UNLOCK();
}
void
splx(unsigned ipl)
{
- if (bsp_apic_ready)
+ int unpend;
+#ifdef INTR_SPL
+ SPIN_COUNT;
+#endif
+
+ if (!bsp_apic_ready) {
+ cpl = ipl;
+ if (ipending & ~ipl)
+ splz();
+ return;
+ }
+
+#ifdef INTR_SPL
+ for (;;) {
IFCPL_LOCK();
+ POSTCODE_HI(0xe);
+ if (inside_intr)
+ break; /* XXX only 1 INT allowed */
+ POSTCODE_HI(0xf);
+ if (cil & ipl) { /* not now */
+ IFCPL_UNLOCK(); /* allow cil to change */
+ while (cil & ipl)
+ SPIN_SPL
+ continue; /* try again */
+ }
+ break;
+ }
+#else /* INTR_SPL */
+ IFCPL_LOCK();
+#endif /* INTR_SPL */
- /* XXX test cil */
cpl = ipl;
- if (ipending & ~ipl) {
- if (bsp_apic_ready)
- IFCPL_UNLOCK();
+ unpend = ipending & ~ipl;
+ IFCPL_UNLOCK();
+
+ if (unpend && !inside_intr)
splz();
- }
- else
- if (bsp_apic_ready)
- IFCPL_UNLOCK();
}
@@ -243,15 +336,29 @@ splx(unsigned ipl)
intrmask_t
splq(intrmask_t mask)
{
- intrmask_t tmp;
+ intrmask_t tmp, tmp2;
+#ifdef INTR_SPL
+ for (;;) {
+ IFCPL_LOCK();
+ tmp = tmp2 = cpl;
+ tmp2 |= mask;
+ if (cil & tmp2) { /* not now */
+ IFCPL_UNLOCK(); /* allow cil to change */
+ while (cil & tmp2)
+ /* spin */ ;
+ continue; /* try again */
+ }
+ break;
+ }
+ cpl = tmp2;
+#else /* INTR_SPL */
IFCPL_LOCK();
-
tmp = cpl;
cpl |= mask;
+#endif /* INTR_SPL */
IFCPL_UNLOCK();
-
return (tmp);
}
OpenPOWER on IntegriCloud