PERFORCE change 64883 for review

John Baldwin jhb at FreeBSD.org
Thu Nov 11 09:47:36 PST 2004


http://perforce.freebsd.org/chv.cgi?CH=64883

Change 64883 by jhb at 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 */


More information about the p4-projects mailing list