All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yinghai Lu <yinghai@kernel.org>
To: Thomas Renninger <trenn@suse.de>, Gary Hade <garyhade@us.ibm.com>,
	Ingo Molnar <mingo@elte.hu>, Thomas Gleixner <tglx@linutronix.de>
Cc: Iranna D Ankad <iranna.ankad@in.ibm.com>,
	"H. Peter Anvin" <hpa@zytor.com>,
	"Eric W. Biederman" <ebiederm@xmission.com>,
	Suresh Siddha <suresh.b.siddha@intel.com>,
	len.brown@intel.com,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: Other problem/regression with b9c61b70075c87a8612624736faf4a2de5b1ed30
Date: Tue, 23 Feb 2010 01:07:23 -0800	[thread overview]
Message-ID: <4B839ACB.3000804@kernel.org> (raw)
In-Reply-To: <201002221258.38506.trenn@suse.de>

Gary,

can you check this patch on your x3950?

Thanks

Yinghai

[PATCH] x86: fix out of order of gsi

found IBM x3950 will have problem after

|commit b9c61b70075c87a8612624736faf4a2de5b1ed30
|
|    x86/pci: update pirq_enable_irq() to setup io apic routing

The problem is that with the patch, the machine freezes when
console=ttyS0,... kernel serial parameter is passed.
It seem to freeze at DVD initialization and the whole problem seem
to be DVD/pata related, but somehow exposed through the serial
parameter.
Such apic problems can expose really weird behavior..

<6>ACPI: IOAPIC (id[0x10] address[0xfecff000] gsi_base[0])
<6>IOAPIC[0]: apic_id 16, version 0, address 0xfecff000, GSI 0-2
<6>ACPI: IOAPIC (id[0x0f] address[0xfec00000] gsi_base[3])
<6>IOAPIC[1]: apic_id 15, version 0, address 0xfec00000, GSI 3-38
<6>ACPI: IOAPIC (id[0x0e] address[0xfec01000] gsi_base[39])
<6>IOAPIC[2]: apic_id 14, version 0, address 0xfec01000, GSI 39-74
<6>ACPI: INT_SRC_OVR (bus 0 bus_irq 1 global_irq 4 dfl dfl)
<6>ACPI: INT_SRC_OVR (bus 0 bus_irq 0 global_irq 5 dfl dfl)
<6>ACPI: INT_SRC_OVR (bus 0 bus_irq 3 global_irq 6 dfl dfl)
<6>ACPI: INT_SRC_OVR (bus 0 bus_irq 4 global_irq 7 dfl dfl)
<6>ACPI: INT_SRC_OVR (bus 0 bus_irq 6 global_irq 9 dfl dfl)
<6>ACPI: INT_SRC_OVR (bus 0 bus_irq 7 global_irq 10 dfl dfl)
<6>ACPI: INT_SRC_OVR (bus 0 bus_irq 8 global_irq 11 low edge)
<6>ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 12 dfl dfl)
<6>ACPI: INT_SRC_OVR (bus 0 bus_irq 12 global_irq 15 dfl dfl)
<6>ACPI: INT_SRC_OVR (bus 0 bus_irq 13 global_irq 16 dfl dfl)
<6>ACPI: INT_SRC_OVR (bus 0 bus_irq 14 global_irq 17 low edge)
<6>ACPI: INT_SRC_OVR (bus 0 bus_irq 15 global_irq 18 dfl dfl)

it turns out that system have three io apic controller. but put boot ioapic
routing in second one. and that gsi_base is not 0. it is using bunch of INT_SRC_OVR...

recent changes
1. one set routing for first io apic controller
2. assume irq = gsi
will break theat system.

so try to remap those gsi, need to seperate boot_ioapic_id detection out of enable_IO_APIC
and call them early.
introduce boot_ioapic_id, and remap_ioapic_gsi...

Reported-by: Iranna D Ankad <iranna.ankad@in.ibm.com>
Bisected-by: Iranna D Ankad <iranna.ankad@in.ibm.com>
Cc: Thomas Renninger <trenn@suse.de>
Cc: stable@kernel.org
Signed-off-by: Yinghai Lu <yinghai@kernel.org>

