lkml.org 
[lkml]   [2002]   [Jan]   [18]   [last100]   RSS Feed
Views: [more markup]  [less markup]  [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
FromJames Cleverdon <>
SubjectRe: [PATCH] MAX_MP_BUSSES increase
DateFri, 18 Jan 2002 13:21:17 -0800
On Tuesday 08 January 2002 01:41 am, Martin J. Bligh wrote:
> > There's a problem with that -- despite its name, CONFIG_MULTIQUAD is used
> > for the old NUMA-Q hardware.  It turns on some memory mapped port I/O
> > code that doesn't have any purpose for other machines.  The PCI bus
> > overflow happens on our new Foster-based boxes that may or may not
> > contain multiple quad CPU boards.
> >
> > Still, CONFIG_MULTIQUAD is better than nothing.  It just may take a
> > little bit of redefinition, so long as we can coax the various distros to
> > build their installation and working kernels with CONFIG_MULTIQUAD turned
> > on....
>
> That's not a good idea. You're going to introduce extra switches to every
> port IO path, and every IPI (for everybody, not just yourself).
> CONFIG_MULTIQUAD is also used to alter the way that PCI config space writes
> are done (in later patches). I suggest you use a different config option,
> or construct it dynamically.
>
> Martin.

OK, I've thrown together an attempt at dynamic table allocation that works on 
the boxes with all the busses.  For safety's sake I keep the static tables 
and only reallocate if they overflow:

diff -ru 2.4.17/arch/i386/kernel/mpparse.c test/arch/i386/kernel/mpparse.c
--- 2.4.17/arch/i386/kernel/mpparse.c	Fri Nov  9 17:58:18 2001
+++ test/arch/i386/kernel/mpparse.c	Fri Jan 18 13:12:46 2002
@@ -35,16 +35,22 @@
  * MP-table.
  */
 int apic_version [MAX_APICS];
-int mp_bus_id_to_type [MAX_MP_BUSSES];
-int mp_bus_id_to_node [MAX_MP_BUSSES];
-int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
+int static_mp_bus_id_to_type[MAX_MP_BUSSES];
+int static_mp_bus_id_to_node[MAX_MP_BUSSES];
+int static_mp_bus_id_to_pci_bus[MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = 
-1 };
+int *mp_bus_id_to_type = static_mp_bus_id_to_type;
+int *mp_bus_id_to_node = static_mp_bus_id_to_node;
+int *mp_bus_id_to_pci_bus = static_mp_bus_id_to_pci_bus;
+int max_mp_busses = MAX_MP_BUSSES;
+int max_irq_sources = MAX_IRQ_SOURCES;
 int mp_current_pci_id;
 
 /* I/O APIC entries */
 struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS];
 
 /* # of MP IRQ source entries */
-struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
+struct mpc_config_intsrc static_mp_irqs[MAX_IRQ_SOURCES];
+struct mpc_config_intsrc *mp_irqs = static_mp_irqs;
 
 /* MP IRQ source entries */
 int mp_irq_entries;
@@ -219,6 +225,7 @@
 	if (m->mpc_apicid > MAX_APICS) {
 		printk("Processor #%d INVALID. (Max ID: %d).\n",
 			m->mpc_apicid, MAX_APICS);
+		--num_processors;
 		return;
 	}
 	ver = m->mpc_apicver;
@@ -296,7 +303,7 @@
 			m->mpc_irqtype, m->mpc_irqflag & 3,
 			(m->mpc_irqflag >> 2) & 3, m->mpc_srcbus,
 			m->mpc_srcbusirq, m->mpc_dstapic, m->mpc_dstirq);
-	if (++mp_irq_entries == MAX_IRQ_SOURCES)
+	if (++mp_irq_entries == max_irq_sources)
 		panic("Max # of irq sources exceeded!!\n");
 }
 
@@ -385,6 +392,7 @@
 
 static int __init smp_read_mpc(struct mp_config_table *mpc)
 {
+	int num_bus, num_irq;
 	char str[16];
 	int count=sizeof(*mpc);
 	unsigned char *mpt=((unsigned char *)mpc)+count;
@@ -434,6 +442,76 @@
 	}
 
 	/*
+	 * Pre-scan to see if the bus and interrupt records are too big to fit
+	 * in the static tables.  If so, then alloc bigger ones.
+	 */
+    {
+	int cnt = count;
+	unsigned char *mpp = mpt;
+	size_t size;
+
+	num_bus = 0;
+	num_irq = 0;
+	while (cnt < mpc->mpc_length) {
+		switch (*mpp) {
+			case MP_PROCESSOR:
+				size = sizeof(struct mpc_config_processor);
+				break;
+			case MP_BUS:
+				++num_bus;
+				size = sizeof(struct mpc_config_bus);
+				break;
+			case MP_INTSRC:
+				++num_irq;
+				size = sizeof(struct mpc_config_intsrc);
+				break;
+			case MP_IOAPIC:
+				size = sizeof(struct mpc_config_ioapic);
+				break;
+			case MP_LINTSRC:
+				size = sizeof(struct mpc_config_lintsrc);
+				break;
+			default:
+				cnt = mpc->mpc_length;
+				size = 0;
+				break;
+		}
+		mpp += size;
+		cnt += size;
+	}
+	if (num_bus > MAX_MP_BUSSES || num_irq >= MAX_IRQ_SOURCES) {
+		unsigned char *up;
+
+		/* Paranoia: Alloc one extra of each. */
+		max_mp_busses = ++num_bus;
+		if (num_irq < 4 * num_bus)
+			num_irq = 4 * num_bus;	/* 4 intr/PCI slot */
+		max_irq_sources = ++num_irq;
+		num_bus *= sizeof(int);
+		cnt = 3 * num_bus;
+		num_irq *= sizeof(struct mpc_config_intsrc);
+		cnt += num_irq;
+		up = alloc_bootmem(cnt);
+		if (!up) {
+			printk("smp_read_mpc: Bus/Intr table realloc (%d "
+				"bytes) failed!  MPS records will be lost!\n",
+				cnt);
+		} else {
+			mp_bus_id_to_type = (int *)up;
+			up += num_bus;
+			mp_bus_id_to_node = (int *)up;
+			up += num_bus;
+			mp_bus_id_to_pci_bus = (int *)up;
+			up += num_bus;
+			mp_irqs = (struct mpc_config_intsrc *)up;
+			memset(mp_bus_id_to_pci_bus, -1, num_bus);
+		}
+	}
+	num_bus = 0;
+	num_irq = 0;
+    }
+
+	/*
 	 *	Now process the configuration blocks.
 	 */
 	while (count < mpc->mpc_length) {
@@ -454,7 +532,11 @@
 			{
 				struct mpc_config_bus *m=
 					(struct mpc_config_bus *)mpt;
-				MP_bus_info(m);
+				if (++num_bus < max_mp_busses)
+					MP_bus_info(m);
+				else
+					printk("Dropped bus #%d (%.6s)!\n",
+						m->mpc_busid, m->mpc_bustype);
 				mpt += sizeof(*m);
 				count += sizeof(*m);
 				break;
@@ -473,7 +555,12 @@
 				struct mpc_config_intsrc *m=
 					(struct mpc_config_intsrc *)mpt;
 
-				MP_intsrc_info(m);
+				if (++num_irq < max_irq_sources)
+					MP_intsrc_info(m);
+				else
+					printk("Dropped intsrc! (%d, %d, %02x, %d)\n",
+						m->mpc_srcbus, m->mpc_srcbusirq,
+						m->mpc_dstapic, m->mpc_dstirq);
 				mpt+=sizeof(*m);
 				count+=sizeof(*m);
 				break;
diff -ru 2.4.17/include/asm-i386/io_apic.h test/include/asm-i386/io_apic.h
--- 2.4.17/include/asm-i386/io_apic.h	Wed Jan  9 15:58:47 2002
+++ test/include/asm-i386/io_apic.h	Fri Jan 18 13:10:31 2002
@@ -96,7 +96,7 @@
 extern int mp_irq_entries;
 
 /* MP IRQ source entries */
-extern struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
+extern struct mpc_config_intsrc *mp_irqs;
 
 /* non-0 if default (table-less) MP configuration */
 extern int mpc_default_type;
diff -ru 2.4.17/include/asm-i386/mpspec.h test/include/asm-i386/mpspec.h
--- 2.4.17/include/asm-i386/mpspec.h	Wed Jan  9 15:58:47 2002
+++ test/include/asm-i386/mpspec.h	Fri Jan 18 13:10:31 2002
@@ -197,8 +197,8 @@
 	MP_BUS_PCI,
 	MP_BUS_MCA
 };
-extern int mp_bus_id_to_type [MAX_MP_BUSSES];
-extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES];
+extern int *mp_bus_id_to_type;
+extern int *mp_bus_id_to_pci_bus;
 
 extern unsigned int boot_cpu_physical_apicid;
 extern unsigned long phys_cpu_present_map;
@@ -207,11 +207,11 @@
 extern void get_smp_config (void);
 extern int nr_ioapics;
 extern int apic_version [MAX_APICS];
-extern int mp_bus_id_to_type [MAX_MP_BUSSES];
+extern int *mp_bus_id_to_type;
 extern int mp_irq_entries;
-extern struct mpc_config_intsrc mp_irqs [MAX_IRQ_SOURCES];
+extern struct mpc_config_intsrc *mp_irqs;
 extern int mpc_default_type;
-extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES];
+extern int *mp_bus_id_to_pci_bus;
 extern int mp_current_pci_id;
 extern unsigned long mp_lapic_addr;
 extern int pic_mode;

-- 
James Cleverdon, IBM xSeries Platform (NUMA), Beaverton
jamesclv@us.ibm.com   |   cleverdj@us.ibm.com
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 12:15    [from the cache]
©2003-2008