lkml.org 
[lkml]   [2010]   [Feb]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH -v12 1/2] x86: fix out of order of gsi -- partial

    From: Eric W. Biederman <ebiederm@xmission.com>

    Iranna D Ankad reported that IBM x3950 systems have boot problems
    after this commit:

    |
    | 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:

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

    It turns out that the system has three io apic controllers, but
    boot ioapic routing is in the second one, and that gsi_base is
    not 0 - it is using a bunch of INT_SRC_OVR...

    So these recent changes:

    1. one set routing for first io apic controller
    2. assume irq = gsi

    ... will break that system.

    So try to remap those gsis, need to seperate boot_ioapic_idx
    detection out of enable_IO_APIC() and call them early.

    So introduce boot_ioapic_idx, and remap_ioapic_gsi()...

    -v2: shift gsi with delta instead of gsi_base of boot_ioapic_idx

    -v3: double check with find_isa_irq_apic(0, mp_INT) to get right
    boot_ioapic_idx

    -v4: nr_legacy_irqs

    -v5: add print out for boot_ioapic_idx, and also make it could be
    applied for current kernel and previous kernel

    -v6: add bus_irq, in acpi_sci_ioapic_setup, so can get overwride
    for sci right mapping...

    -v7: looks like pnpacpi get irq instead of gsi, so need to revert
    them back...

    -v8: split into two patches

    -v9: according to Eric, use fixed 16 for shifting instead of remap

    -v10: still need to touch rsparser.c

    -v11: just revert back to way Eric suggest...
    anyway the ioapic in first ioapic is blocked by second...

    -v12: two patches, this one will add more loop but check apic_id and irq > 16

    Reported-by: Iranna D Ankad <iranna.ankad@in.ibm.com>
    Bisected-by: Iranna D Ankad <iranna.ankad@in.ibm.com>
    Tested-by: Gary Hade <garyhade@us.ibm.com>
    Signed-off-by: Yinghai Lu <yinghai@kernel.org>
    Cc: Thomas Renninger <trenn@suse.de>
    Cc: Eric W. Biederman <ebiederm@xmission.com>
    Cc: Suresh Siddha <suresh.b.siddha@intel.com>
    Cc: len.brown@intel.com

    ---
    arch/x86/kernel/apic/io_apic.c | 28 ++++++++++------------------
    1 file changed, 10 insertions(+), 18 deletions(-)

    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
    @@ -1475,7 +1475,7 @@ static struct {

    static void __init setup_IO_APIC_irqs(void)
    {
    - int apic_id = 0, pin, idx, irq;
    + int apic_id, pin, idx, irq;
    int notcon = 0;
    struct irq_desc *desc;
    struct irq_cfg *cfg;
    @@ -1483,14 +1483,7 @@ 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 (apic_id = 0; apic_id < nr_ioapics; apic_id++)
    for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) {
    idx = find_irq_entry(apic_id, pin, mp_INT);
    if (idx == -1) {
    @@ -1512,6 +1505,9 @@ static void __init setup_IO_APIC_irqs(vo

    irq = pin_2_irq(idx, apic_id, pin);

    + if ((apic_id > 0) && (irq > 16))
    + continue;
    +
    /*
    * Skip the timer IRQ if there's a quirk handler
    * installed and if it returns 1:
    @@ -4105,27 +4101,23 @@ int acpi_get_override_irq(int bus_irq, i
    #ifdef CONFIG_SMP
    void __init setup_ioapic_dest(void)
    {
    - int pin, ioapic = 0, irq, irq_entry;
    + int pin, ioapic, irq, irq_entry;
    struct irq_desc *desc;
    const struct cpumask *mask;

    if (skip_ioapic_setup == 1)
    return;

    -#ifdef CONFIG_ACPI
    - if (!acpi_disabled && acpi_ioapic) {
    - ioapic = mp_find_ioapic(0);
    - if (ioapic < 0)
    - ioapic = 0;
    - }
    -#endif
    -
    + for (ioapic = 0; ioapic < nr_ioapics; ioapic++)
    for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) {
    irq_entry = find_irq_entry(ioapic, pin, mp_INT);
    if (irq_entry == -1)
    continue;
    irq = pin_2_irq(irq_entry, ioapic, pin);

    + if ((ioapic > 0) && (irq > 16))
    + continue;
    +
    desc = irq_to_desc(irq);

    /*

    \
     
     \ /
      Last update: 2010-02-28 10:11    [W:0.033 / U:30.660 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site