---
 arch/x86/include/asm/io_apic.h |    3 +-
 arch/x86/include/asm/mpspec.h  |    1 
 arch/x86/kernel/acpi/boot.c    |   27 +++++++++++++++++---
 arch/x86/kernel/apic/io_apic.c |   55 ++++++++++++++++++++++++-----------------
 4 files changed, 59 insertions(+), 27 deletions(-)

Index: linux-2.6/arch/x86/include/asm/io_apic.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/io_apic.h
+++ linux-2.6/arch/x86/include/asm/io_apic.h
@@ -113,6 +113,7 @@ struct IR_IO_APIC_route_entry {
  */
 extern int nr_ioapics;
 extern int nr_ioapic_registers[MAX_IO_APICS];
+extern int boot_ioapic_idx;
 
 #define MP_MAX_IOAPIC_PIN 127
 
@@ -160,7 +161,7 @@ extern int io_apic_get_redir_entries(int
 struct io_apic_irq_attr;
 extern int io_apic_set_pci_routing(struct device *dev, int irq,
 		 struct io_apic_irq_attr *irq_attr);
-void setup_IO_APIC_irq_extra(u32 gsi);
+void setup_IO_APIC_irq_extra(u32 gsi, unsigned int *irq);
 extern int (*ioapic_renumber_irq)(int ioapic, int irq);
 extern void ioapic_init_mappings(void);
 extern void ioapic_insert_resources(void);
Index: linux-2.6/arch/x86/include/asm/mpspec.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/mpspec.h
+++ linux-2.6/arch/x86/include/asm/mpspec.h
@@ -105,6 +105,7 @@ extern void mp_config_acpi_legacy_irqs(v
 struct device;
 extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
 				 int active_high_low);
+int remap_ioapic_gsi(int ioapic, u32 gsi);
 extern int acpi_probe_gsi(void);
 #ifdef CONFIG_X86_IO_APIC
 extern int mp_find_ioapic(int gsi);
Index: linux-2.6/arch/x86/kernel/acpi/boot.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/acpi/boot.c
+++ linux-2.6/arch/x86/kernel/acpi/boot.c
@@ -449,7 +449,7 @@ int acpi_gsi_to_irq(u32 gsi, unsigned in
 
 #ifdef CONFIG_X86_IO_APIC
 	if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
-		setup_IO_APIC_irq_extra(gsi);
+		setup_IO_APIC_irq_extra(gsi, irq);
 #endif
 
 	return 0;
@@ -1049,11 +1049,29 @@ static int mp_config_acpi_gsi(struct dev
 	return 0;
 }
 
+int remap_ioapic_gsi(int ioapic, u32 gsi)
+{
+	int base_boot = mp_gsi_routing[boot_ioapic_idx].gsi_base;
+	int base_x;
+
+	if (!base_boot)
+		return gsi;
+
+	base_x = mp_gsi_routing[ioapic].gsi_base;
+	if (base_x < base_boot)
+		gsi += base_boot;
+	else if (base_x == base_boot)
+		gsi -= base_boot;
+
+	return gsi;
+}
+
 int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
 {
 	int ioapic;
 	int ioapic_pin;
 	struct io_apic_irq_attr irq_attr;
+	u32 plat_gsi;
 
 	if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
 		return gsi;
@@ -1074,12 +1092,13 @@ int mp_register_gsi(struct device *dev,
 	if (ioapic_renumber_irq)
 		gsi = ioapic_renumber_irq(ioapic, gsi);
 #endif
+	plat_gsi = remap_ioapic_gsi(ioapic, gsi);
 
 	if (ioapic_pin > MP_MAX_IOAPIC_PIN) {
 		printk(KERN_ERR "Invalid reference to IOAPIC pin "
 		       "%d-%d\n", mp_ioapics[ioapic].apicid,
 		       ioapic_pin);
-		return gsi;
+		return plat_gsi;
 	}
 
 	if (enable_update_mptable)
@@ -1088,9 +1107,9 @@ int mp_register_gsi(struct device *dev,
 	set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin,
 			     trigger == ACPI_EDGE_SENSITIVE ? 0 : 1,
 			     polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
-	io_apic_set_pci_routing(dev, gsi, &irq_attr);
+	io_apic_set_pci_routing(dev, plat_gsi, &irq_attr);
 
-	return gsi;
+	return plat_gsi;
 }
 
 /*
Index: linux-2.6/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6/arch/x86/kernel/apic/io_apic.c
@@ -84,6 +84,7 @@ int nr_ioapic_registers[MAX_IO_APICS];
 /* I/O APIC entries */
 struct mpc_ioapic mp_ioapics[MAX_IO_APICS];
 int nr_ioapics;
+int boot_ioapic_idx;
 
 /* IO APIC gsi routing info */
 struct mp_ioapic_gsi  mp_gsi_routing[MAX_IO_APICS];
@@ -1028,13 +1029,18 @@ static int pin_2_irq(int idx, int apic,
 	if (test_bit(bus, mp_bus_not_pci)) {
 		irq = mp_irqs[idx].srcbusirq;
 	} else {
-		/*
-		 * PCI IRQs are mapped in order
-		 */
-		i = irq = 0;
-		while (i < apic)
-			irq += nr_ioapic_registers[i++];
-		irq += pin;
+		if (!acpi_ioapic) {
+			/*
+			 * PCI IRQs are mapped in order
+			 */
+			i = irq = 0;
+			while (i < apic)
+				irq += nr_ioapic_registers[i++];
+			irq += pin;
+		} else {
+			irq = pin + mp_gsi_routing[apic].gsi_base;
+			irq = remap_ioapic_gsi(apic, irq);
+		}
 		/*
                  * For MPS mode, so far only needed by ES7000 platform
                  */
@@ -1473,9 +1479,10 @@ static struct {
 	DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
 } mp_ioapic_routing[MAX_IO_APICS];
 
-static void __init setup_IO_APIC_irqs(void)
+
+static void __init setup_IO_APIC_irqs(int apic_id)
 {
-	int apic_id = 0, pin, idx, irq;
+	int pin, idx, irq;
 	int notcon = 0;
 	struct irq_desc *desc;
 	struct irq_cfg *cfg;
@@ -1483,14 +1490,6 @@ static void __init setup_IO_APIC_irqs(vo
 
 	apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
 
-#ifdef CONFIG_ACPI
-	if (!acpi_disabled && acpi_ioapic) {
-		apic_id = mp_find_ioapic(0);
-		if (apic_id < 0)
-			apic_id = 0;
-	}
-#endif
-
 	for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) {
 		idx = find_irq_entry(apic_id, pin, mp_INT);
 		if (idx == -1) {
@@ -1545,7 +1544,7 @@ static void __init setup_IO_APIC_irqs(vo
  * but could not use acpi_register_gsi()
  * like some special sci in IBM x3330
  */
-void setup_IO_APIC_irq_extra(u32 gsi)
+void setup_IO_APIC_irq_extra(u32 gsi, unsigned int *pirq)
 {
 	int apic_id = 0, pin, idx, irq;
 	int node = cpu_to_node(boot_cpu_id);
@@ -1565,6 +1564,7 @@ void setup_IO_APIC_irq_extra(u32 gsi)
 		return;
 
 	irq = pin_2_irq(idx, apic_id, pin);
+	*pirq = irq;
 #ifdef CONFIG_SPARSE_IRQ
 	desc = irq_to_desc(irq);
 	if (desc)
@@ -1940,11 +1940,10 @@ __apicdebuginit(int) print_ICs(void)
 
 fs_initcall(print_ICs);
 
-
 /* Where if anywhere is the i8259 connect in external int mode */
 static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
 
-void __init enable_IO_APIC(void)
+static void __init probe_ioapic_i8259(void)
 {
 	union IO_APIC_reg_01 reg_01;
 	int i8259_apic, i8259_pin;
@@ -2001,7 +2000,12 @@ void __init enable_IO_APIC(void)
 	{
 		printk(KERN_WARNING "ExtINT in hardware and MP table differ\n");
 	}
+}
 
+void __init enable_IO_APIC(void)
+{
+	if (!nr_legacy_irqs)
+		return;
 	/*
 	 * Do not trust the IO-APIC being empty at bootup
 	 */
@@ -3126,7 +3130,6 @@ out:
 
 void __init setup_IO_APIC(void)
 {
-
 	/*
 	 * calling enable_IO_APIC() is moved to setup_local_APIC for BP
 	 */
@@ -3139,7 +3142,15 @@ void __init setup_IO_APIC(void)
 	x86_init.mpparse.setup_ioapic_ids();
 
 	sync_Arb_IDs();
-	setup_IO_APIC_irqs();
+	probe_ioapic_i8259();
+	boot_ioapic_idx = ioapic_i8259.apic;
+#ifdef CONFIG_ACPI
+	if (!acpi_disabled && acpi_ioapic && boot_ioapic_idx < 0)
+		boot_ioapic_idx = mp_find_ioapic(0);
+#endif
+	if (boot_ioapic_idx < 0)
+		boot_ioapic_idx = 0;
+	setup_IO_APIC_irqs(boot_ioapic_idx);
 	init_IO_APIC_traps();
 	if (nr_legacy_irqs)
 		check_timer();

       reply	other threads:[~2010-02-23  9:09 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <201002221108.42847.trenn@suse.de>
     [not found] ` <4B826CA6.7060007@kernel.org>
     [not found]   ` <201002221258.38506.trenn@suse.de>
2010-02-23  9:07     ` Yinghai Lu [this message]
2010-02-23 18:40       ` Other problem/regression with b9c61b70075c87a8612624736faf4a2de5b1ed30 Yinghai Lu
2010-02-23 20:17         ` Eric W. Biederman
2010-02-26 19:30         ` [PATCH -v8 1/2] x86: fix out of order of gsi - have right boot_ioapic_idx Yinghai Lu
2010-02-27 12:57           ` [tip:x86/apic] x86: Fix out of order gsi - have the " tip-bot for Yinghai Lu
2010-02-26 19:31         ` [PATCH -v8 2/2] x86: fix out of order of gsi -- add remap_ioapic_gsi_to_irq Yinghai Lu
2010-02-27 12:57           ` [tip:x86/apic] x86: Fix out of order gsi -- add remap_ioapic_gsi_to_irq() tip-bot for Yinghai Lu
2010-02-27 13:01             ` Ingo Molnar
2010-02-27 18:52               ` Yinghai Lu
2010-02-27 22:57                 ` H. Peter Anvin
2010-02-27 19:04               ` Eric W. Biederman
2010-02-27 19:40                 ` Yinghai Lu
2010-02-27 21:30                   ` Eric W. Biederman
2010-02-27 22:00                     ` Yinghai Lu
2010-02-27 22:18                       ` Eric W. Biederman
2010-02-27 22:58                         ` Yinghai Lu
2010-02-28  1:12                         ` [PATCH -v9] x86: fix out of order of gsi Yinghai Lu
2010-02-28  3:26                           ` [PATCH -v10] " Yinghai Lu
2010-02-28  3:47                         ` [PATCH -v11] x86: fix out of order of gsi -- partial Yinghai Lu
2010-02-28  8:09                           ` Ingo Molnar
2010-02-28  9:05                             ` Yinghai Lu
2010-03-01 14:40                               ` Thomas Renninger
2010-03-01 18:31                                 ` Yinghai Lu
2010-02-28  9:06                             ` [PATCH -v12 1/2] " Yinghai Lu
2010-02-28 19:51                               ` [tip:x86/apic] x86: Fix out of order of gsi tip-bot for Eric W. Biederman
2010-02-28  9:08                             ` [PATCH -v12 2/2] x86: fix out of order of gsi - full Yinghai Lu
2010-03-01 18:59                               ` Eric W. Biederman
2010-03-01 19:37                       ` [tip:x86/apic] x86: Fix out of order gsi -- add remap_ioapic_gsi_to_irq() Eric W. Biederman
2010-03-01 20:26                         ` Yinghai Lu
2010-03-01 16:46                     ` [LKML] " Konrad Rzeszutek Wilk
2010-03-01 18:37                       ` Yinghai Lu
2010-03-01 18:44                       ` Eric W. Biederman
2010-03-01 18:33                         ` [LKML] " Konrad Rzeszutek Wilk
2010-02-23 19:02       ` Other problem/regression with b9c61b70075c87a8612624736faf4a2de5b1ed30 Gary Hade

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4B839ACB.3000804@kernel.org \
    --to=yinghai@kernel.org \
    --cc=ebiederm@xmission.com \
    --cc=garyhade@us.ibm.com \
    --cc=hpa@zytor.com \
    --cc=iranna.ankad@in.ibm.com \
    --cc=len.brown@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=suresh.b.siddha@intel.com \
    --cc=tglx@linutronix.de \
    --cc=trenn@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.