public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [patch 0/4] i386, x86_64: fix the irqbalance quirk for E7520/E7320/E7525 - V2
@ 2006-11-09  1:20 Siddha, Suresh B
  2006-11-09  1:23 ` [patch 1/4] i386: add write_pci_config_byte() to direct PCI access routines Siddha, Suresh B
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Siddha, Suresh B @ 2006-11-09  1:20 UTC (permalink / raw)
  To: ak, akpm
  Cc: shaohua.li, linux-kernel, discuss, ashok.raj, suresh.b.siddha,
	greg

Mechanism of selecting physical mode in genapic when cpu hotplug is enabled
on x86_64, broke the quirk(quirk_intel_irqbalance()) introduced for working
around the transposing interrupt message errata in E7520/E7320/E7525
(revision ID 0x9 and below. errata #23 in 
http://download.intel.com/design/chipsets/specupdt/30304203.pdf).

This errata requires the mode to be in logical flat, so that interrupts
can be directed to more than one cpu(and thus use hardware IRQ balancing
enabled by BIOS on these platforms).

Following four patches fixes this by moving the quirk to early quirk
and forcing the x86_64 genapic selection to logical flat on these platforms.

Thanks to Shaohua for pointing out the breakage.

Changes in V2:
- Fix compilation breakages
- ifdef and variable name cleanups

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [patch 1/4] i386: add write_pci_config_byte() to direct PCI access routines
  2006-11-09  1:20 [patch 0/4] i386, x86_64: fix the irqbalance quirk for E7520/E7320/E7525 - V2 Siddha, Suresh B
@ 2006-11-09  1:23 ` Siddha, Suresh B
  2006-11-09  1:27 ` [patch 2/4] i386: introduce the mechanism of disabling cpu hotplug control Siddha, Suresh B
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Siddha, Suresh B @ 2006-11-09  1:23 UTC (permalink / raw)
  To: ak, akpm
  Cc: shaohua.li, linux-kernel, discuss, ashok.raj, suresh.b.siddha,
	greg

Add write_pci_config_byte() to direct PCI access  routines

Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
---

diff --git a/arch/i386/pci/early.c b/arch/i386/pci/early.c
index 713d6c8..42df4b6 100644
--- a/arch/i386/pci/early.c
+++ b/arch/i386/pci/early.c
@@ -45,6 +45,13 @@ void write_pci_config(u8 bus, u8 slot, u
 	outl(val, 0xcfc);
 }
 
+void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val)
+{
+	PDprintk("%x writing to %x: %x\n", slot, offset, val);
+	outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
+	outb(val, 0xcfc);
+}
+
 int early_pci_allowed(void)
 {
 	return (pci_probe & (PCI_PROBE_CONF1|PCI_PROBE_NOEARLY)) ==
diff --git a/include/asm-x86_64/pci-direct.h b/include/asm-x86_64/pci-direct.h
index eba9cb4..6823fa4 100644
--- a/include/asm-x86_64/pci-direct.h
+++ b/include/asm-x86_64/pci-direct.h
@@ -10,6 +10,7 @@ extern u32 read_pci_config(u8 bus, u8 sl
 extern u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset);
 extern u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset);
 extern void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, u32 val);
+extern void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val);
 
 extern int early_pci_allowed(void);
 

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [patch 2/4] i386: introduce the mechanism of disabling cpu hotplug control
  2006-11-09  1:20 [patch 0/4] i386, x86_64: fix the irqbalance quirk for E7520/E7320/E7525 - V2 Siddha, Suresh B
  2006-11-09  1:23 ` [patch 1/4] i386: add write_pci_config_byte() to direct PCI access routines Siddha, Suresh B
@ 2006-11-09  1:27 ` Siddha, Suresh B
  2006-11-09  1:29 ` [patch 3/4] x86_64: add genapic_force Siddha, Suresh B
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Siddha, Suresh B @ 2006-11-09  1:27 UTC (permalink / raw)
  To: ak, akpm
  Cc: shaohua.li, linux-kernel, discuss, ashok.raj, suresh.b.siddha,
	greg

Add 'enable_cpu_hotplug' flag and when cleared, the hotplug control file
("online") will not be added under /sys/devices/system/cpu/cpuX/

Next patch doing PCI quirks will use this.

Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
---

