diff options
Diffstat (limited to 'sys/i386/include')
-rw-r--r-- | sys/i386/include/apicvar.h | 51 | ||||
-rw-r--r-- | sys/i386/include/smp.h | 7 |
2 files changed, 44 insertions, 14 deletions
diff --git a/sys/i386/include/apicvar.h b/sys/i386/include/apicvar.h index cc46fda..a680b0d 100644 --- a/sys/i386/include/apicvar.h +++ b/sys/i386/include/apicvar.h @@ -81,22 +81,55 @@ #define APIC_IO_INTS (IDT_IO_INTS + 16) #define APIC_NUM_IOINTS 192 +/* + ********************* !!! WARNING !!! ****************************** + * Each local apic has an interrupt receive fifo that is two entries deep + * for each interrupt priority class (higher 4 bits of interrupt vector). + * Once the fifo is full the APIC can no longer receive interrupts for this + * class and sending IPIs from other CPUs will be blocked. + * To avoid deadlocks there should be no more than two IPI interrupts + * pending at the same time. + * Currently this is guaranteed by dividing the IPIs in two groups that have + * each at most one IPI interrupt pending. The first group is protected by the + * smp_ipi_mtx and waits for the completion of the IPI (Only one IPI user + * at a time) The second group uses a single interrupt and a bitmap to avoid + * redundant IPI interrupts. + * + * Right now IPI_STOP used by kdb shares the interrupt priority class with + * the two IPI groups mentioned above. As such IPI_STOP may cause a deadlock. + * Eventually IPI_STOP should use NMI IPIs - this would eliminate this and + * other deadlocks caused by IPI_STOP. + */ + #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) -#define APIC_IPI_INTS (APIC_LOCAL_INTS + 3) -#define IPI_AST APIC_IPI_INTS /* Generate software trap. */ +#if 0 +#define APIC_TIMER_INT (APIC_LOCAL_INTS + X) +#define APIC_ERROR_INT (APIC_LOCAL_INTS + X) +#define APIC_THERMAL_INT (APIC_LOCAL_INTS + X) +#endif + +#define APIC_IPI_INTS (APIC_LOCAL_INTS + 0) +#define IPI_RENDEZVOUS (APIC_IPI_INTS) /* Inter-CPU rendezvous. */ #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. */ +/* Vector to handle bitmap based IPIs */ +#define IPI_BITMAP_VECTOR (APIC_IPI_INTS + 5) +/* IPIs handled by IPI_BITMAPED_VECTOR (XXX ups is there a better place?) */ +#define IPI_AST 0 /* Generate software trap. */ +#define IPI_HARDCLOCK 1 /* Inter-CPU clock handling. */ +#define IPI_STATCLOCK 2 +#define IPI_BITMAP_LAST IPI_STATCLOCK +#define IPI_IS_BITMAPED(x) ((x) <= IPI_BITMAP_LAST) + +#define IPI_STOP (APIC_IPI_INTS + 6) /* Stop CPU until restarted. */ + +/* The spurious interrupt can share the priority class with the IPIs since + * it is not a normal interrupt. (Does not use the APIC's interrupt fifo) + */ #define APIC_SPURIOUS_INT 255 #define LVT_LINT0 0 diff --git a/sys/i386/include/smp.h b/sys/i386/include/smp.h index fe87fdf..eb6a635 100644 --- a/sys/i386/include/smp.h +++ b/sys/i386/include/smp.h @@ -55,9 +55,7 @@ inthand_t IDTVEC(invltlb), /* TLB shootdowns - global */ IDTVEC(invlpg), /* TLB shootdowns - 1 page */ IDTVEC(invlrng), /* TLB shootdowns - page range */ - IDTVEC(hardclock), /* Forward hardclock() */ - IDTVEC(statclock), /* Forward statclock() */ - IDTVEC(cpuast), /* Additional software trap on other cpu */ + IDTVEC(ipi_intr_bitmap_handler), /* Bitmap based IPIs */ IDTVEC(cpustop), /* CPU stops & waits to be restarted */ IDTVEC(rendezvous), /* handle CPU rendezvous */ IDTVEC(lazypmap); /* handle lazy pmap release */ @@ -70,9 +68,8 @@ void ipi_all(u_int ipi); void ipi_all_but_self(u_int ipi); void ipi_self(u_int ipi); void forward_statclock(void); -void forwarded_statclock(struct clockframe frame); void forward_hardclock(void); -void forwarded_hardclock(struct clockframe frame); +void ipi_bitmap_handler(struct clockframe frame); u_int mp_bootaddress(u_int); int mp_grab_cpu_hlt(void); void mp_topology(void); |