[PATCH] Only scan the root bus in early PCI quirks.

From: Andi Kleen
Date: Tue Dec 16 2008 - 09:26:42 EST


Only scan the root bus in early PCI quirks.

We found a situation on Linus' machine that the Nvidia timer
quirk hit on a Intel chipset system. The problem is that the
system has a fancy Nvidia card with an own PCI bridge, and
the early-quirks code looking for any NVidia bridge triggered
on it incorrectly. This didn't lead a boot failure by luck,
but the timer routing code selecting the wrong timer first and
some ugly messages. It might lead to real problems on
other systems.

Update: according to Suresh the problem can cause real boot failures
together with x2apic.

I checked all the devices which are currently checked for
by early_quirks and it turns out they are all located in
the root bus zero.

So change the early-quirks loop to only scan bus 0. This
incidently also saves quite some unnecessary scanning work,
because early_quirks doesn't go through all the non root
busses. I don't expect that it will make the boot visible
faster, but doing less work is still good.

The graphics card is not on bus 0, so it is not matched
anymore.

Cc: youquan.song@xxxxxxxxx
Cc: suresh.b.siddha@xxxxxxxxx

Signed-off-by: Andi Kleen <ak@xxxxxxxxxxxxxxx>

---
arch/x86/kernel/early-quirks.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)

Index: linux-2.6.28-rc4-test/arch/x86/kernel/early-quirks.c
===================================================================
--- linux-2.6.28-rc4-test.orig/arch/x86/kernel/early-quirks.c 2008-10-24 13:34:40.000000000 +0200
+++ linux-2.6.28-rc4-test/arch/x86/kernel/early-quirks.c 2008-12-16 15:23:07.000000000 +0100
@@ -214,6 +214,12 @@
void (*f)(int num, int slot, int func);
};

+/*
+ * Only works for devices on the root bus. If you add any devices
+ * not on bus 0 readd another loop level in early_quirks(). But
+ * be careful because at least the Nvidia quirk here relies on
+ * only matching on bus 0.
+ */
static struct chipset early_qrk[] __initdata = {
{ PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
PCI_CLASS_BRIDGE_PCI, PCI_ANY_ID, QFLAG_APPLY_ONCE, nvidia_bugs },
@@ -284,17 +290,17 @@

void __init early_quirks(void)
{
- int num, slot, func;
+ int slot, func;

if (!early_pci_allowed())
return;

/* Poor man's PCI discovery */
- for (num = 0; num < 32; num++)
- for (slot = 0; slot < 32; slot++)
- for (func = 0; func < 8; func++) {
- /* Only probe function 0 on single fn devices */
- if (check_dev_quirk(num, slot, func))
- break;
- }
+ /* Only scan the root bus */
+ for (slot = 0; slot < 32; slot++)
+ for (func = 0; func < 8; func++) {
+ /* Only probe function 0 on single fn devices */
+ if (check_dev_quirk(0, slot, func))
+ break;
+ }
}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/