From owner-p4-projects@FreeBSD.ORG Thu Nov 11 19:15:24 2004 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 334B216A4D1; Thu, 11 Nov 2004 19:15:24 +0000 (GMT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id E4D9B16A4CE for ; Thu, 11 Nov 2004 19:15:23 +0000 (GMT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id B615743D54 for ; Thu, 11 Nov 2004 19:15:23 +0000 (GMT) (envelope-from jhb@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.11/8.12.11) with ESMTP id iABJFNVb029900 for ; Thu, 11 Nov 2004 19:15:23 GMT (envelope-from jhb@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.11/8.12.11/Submit) id iABJFNcP029897 for perforce@freebsd.org; Thu, 11 Nov 2004 19:15:23 GMT (envelope-from jhb@freebsd.org) Date: Thu, 11 Nov 2004 19:15:23 GMT Message-Id: <200411111915.iABJFNcP029897@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jhb@freebsd.org using -f From: John Baldwin To: Perforce Change Reviews Subject: PERFORCE change 64889 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 11 Nov 2004 19:15:24 -0000 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.