Date: Thu, 11 Nov 2004 17:47:35 GMT From: John Baldwin <jhb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 64883 for review Message-ID: <200411111747.iABHlZCZ026459@repoman.freebsd.org>
index | next in thread | raw e-mail
http://perforce.freebsd.org/chv.cgi?CH=64883 Change 64883 by jhb@jhb_slimer on 2004/11/11 17:47:05 - Provide a function to adjust the TPR for the current CPU. - Shuffle the IPI and local interrupts a bit so that the handlers that use spin locks (the ones related to clock) are all lower than the IPI handlers that can safely be allowed to fire while holding a spin lock. (More on this later.) Affected files ... .. //depot/projects/smpng/sys/i386/i386/local_apic.c#15 edit .. //depot/projects/smpng/sys/i386/include/apicvar.h#7 edit Differences ... ==== //depot/projects/smpng/sys/i386/i386/local_apic.c#15 (text+ko) ==== @@ -60,7 +60,8 @@ #define MAX_APICID 16 /* Sanity checks on IDT vectors. */ -CTASSERT(APIC_IO_INTS + APIC_NUM_IOINTS <= APIC_LOCAL_INTS); +CTASSERT(APIC_IO_INTS + APIC_NUM_IOINTS == APIC_CLOCK_INTS); +CTASSERT(APIC_CLOCK_INTS == 240); CTASSERT(IPI_STOP < APIC_SPURIOUS_INT); /* @@ -264,10 +265,8 @@ /* XXX: more LVT entries */ - /* Clear the TPR. */ - value = lapic->tpr; - value &= ~APIC_TPR_PRIO; - lapic->tpr = value; + /* Initialize the TPR to allow all interrupts. */ + lapic_set_tpr(0); /* Use the cluster model for logical IDs. */ value = lapic->dfr; @@ -472,6 +471,24 @@ return (0); } +/* + * Adjust the TPR of the current CPU so that it blocks all interrupts below + * the passed in vector. + */ +void +lapic_set_tpr(u_int vector) +{ +#ifdef CHEAP_TPR + lapic->tpr = vector; +#else + u_int32_t tpr; + + tpr = lapic->tpr & ~APIC_TPR_PRIO; + tpr |= vector; + lapic->tpr = tpr; +#endif +} + void lapic_eoi(void) { @@ -637,10 +654,9 @@ #ifdef SMP /* * Inter Processor Interrupt functions. The lapic_ipi_*() functions are - * private the sys/i386 code. The public interface for the rest of the + * private to the sys/i386 code. The public interface for the rest of the * kernel is defined in mp_machdep.c. */ - int lapic_ipi_wait(int delay) { ==== //depot/projects/smpng/sys/i386/include/apicvar.h#7 (text+ko) ==== @@ -78,24 +78,38 @@ */ #define APIC_ID_ALL 0xff + +/* I/O Interrupts are used for external devices such as ISA, PCI, etc. */ #define APIC_IO_INTS (IDT_IO_INTS + 16) #define APIC_NUM_IOINTS 192 -#define APIC_LOCAL_INTS 240 -#define APIC_TIMER_INT APIC_LOCAL_INTS -#define APIC_ERROR_INT (APIC_LOCAL_INTS + 1) -#define APIC_THERMAL_INT (APIC_LOCAL_INTS + 2) +/* Clock interrupts are used for clock handling and drive hardclock, etc. */ +#define APIC_CLOCK_INTS (APIC_IO_INTS + APIC_NUM_IOINTS) +#define APIC_TIMER_INT APIC_CLOCK_INTS +#define IPI_HARDCLOCK (APIC_CLOCK_INTS + 1) /* Inter-CPU clock handling. */ +#define IPI_STATCLOCK (APIC_CLOCK_INTS + 2) + +/* + * These interrupt handlers are for IPIs and local interrupts whose handlers + * do not use any spin locks, so they may still be allowed when a spin lock + * is held. + */ +#define APIC_LOCK_SAFE_INTS (APIC_CLOCK_INTS + 3) + +/* Interrupts for local APIC LVT entries other than the timer. */ +#define APIC_LOCAL_INTS APIC_LOCK_SAFE_INTS +#define APIC_ERROR_INT APIC_LOCAL_INTS +#define APIC_THERMAL_INT (APIC_LOCAL_INTS + 1) -#define APIC_IPI_INTS (APIC_LOCAL_INTS + 3) +/* Spin lock safe IPIs. */ +#define APIC_IPI_INTS (APIC_LOCAL_INTS + 2) #define IPI_AST APIC_IPI_INTS /* Generate software trap. */ #define IPI_INVLTLB (APIC_IPI_INTS + 1) /* TLB Shootdown IPIs */ #define IPI_INVLPG (APIC_IPI_INTS + 2) #define IPI_INVLRNG (APIC_IPI_INTS + 3) #define IPI_LAZYPMAP (APIC_IPI_INTS + 4) /* Lazy pmap release. */ -#define IPI_HARDCLOCK (APIC_IPI_INTS + 8) /* Inter-CPU clock handling. */ -#define IPI_STATCLOCK (APIC_IPI_INTS + 9) -#define IPI_RENDEZVOUS (APIC_IPI_INTS + 10) /* Inter-CPU rendezvous. */ -#define IPI_STOP (APIC_IPI_INTS + 11) /* Stop CPU until restarted. */ +#define IPI_RENDEZVOUS (APIC_IPI_INTS + 5) /* Inter-CPU rendezvous. */ +#define IPI_STOP (APIC_IPI_INTS + 6) /* Stop CPU until restarted. */ #define APIC_SPURIOUS_INT 255 @@ -173,6 +187,7 @@ enum intr_polarity pol); int lapic_set_lvt_triggermode(u_int apic_id, u_int lvt, enum intr_trigger trigger); +void lapic_set_tpr(u_int vector); void lapic_setup(void); #endif /* !LOCORE */help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200411111747.iABHlZCZ026459>
