PERFORCE change 64889 for review
John Baldwin
jhb at FreeBSD.org
Thu Nov 11 11:15:24 PST 2004
http://perforce.freebsd.org/chv.cgi?CH=64889
Change 64889 by jhb at jhb_slimer on 2004/11/11 19:15:13
Add and use macros for use in IPI spin-wait loops to dink with
TPR and enable interrupts while holding a spinlock such that we
will allow safe IPIs to interrupt us while waiting in the spin
loop.
XXX: Ideally what we would do is just mess with the TPR to
implement critical sections instead of cli/sti. Maybe amd64 can
do this if it mandates APIC use.
Affected files ...
.. //depot/projects/smpng/sys/i386/i386/local_apic.c#16 edit
.. //depot/projects/smpng/sys/i386/i386/mp_machdep.c#75 edit
.. //depot/projects/smpng/sys/i386/i386/pmap.c#77 edit
.. //depot/projects/smpng/sys/i386/include/apicvar.h#8 edit
Differences ...
==== //depot/projects/smpng/sys/i386/i386/local_apic.c#16 (text+ko) ====
@@ -666,6 +666,8 @@
* Wait delay loops for IPI to be sent. This is highly bogus
* since this is sensitive to CPU clock speed. If delay is
* -1, we wait forever.
+ *
+ * XXX: Should we be using the IPI spinwait macros here?
*/
if (delay == -1) {
incr = 0;
@@ -761,7 +763,7 @@
* the failure with the check above when the next IPI is
* sent.
*
- * We could skiip this wait entirely, EXCEPT it probably
+ * We could skip this wait entirely, EXCEPT it probably
* protects us from other routines that assume that the
* message was delivered and acted upon when this function
* returns.
==== //depot/projects/smpng/sys/i386/i386/mp_machdep.c#75 (text+ko) ====
@@ -932,8 +932,10 @@
smp_tlb_addr2 = addr2;
atomic_store_rel_int(&smp_tlb_wait, 0);
ipi_all_but_self(vector);
+ APIC_IPI_SPINWAIT_ENTER();
while (smp_tlb_wait < ncpu)
ia32_pause();
+ APIC_IPI_SPINWAIT_EXIT();
}
/*
@@ -1021,8 +1023,10 @@
ipi_all_but_self(vector);
else
ipi_selected(mask, vector);
+ APIC_IPI_SPINWAIT_ENTER();
while (smp_tlb_wait < ncpu)
ia32_pause();
+ APIC_IPI_SPINWAIT_EXIT();
}
void
==== //depot/projects/smpng/sys/i386/i386/pmap.c#77 (text+ko) ====
@@ -1329,11 +1329,13 @@
(u_int)&pmap->pm_active);
atomic_store_rel_int(&lazywait, 0);
ipi_selected(mask, IPI_LAZYPMAP);
+ APIC_IPI_SPINWAIT_ENTER();
while (lazywait == 0) {
ia32_pause();
if (--spins == 0)
break;
}
+ APIC_IPI_SPINWAIT_EXIT();
}
mtx_unlock_spin(&smp_ipi_mtx);
if (spins == 0)
==== //depot/projects/smpng/sys/i386/include/apicvar.h#8 (text+ko) ====
@@ -133,6 +133,16 @@
#define APIC_BUS_PCI 2
#define APIC_BUS_MAX APIC_BUS_PCI
+#define APIC_IPI_SPINWAIT_ENTER() do { \
+ lapic_set_tpr(APIC_LOCK_SAFE_INTS); \
+ enable_intr(); \
+} while (0)
+
+#define APIC_IPI_SPINWAIT_EXIT() do { \
+ disable_intr(); \
+ lapic_set_tpr(0); \
+} while (0)
+
/*
* An APIC enumerator is a psuedo bus driver that enumerates APIC's including
* CPU's and I/O APIC's.
More information about the p4-projects
mailing list