diff --git a/sys/amd64/amd64/intr_machdep.c b/sys/amd64/amd64/intr_machdep.c index 447bbb96360..ffd0701bf27 100644 --- a/sys/amd64/amd64/intr_machdep.c +++ b/sys/amd64/amd64/intr_machdep.c @@ -52,6 +52,7 @@ #include #include #include +#include #ifdef DDB #include #endif @@ -429,8 +430,9 @@ DB_SHOW_COMMAND(irqs, db_show_irqs) * allocate CPUs round-robin. */ -static u_int cpu_apic_ids[MAXCPU]; -static int current_cpu, num_cpus; +/* The BSP is always a valid target. */ +static cpumask_t intr_cpus = (1 << 0); +static int current_cpu, num_cpus = 1; static void intr_assign_next_cpu(struct intsrc *isrc) @@ -443,25 +445,29 @@ intr_assign_next_cpu(struct intsrc *isrc) */ pic = isrc->is_pic; apic_id = cpu_apic_ids[current_cpu]; - current_cpu++; - if (current_cpu >= num_cpus) - current_cpu = 0; pic->pic_assign_cpu(isrc, apic_id); + do { + current_cpu++; + if (current_cpu >= num_cpus) + current_cpu = 0; + } while (!(intr_cpus & (1 << current_cpu))); } /* - * Add a local APIC ID to our list of valid local APIC IDs that can - * be destinations of interrupts. + * Add a CPU to our mask of valid CPUs that can be destinations of + * interrupts. */ void -intr_add_cpu(u_int apic_id) +intr_add_cpu(u_int cpu) { + if (cpu >= MAXCPU) + panic("%s: Invalid CPU ID", __func__); if (bootverbose) - printf("INTR: Adding local APIC %d as a target\n", apic_id); - if (num_cpus >= MAXCPU) - panic("WARNING: Local APIC IDs exhausted!"); - cpu_apic_ids[num_cpus] = apic_id; + printf("INTR: Adding local APIC %d as a target\n", + cpu_apic_ids[cpu]); + + intr_cpus |= (1 << cpu); num_cpus++; } diff --git a/sys/amd64/amd64/local_apic.c b/sys/amd64/amd64/local_apic.c index bc2f337aff0..0fe1ffe9f2c 100644 --- a/sys/amd64/amd64/local_apic.c +++ b/sys/amd64/amd64/local_apic.c @@ -220,7 +220,6 @@ lapic_init(vm_paddr_t addr) /* Set BSP's per-CPU local APIC ID. */ PCPU_SET(apic_id, lapic_id()); - intr_add_cpu(PCPU_GET(apic_id)); /* Local APIC timer interrupt. */ setidt(APIC_TIMER_INT, IDTVEC(timerint), SDT_SYSIGT, SEL_KPL, 0); diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index 0a0342e8b25..ce001ba1542 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -152,7 +152,7 @@ struct cpu_info { int cpu_bsp:1; int cpu_disabled:1; } static cpu_info[MAXCPU]; -static int cpu_apic_ids[MAXCPU]; +int cpu_apic_ids[MAXCPU]; /* Holds pending bitmap based IPIs per CPU */ static volatile u_int cpu_ipi_pending[MAXCPU]; @@ -625,10 +625,11 @@ init_secondary(void) static void set_interrupt_apic_ids(void) { - u_int apic_id; + u_int i, apic_id; - for (apic_id = 0; apic_id < MAXCPU; apic_id++) { - if (!cpu_info[apic_id].cpu_present) + for (i = 0; i < MAXCPU; i++) { + apic_id = cpu_apic_ids[i]; + if (apic_id == -1) continue; if (cpu_info[apic_id].cpu_bsp) continue; @@ -640,7 +641,7 @@ set_interrupt_apic_ids(void) apic_id % hyperthreading_cpus != 0) continue; - intr_add_cpu(apic_id); + intr_add_cpu(i); } } diff --git a/sys/amd64/include/intr_machdep.h b/sys/amd64/include/intr_machdep.h index fd481b0c76e..7853f4f4006 100644 --- a/sys/amd64/include/intr_machdep.h +++ b/sys/amd64/include/intr_machdep.h @@ -131,9 +131,7 @@ enum intr_trigger elcr_read_trigger(u_int irq); void elcr_resume(void); void elcr_write_trigger(u_int irq, enum intr_trigger trigger); #ifdef SMP -void intr_add_cpu(u_int apic_id); -#else -#define intr_add_cpu(apic_id) +void intr_add_cpu(u_int cpu); #endif int intr_add_handler(const char *name, int vector, driver_filter_t filter, driver_intr_t handler, void *arg, enum intr_type flags, diff --git a/sys/amd64/include/smp.h b/sys/amd64/include/smp.h index 5a2d3aab956..eb3e0914af4 100644 --- a/sys/amd64/include/smp.h +++ b/sys/amd64/include/smp.h @@ -34,6 +34,7 @@ extern int mp_naps; extern int boot_cpu_id; extern struct pcb stoppcbs[]; extern struct mtx smp_tlb_mtx; +extern int cpu_apic_ids[]; /* IPI handlers */ inthand_t diff --git a/sys/i386/i386/intr_machdep.c b/sys/i386/i386/intr_machdep.c index c505984cba7..ee34570ba72 100644 --- a/sys/i386/i386/intr_machdep.c +++ b/sys/i386/i386/intr_machdep.c @@ -51,6 +51,7 @@ #include #include #include +#include #ifdef DDB #include #endif @@ -395,8 +396,9 @@ DB_SHOW_COMMAND(irqs, db_show_irqs) * allocate CPUs round-robin. */ -static u_int cpu_apic_ids[MAXCPU]; -static int current_cpu, num_cpus; +/* The BSP is always a valid target. */ +static cpumask_t intr_cpus = (1 << 0); +static int current_cpu, num_cpus = 1; static void intr_assign_next_cpu(struct intsrc *isrc) @@ -409,25 +411,29 @@ intr_assign_next_cpu(struct intsrc *isrc) */ pic = isrc->is_pic; apic_id = cpu_apic_ids[current_cpu]; - current_cpu++; - if (current_cpu >= num_cpus) - current_cpu = 0; pic->pic_assign_cpu(isrc, apic_id); + do { + current_cpu++; + if (current_cpu >= num_cpus) + current_cpu = 0; + } while (!(intr_cpus & (1 << current_cpu))); } /* - * Add a local APIC ID to our list of valid local APIC IDs that can - * be destinations of interrupts. + * Add a CPU to our mask of valid CPUs that can be destinations of + * interrupts. */ void -intr_add_cpu(u_int apic_id) +intr_add_cpu(u_int cpu) { + if (cpu >= MAXCPU) + panic("%s: Invalid CPU ID", __func__); if (bootverbose) - printf("INTR: Adding local APIC %d as a target\n", apic_id); - if (num_cpus >= MAXCPU) - panic("WARNING: Local APIC IDs exhausted!"); - cpu_apic_ids[num_cpus] = apic_id; + printf("INTR: Adding local APIC %d as a target\n", + cpu_apic_ids[cpu]); + + intr_cpus |= (1 << cpu); num_cpus++; } diff --git a/sys/i386/i386/local_apic.c b/sys/i386/i386/local_apic.c index ea27aa2c78f..6b6d5613df1 100644 --- a/sys/i386/i386/local_apic.c +++ b/sys/i386/i386/local_apic.c @@ -221,7 +221,6 @@ lapic_init(vm_paddr_t addr) /* Set BSP's per-CPU local APIC ID. */ PCPU_SET(apic_id, lapic_id()); - intr_add_cpu(PCPU_GET(apic_id)); /* Local APIC timer interrupt. */ setidt(APIC_TIMER_INT, IDTVEC(timerint), SDT_SYS386IGT, SEL_KPL, diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c index 3ca9bcf8609..7fa94581c71 100644 --- a/sys/i386/i386/mp_machdep.c +++ b/sys/i386/i386/mp_machdep.c @@ -209,7 +209,7 @@ struct cpu_info { int cpu_bsp:1; int cpu_disabled:1; } static cpu_info[MAXCPU]; -static int cpu_apic_ids[MAXCPU]; +int cpu_apic_ids[MAXCPU]; /* Holds pending bitmap based IPIs per CPU */ static volatile u_int cpu_ipi_pending[MAXCPU]; @@ -668,10 +668,11 @@ init_secondary(void) static void set_interrupt_apic_ids(void) { - u_int apic_id; + u_int i, apic_id; - for (apic_id = 0; apic_id < MAXCPU; apic_id++) { - if (!cpu_info[apic_id].cpu_present) + for (i = 0; i < MAXCPU; i++) { + apic_id = cpu_apic_ids[i]; + if (apic_id == -1) continue; if (cpu_info[apic_id].cpu_bsp) continue; @@ -683,7 +684,7 @@ set_interrupt_apic_ids(void) apic_id % hyperthreading_cpus != 0) continue; - intr_add_cpu(apic_id); + intr_add_cpu(i); } } diff --git a/sys/i386/include/intr_machdep.h b/sys/i386/include/intr_machdep.h index 253027e15bb..8d36436f2cf 100644 --- a/sys/i386/include/intr_machdep.h +++ b/sys/i386/include/intr_machdep.h @@ -128,9 +128,7 @@ enum intr_trigger elcr_read_trigger(u_int irq); void elcr_resume(void); void elcr_write_trigger(u_int irq, enum intr_trigger trigger); #ifdef SMP -void intr_add_cpu(u_int apic_id); -#else -#define intr_add_cpu(apic_id) +void intr_add_cpu(u_int cpu); #endif int intr_add_handler(const char *name, int vector, driver_filter_t filter, driver_intr_t handler, void *arg, enum intr_type flags, void **cookiep); diff --git a/sys/i386/include/smp.h b/sys/i386/include/smp.h index 6451a5c2a98..7116b43c3d3 100644 --- a/sys/i386/include/smp.h +++ b/sys/i386/include/smp.h @@ -35,6 +35,7 @@ extern int mp_naps; extern int boot_cpu_id; extern struct pcb stoppcbs[]; extern struct mtx smp_tlb_mtx; +extern int cpu_apic_ids[]; #ifdef COUNT_IPIS extern u_long *ipi_invltlb_counts[MAXCPU]; extern u_long *ipi_invlrng_counts[MAXCPU];