diff --git a/arch/i386/kernel/topology.c b/arch/i386/kernel/topology.c
index 07d6da3..844c08f 100644
--- a/arch/i386/kernel/topology.c
+++ b/arch/i386/kernel/topology.c
@@ -40,14 +40,18 @@ int arch_register_cpu(int num)
 	 * restrictions and assumptions in kernel. This basically
 	 * doesnt add a control file, one cannot attempt to offline
 	 * BSP.
+	 *
+	 * Also certain PCI quirks require not to enable hotplug control
+	 * for all CPU's.
 	 */
-	if (!num)
+	if (!num || !enable_cpu_hotplug)
 		cpu_devices[num].cpu.no_control = 1;
 
 	return register_cpu(&cpu_devices[num].cpu, num);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
+int enable_cpu_hotplug = 1;
 
 void arch_unregister_cpu(int num) {
 	return unregister_cpu(&cpu_devices[num].cpu);
diff --git a/include/asm-i386/cpu.h b/include/asm-i386/cpu.h
index b1bc7b1..9d914e1 100644
--- a/include/asm-i386/cpu.h
+++ b/include/asm-i386/cpu.h
@@ -13,6 +13,9 @@ struct i386_cpu {
 extern int arch_register_cpu(int num);
 #ifdef CONFIG_HOTPLUG_CPU
 extern void arch_unregister_cpu(int);
+extern int enable_cpu_hotplug;
+#else
+#define enable_cpu_hotplug	0
 #endif
 
 DECLARE_PER_CPU(int, cpu_state);

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [patch 3/4] x86_64: add genapic_force
  2006-11-09  1:20 [patch 0/4] i386, x86_64: fix the irqbalance quirk for E7520/E7320/E7525 - V2 Siddha, Suresh B
  2006-11-09  1:23 ` [patch 1/4] i386: add write_pci_config_byte() to direct PCI access routines Siddha, Suresh B
  2006-11-09  1:27 ` [patch 2/4] i386: introduce the mechanism of disabling cpu hotplug control Siddha, Suresh B
@ 2006-11-09  1:29 ` Siddha, Suresh B
  2006-11-09  1:30 ` [patch 4/4] fix the irqbalance quirk for E7320/E7520/E7525 Siddha, Suresh B
  2006-11-09 13:20 ` [patch 0/4] i386, x86_64: fix the irqbalance quirk for E7520/E7320/E7525 - V2 Andi Kleen
  4 siblings, 0 replies; 6+ messages in thread
From: Siddha, Suresh B @ 2006-11-09  1:29 UTC (permalink / raw)
  To: ak, akpm
  Cc: shaohua.li, linux-kernel, discuss, ashok.raj, suresh.b.siddha,
	greg

Add genapic_force. Used by the next Intel quirks patch.

Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
---

diff --git a/arch/x86_64/kernel/genapic.c b/arch/x86_64/kernel/genapic.c
index 8e78a75..b007433 100644
--- a/arch/x86_64/kernel/genapic.c
+++ b/arch/x86_64/kernel/genapic.c
@@ -33,7 +33,7 @@ extern struct genapic apic_flat;
 extern struct genapic apic_physflat;
 
 struct genapic *genapic = &apic_flat;
-
+struct genapic *genapic_force;
 
 /*
  * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode.
@@ -46,6 +46,13 @@ void __init clustered_apic_check(void)
 	u8 cluster_cnt[NUM_APIC_CLUSTERS];
 	int max_apic = 0;
 
+	/* genapic selection can be forced because of certain quirks.
+	 */
+	if (genapic_force) {
+		genapic = genapic_force;
+		goto print;
+	}
+
 #if defined(CONFIG_ACPI)
 	/*
 	 * Some x86_64 machines use physical APIC mode regardless of how many
diff --git a/include/asm-x86_64/genapic.h b/include/asm-x86_64/genapic.h
index a0e9a4b..b80f4bb 100644
--- a/include/asm-x86_64/genapic.h
+++ b/include/asm-x86_64/genapic.h
@@ -30,6 +30,6 @@ struct genapic {
 };
 
 
-extern struct genapic *genapic;
+extern struct genapic *genapic, *genapic_force, apic_flat;
 
 #endif

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [patch 4/4] fix the irqbalance quirk for E7320/E7520/E7525
  2006-11-09  1:20 [patch 0/4] i386, x86_64: fix the irqbalance quirk for E7520/E7320/E7525 - V2 Siddha, Suresh B
                   ` (2 preceding siblings ...)
  2006-11-09  1:29 ` [patch 3/4] x86_64: add genapic_force Siddha, Suresh B
@ 2006-11-09  1:30 ` Siddha, Suresh B
  2006-11-09 13:20 ` [patch 0/4] i386, x86_64: fix the irqbalance quirk for E7520/E7320/E7525 - V2 Andi Kleen
  4 siblings, 0 replies; 6+ messages in thread
From: Siddha, Suresh B @ 2006-11-09  1:30 UTC (permalink / raw)
  To: ak, akpm
  Cc: shaohua.li, linux-kernel, discuss, ashok.raj, suresh.b.siddha,
	greg

Move the irqbalance quirks for E7320/E7520/E7525(Errata 23 in
http://download.intel.com/design/chipsets/specupdt/30304203.pdf) to early
quirks.

And add a PCI quirk for these platforms to check(which happens very late
during the boot) if the APIC routing is indeed set to default flat mode.

This fixes the breakage(in x86_64) of this quirk due to cpu hotplug which
selects physical mode instead of the logical flat(as needed for this errata
workaround).

Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
---

diff --git a/arch/i386/kernel/acpi/earlyquirk.c b/arch/i386/kernel/acpi/earlyquirk.c
index fe799b1..4cdec39 100644
--- a/arch/i386/kernel/acpi/earlyquirk.c
+++ b/arch/i386/kernel/acpi/earlyquirk.c
@@ -10,6 +10,7 @@ #include <linux/acpi.h>
 #include <asm/pci-direct.h>
 #include <asm/acpi.h>
 #include <asm/apic.h>
+#include <asm/irq.h>
 
 #ifdef CONFIG_ACPI
 
@@ -43,6 +44,24 @@ #endif
 	return 0;
 }
 
+static void check_intel(void)
+{
+	u16 vendor, device;
+
+	vendor = read_pci_config_16(0, 0, 0, PCI_VENDOR_ID);
+
+	if (vendor != PCI_VENDOR_ID_INTEL)
+		return;
+
+	device = read_pci_config_16(0, 0, 0, PCI_DEVICE_ID);
+#ifdef CONFIG_SMP
+	if (device == PCI_DEVICE_ID_INTEL_E7320_MCH ||
+	    device == PCI_DEVICE_ID_INTEL_E7520_MCH ||
+	    device == PCI_DEVICE_ID_INTEL_E7525_MCH)
+		quirk_intel_irqbalance();
+#endif
+}
+
 void __init check_acpi_pci(void)
 {
 	int num, slot, func;
@@ -54,6 +73,8 @@ void __init check_acpi_pci(void)
 	if (!early_pci_allowed())
 		return;
 
+	check_intel();
+
 	/* Poor man's PCI discovery */
 	for (num = 0; num < 32; num++) {
 		for (slot = 0; slot < 32; slot++) {
diff --git a/arch/i386/kernel/quirks.c b/arch/i386/kernel/quirks.c
index 9f6ab17..78101c2 100644
--- a/arch/i386/kernel/quirks.c
+++ b/arch/i386/kernel/quirks.c
@@ -3,10 +3,23 @@
  */
 #include <linux/pci.h>
 #include <linux/irq.h>
+#include <asm/pci-direct.h>
+#include <asm/genapic.h>
+#include <asm/cpu.h>
 
 #if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_SMP) && defined(CONFIG_PCI)
+static void __devinit verify_quirk_intel_irqbalance(struct pci_dev *dev)
+{
+#ifdef CONFIG_X86_64
+	if (genapic !=  &apic_flat)
+		panic("APIC mode must be flat on this system\n");
+#elif defined(CONFIG_X86_GENERICARCH)
+	if (genapic != &apic_default)
+		panic("APIC mode must be default(flat) on this system. Use apic=default\n");
+#endif
+}
 
-static void __devinit quirk_intel_irqbalance(struct pci_dev *dev)
+void __init quirk_intel_irqbalance(void)
 {
 	u8 config, rev;
 	u32 word;
@@ -16,18 +29,18 @@ static void __devinit quirk_intel_irqbal
 	 * based platforms.
 	 * Disable SW irqbalance/affinity on those platforms.
 	 */
-	pci_read_config_byte(dev, PCI_CLASS_REVISION, &rev);
+	rev = read_pci_config_byte(0, 0, 0, PCI_CLASS_REVISION);
 	if (rev > 0x9)
 		return;
 
 	printk(KERN_INFO "Intel E7520/7320/7525 detected.");
 
-	/* enable access to config space*/
-	pci_read_config_byte(dev, 0xf4, &config);
-	pci_write_config_byte(dev, 0xf4, config|0x2);
+	/* enable access to config space */
+	config = read_pci_config_byte(0, 0, 0, 0xf4);
+	write_pci_config_byte(0, 0, 0, 0xf4, config|0x2);
 
 	/* read xTPR register */
-	raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word);
+	word = read_pci_config_16(0, 0, 0x40, 0x4c);
 
 	if (!(word & (1 << 13))) {
 		printk(KERN_INFO "Disabling irq balancing and affinity\n");
@@ -38,13 +51,24 @@ #endif
 #ifdef CONFIG_PROC_FS
 		no_irq_affinity = 1;
 #endif
+#ifdef CONFIG_HOTPLUG_CPU
+		printk(KERN_INFO "Disabling cpu hotplug control\n");
+		enable_cpu_hotplug = 0;
+#endif
+#ifdef CONFIG_X86_64
+		/* force the genapic selection to flat mode so that
+		 * interrupts can be redirected to more than one CPU.
+		 */
+		genapic_force = &apic_flat;
+#endif
 	}
 
-	/* put back the original value for config space*/
+	/* put back the original value for config space */
 	if (!(config & 0x2))
-		pci_write_config_byte(dev, 0xf4, config);
+		write_pci_config_byte(0, 0, 0, 0xf4, config);
 }
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_E7320_MCH,	quirk_intel_irqbalance);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_E7525_MCH,	quirk_intel_irqbalance);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_E7520_MCH,	quirk_intel_irqbalance);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_E7320_MCH,  verify_quirk_intel_irqbalance);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_E7525_MCH,  verify_quirk_intel_irqbalance);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_E7520_MCH,  verify_quirk_intel_irqbalance);
+
 #endif
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 4bb8b77..be0e103 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -52,6 +52,7 @@ #include <asm/tlbflush.h>
 #include <asm/desc.h>
 #include <asm/arch_hooks.h>
 #include <asm/nmi.h>
+#include <asm/genapic.h>
 
 #include <mach_apic.h>
 #include <mach_wakecpu.h>
@@ -1461,6 +1462,12 @@ #endif
 	cpu_set(cpu, smp_commenced_mask);
 	while (!cpu_isset(cpu, cpu_online_map))
 		cpu_relax();
+
+#ifdef CONFIG_X86_GENERICARCH
+	if (num_online_cpus() > 8 && genapic == &apic_default)
+		panic("Default flat APIC routing can't be used with > 8 cpus\n");
+#endif
+
 	return 0;
 }
 
diff --git a/arch/x86_64/kernel/early-quirks.c b/arch/x86_64/kernel/early-quirks.c
index 2b1245d..b833bb8 100644
--- a/arch/x86_64/kernel/early-quirks.c
+++ b/arch/x86_64/kernel/early-quirks.c
@@ -68,6 +68,18 @@ static void ati_bugs(void)
 	}
 }
 
+static void intel_bugs(void)
+{
+	u16 device = read_pci_config_16(0, 0, 0, PCI_DEVICE_ID);
+
+#ifdef CONFIG_SMP
+	if (device == PCI_DEVICE_ID_INTEL_E7320_MCH ||
+	    device == PCI_DEVICE_ID_INTEL_E7520_MCH ||
+	    device == PCI_DEVICE_ID_INTEL_E7525_MCH)
+		quirk_intel_irqbalance();
+#endif
+}
+
 struct chipset {
 	u16 vendor;
 	void (*f)(void);
@@ -77,6 +89,7 @@ static struct chipset early_qrk[] = {
 	{ PCI_VENDOR_ID_NVIDIA, nvidia_bugs },
 	{ PCI_VENDOR_ID_VIA, via_bugs },
 	{ PCI_VENDOR_ID_ATI, ati_bugs },
+	{ PCI_VENDOR_ID_INTEL, intel_bugs},
 	{}
 };
 
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 62c2e74..4c161c2 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -60,6 +60,7 @@ #include <asm/nmi.h>
 #include <asm/irq.h>
 #include <asm/hw_irq.h>
 #include <asm/numa.h>
+#include <asm/genapic.h>
 
 /* Number of siblings per CPU package */
 int smp_num_siblings = 1;
@@ -1167,6 +1168,13 @@ int __cpuinit __cpu_up(unsigned int cpu)
 
 	while (!cpu_isset(cpu, cpu_online_map))
 		cpu_relax();
+
+	if (num_online_cpus() > 8 && genapic == &apic_flat) {
+		printk(KERN_WARNING
+		       "flat APIC routing can't be used with > 8 cpus\n");
+		BUG();
+	}
+
 	err = 0;
 
 	return err;
diff --git a/include/asm-i386/genapic.h b/include/asm-i386/genapic.h
index 8ffbb0f..fd2be59 100644
--- a/include/asm-i386/genapic.h
+++ b/include/asm-i386/genapic.h
@@ -122,6 +122,6 @@ #define APIC_INIT(aname, aprobe) { \
 	APICFUNC(phys_pkg_id) \
 	}
 
-extern struct genapic *genapic;
+extern struct genapic *genapic, apic_default;
 
 #endif
diff --git a/include/asm-i386/irq.h b/include/asm-i386/irq.h
index 331726b..c35dc8e 100644
--- a/include/asm-i386/irq.h
+++ b/include/asm-i386/irq.h
@@ -37,6 +37,8 @@ #ifdef CONFIG_IRQBALANCE
 extern int irqbalance_disable(char *str);
 #endif
 
+extern void quirk_intel_irqbalance(void);
+
 #ifdef CONFIG_HOTPLUG_CPU
 extern void fixup_irqs(cpumask_t map);
 #endif
diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h
index e72cfcd..3b6a4ec 100644
--- a/include/asm-x86_64/proto.h
+++ b/include/asm-x86_64/proto.h
@@ -88,6 +88,7 @@ extern void syscall32_cpu_init(void);
 extern void setup_node_bootmem(int nodeid, unsigned long start, unsigned long end);
 
 extern void early_quirks(void);
+extern void quirk_intel_irqbalance(void);
 extern void check_efer(void);
 
 extern int unhandled_signal(struct task_struct *tsk, int sig);

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [patch 0/4] i386, x86_64: fix the irqbalance quirk for E7520/E7320/E7525 - V2
  2006-11-09  1:20 [patch 0/4] i386, x86_64: fix the irqbalance quirk for E7520/E7320/E7525 - V2 Siddha, Suresh B
                   ` (3 preceding siblings ...)
  2006-11-09  1:30 ` [patch 4/4] fix the irqbalance quirk for E7320/E7520/E7525 Siddha, Suresh B
@ 2006-11-09 13:20 ` Andi Kleen
  4 siblings, 0 replies; 6+ messages in thread
From: Andi Kleen @ 2006-11-09 13:20 UTC (permalink / raw)
  To: Siddha, Suresh B; +Cc: akpm, shaohua.li, linux-kernel, discuss, ashok.raj, greg

On Thursday 09 November 2006 02:20, Siddha, Suresh B wrote:
> Mechanism of selecting physical mode in genapic when cpu hotplug is enabled
> on x86_64, broke the quirk(quirk_intel_irqbalance()) introduced for working
> around the transposing interrupt message errata in E7520/E7320/E7525
> (revision ID 0x9 and below. errata #23 in
> http://download.intel.com/design/chipsets/specupdt/30304203.pdf).
>
> This errata requires the mode to be in logical flat, so that interrupts
> can be directed to more than one cpu(and thus use hardware IRQ balancing
> enabled by BIOS on these platforms).

Fine by me. But can you fix the compilation issues Andrew found and resend
please?

-Andi

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2006-11-09 15:21 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-11-09  1:20 [patch 0/4] i386, x86_64: fix the irqbalance quirk for E7520/E7320/E7525 - V2 Siddha, Suresh B
2006-11-09  1:23 ` [patch 1/4] i386: add write_pci_config_byte() to direct PCI access routines Siddha, Suresh B
2006-11-09  1:27 ` [patch 2/4] i386: introduce the mechanism of disabling cpu hotplug control Siddha, Suresh B
2006-11-09  1:29 ` [patch 3/4] x86_64: add genapic_force Siddha, Suresh B
2006-11-09  1:30 ` [patch 4/4] fix the irqbalance quirk for E7320/E7520/E7525 Siddha, Suresh B
2006-11-09 13:20 ` [patch 0/4] i386, x86_64: fix the irqbalance quirk for E7520/E7320/E7525 - V2 Andi Kleen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox