Skip to contentSkip to conversation

Dynamic irq_vector allocation for 2.6.0-test6-mm

PATCH In review James Cleverdon 2 participants 3 messages Oct 4, 2003 – Oct 6, 2003

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Dynamic irq_vector allocation for 2.6.0-test6-mm

irq_vector is indexed by a value that can be as large as the sum of all the RTEs in all the I/O APICs. On a 32-way x445 or a 16-way x440 with PCI expansion boxes, the static array will overflow.

Type changed to u8 because that's how big a vector number is. That should please the embedded folks.

Because the fixmaps for I/O APICs aren't ready, I had to map them myself.

Signature · 3 lines
James Cleverdon
IBM xSeries Linux Solutions
{jamesclv(Unix, preferred), cleverdj(Notes)} at us dot ibm dot comm
arch/i386/kernel/io_apic.c +3 -2
diff -pru 2.6.0-test6-mm1/arch/i386/kernel/io_apic.c k6/arch/i386/kernel/io_apic.c
@@ -1138,12 +1138,13 @@ static inline int IO_APIC_irq_trigger(in
 	return 0;
 }
 
-int irq_vector[NR_IRQS] = { FIRST_DEVICE_VECTOR , 0 };
+u8 *irq_vector;
+int nr_irqs;
 
 static int __init assign_irq_vector(int irq)
 {
 	static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
-	BUG_ON(irq >= NR_IRQS);
+	BUG_ON(irq >= nr_irqs);
 	if (IO_APIC_VECTOR(irq) > 0)
 		return IO_APIC_VECTOR(irq);
 next:
arch/i386/kernel/mpparse.c +28 -0
diff -pru 2.6.0-test6-mm1/arch/i386/kernel/mpparse.c k6/arch/i386/kernel/mpparse.c
@@ -616,6 +616,31 @@ static inline void __init construct_defa
 	}
 }
 
+#ifdef CONFIG_X86_IO_APIC
+/* irq_vector must be have an entry for all RTEs of all I/O APICs. */
+void __init alloc_irq_vector_array(void)
+{
+	int	total = 0;
+	int	idx;
+	union IO_APIC_reg_01	reg_01;
+
+	/* The I/O APIC fixmaps aren't inited yet, so use the first one. */
+	for (idx = 0; idx < nr_ioapics; idx++) {
+		set_fixmap_nocache(FIX_IO_APIC_BASE_0, mp_ioapics[idx].mpc_apicaddr);
+		reg_01.raw = io_apic_read(0, 1);
+		total += reg_01.bits.entries + 1;
+	}
+
+	/* Always alloc at least NR_IRQS vectors. */
+	nr_irqs = max(total, NR_IRQS);
+	irq_vector = (u8 *) alloc_bootmem(nr_irqs);
+	memset(irq_vector, 0, nr_irqs);
+	irq_vector[0] = FIRST_DEVICE_VECTOR;
+}
+#else
+void __init alloc_irq_vector_array(void) { }
+#endif /* CONFIG_X86_IO_APIC */
+
 static struct intel_mp_floating *mpf_found;
 
 /*
@@ -633,6 +658,7 @@ void __init get_smp_config (void)
 	 */
 	if (acpi_lapic && acpi_ioapic) {
 		printk(KERN_INFO "Using ACPI (MADT) for SMP configuration information\n");
+		alloc_irq_vector_array();
 		return;
 	}
 	else if (acpi_lapic)
@@ -665,6 +691,7 @@ void __init get_smp_config (void)
 			smp_found_config = 0;
 			printk(KERN_ERR "BIOS bug, MP table errors detected!...\n");
 			printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n");
+			alloc_irq_vector_array();
 			return;
 		}
 		/*
@@ -688,6 +715,7 @@ void __init get_smp_config (void)
 	} else
 		BUG();
 
+	alloc_irq_vector_array();
 	printk(KERN_INFO "Processors: %d\n", num_processors);
 	/*
 	 * Only use the first configuration found.
include/asm-i386/hw_irq.h +3 -2
diff -pru 2.6.0-test6-mm1/include/asm-i386/hw_irq.h k6/include/asm-i386/hw_irq.h
@@ -25,8 +25,9 @@
  * Interrupt entry/exit code at both C and assembly level
  */
 
-extern int irq_vector[NR_IRQS];
-#define IO_APIC_VECTOR(irq)	irq_vector[irq]
+extern u8 *irq_vector;
+#define IO_APIC_VECTOR(irq)	((int)irq_vector[(irq)])
+extern int nr_irqs;
 
 extern void (*interrupt[NR_IRQS])(void);
 
#1 lore raw
Quoted 3 lines · James Cleverdon

irq_vector is indexed by a value that can be as large as the sum of all the RTEs in all the I/O APICs. On a 32-way x445 or a 16-way x440 with PCI expansion boxes, the static array will overflow.

What is number of interrupt sources on that 32x?

#2 lore raw
Quoted 6 lines · Zwane Mwaikambo
Quoted 3 lines · James Cleverdon

irq_vector is indexed by a value that can be as large as the sum of all the RTEs in all the I/O APICs. On a 32-way x445 or a 16-way x440 with PCI expansion boxes, the static array will overflow.

What is number of interrupt sources on that 32x?

That depends on the number of PCI cards plugged into the slots and how many of the four interrupt lines (/INTA - /INTD) are used.

However it doesn't matter. Even if no cards are present, the array will still overflow because the I/O APIC init routines assign a vector to each RTE and run off the end of irq_vector.

Signature · 3 lines
James Cleverdon
IBM xSeries Linux Solutions
{jamesclv(Unix, preferred), cleverdj(Notes)} at us dot ibm dot comm