Date: Thu, 11 Nov 2004 19:15:23 GMT From: John Baldwin <jhb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 64889 for review Message-ID: <200411111915.iABJFNcP029897@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=64889 Change 64889 by jhb@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.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200411111915.iABJFNcP029897>