ACPI, PCI, irq: Do not share PCI IRQ with ISA IRQ
PATCH 1/2 ACPI, PCI, irq: Do not share PCI IRQ with ISA IRQ
Avoid IRQs occupied by ISA IRQs when allocating IRQs for PCI link devices, otherwise it may cause interrupt storm due to incompatible pin attributes.
This issue was triggered on a KVM virtual machine, which
1) uses IRQ9 for SCI in high level mode.
2) defines an PCI interrupt link device (LNKS) with IRQ9 as the only possible irq.
3) has an PCI device referring to link device LNKS.
So it causes interrupt storm when enabling the PCI device because PCI IRQ works in low level mode.
--- drivers/acpi/pci_irq.c | 1 + drivers/acpi/pci_link.c | 13 +++++++++++++ include/linux/acpi.h | 1 + 3 files changed, 15 insertions(+)
drivers/acpi/pci_irq.c +1 -0
@@ -372,6 +372,7 @@ static int acpi_isa_register_gsi(struct pci_dev *dev)/* Interrupt Line values above 0xF are forbidden */ if (dev->irq >0 && (dev->irq <=0xF ) && +acpi_isa_irq_available (dev->irq) && (acpi_isa_irq_to_gsi (dev->irq, &dev_gsi) ==0 )) {dev_warn (&dev->dev,"PCI INT %c: no GSI - using ISA IRQ %d\n" ,pin_name (dev->pin), dev->irq);
drivers/acpi/pci_link.c +13 -0
@@ -553,6 +553,13 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link) irq = link->irq.possible[i]; } } +if (acpi_irq_penalty[irq] >=PIRQ_PENALTY_ISA_ALWAYS ) { + printk(KERN_ERR PREFIX "No IRQ available for %s [%s]. " +"Try pci=noacpi or acpi=off\n" , +acpi_device_name (link->device), + acpi_device_bid(link->device)); +return -ENODEV ; + }/* Attempt to enable the link device at this IRQ. */ if (acpi_pci_link_set (link, irq)) {
@@ -821,6 +828,12 @@ void acpi_penalize_isa_irq(int irq, int active) } } +bool acpi_isa_irq_available (int irq) +{ +return irq >=0 && (irq >=ARRAY_SIZE (acpi_irq_penalty) || + acpi_irq_penalty[irq] <PIRQ_PENALTY_ISA_ALWAYS ); +} +/* * Penalize IRQ used by ACPI SCI. If ACPI SCI pin attributes conflict with * PCI IRQ attributes, mark ACPI SCI as ISA_ALWAYS so it won't be use for
include/linux/acpi.h +1 -0
@@ -217,6 +217,7 @@ struct pci_dev;int acpi_pci_irq_enable (struct pci_dev *dev);void acpi_penalize_isa_irq (int irq,int active); +bool acpi_isa_irq_available (int irq);void acpi_penalize_sci_irq (int irq,int trigger,int polarity);void acpi_pci_irq_disable (struct pci_dev *dev);
Signature · 1 line
1.7.10.4
PATCH 2/2 ACPI / PCI: Remove duplicated penalty on SCI IRQ
Now we have dedicated interface acpi_penalize_sci_irq() to penalize ISA IRQ used by ACPI SCI, so remove duplicated code to penalize ACPI SCI in acpi_irq_penalty_init().
--- drivers/acpi/pci_link.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/acpi/pci_link.c +1 -2
@@ -498,8 +498,7 @@ int __init acpi_irq_penalty_init(void)PIRQ_PENALTY_PCI_POSSIBLE ; } } -/* Add a penalty for the SCI */ - acpi_irq_penalty[acpi_gbl_FADT.sci_interrupt] +=PIRQ_PENALTY_PCI_USING ; +return 0 ; }
Signature · 1 line
1.7.10.4
Re: [Bugfix 2/2] ACPI / PCI: Remove duplicated penalty on SCI IRQ
Quoted 5 lines · Jiang Liu
Now we have dedicated interface
acpi_penalize_sci_irq()to penalize ISA IRQ used by ACPI SCI, so remove duplicated code to penalize ACPI SCI inacpi_irq_penalty_init().Signed-off-by Jiang Liu <[email protected]>
Quoted 26 lines
--- drivers/acpi/pci_link.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)drivers/acpi/pci_link.c +1
-2@@ -498,8 +498,7 @@ int __init acpi_irq_penalty_init(void)PIRQ_PENALTY_PCI_POSSIBLE ; } } -/* Add a penalty for the SCI */ - acpi_irq_penalty[acpi_gbl_FADT.sci_interrupt] +=PIRQ_PENALTY_PCI_USING ; +return 0 ; }Signature · 7 lines
1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Quoted 11 lines · Jiang Liu
Avoid IRQs occupied by ISA IRQs when allocating IRQs for PCI link devices, otherwise it may cause interrupt storm due to incompatible pin attributes.
This issue was triggered on a KVM virtual machine, which
1) uses IRQ9 for SCI in high level mode.
2) defines an PCI interrupt link device (LNKS) with IRQ9 as the only possible irq.
3) has an PCI device referring to link device LNKS.
So it causes interrupt storm when enabling the PCI device because PCI IRQ works in low level mode.
Quoted 1 line
Signed-off-by Jiang Liu <[email protected]>
Quoted 68 lines
--- drivers/acpi/pci_irq.c | 1 + drivers/acpi/pci_link.c | 13 +++++++++++++ include/linux/acpi.h | 1 + 3 files changed, 15 insertions(+)drivers/acpi/pci_irq.c +1
-0@@ -372,6 +372,7 @@ static int acpi_isa_register_gsi(struct pci_dev *dev)/* Interrupt Line values above 0xF are forbidden */ if (dev->irq >0 && (dev->irq <=0xF ) && +acpi_isa_irq_available (dev->irq) && (acpi_isa_irq_to_gsi (dev->irq, &dev_gsi) ==0 )) {dev_warn (&dev->dev,"PCI INT %c: no GSI - using ISA IRQ %d\n" ,pin_name (dev->pin), dev->irq);drivers/acpi/pci_link.c +13
-0@@ -553,6 +553,13 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link) irq = link->irq.possible[i]; } } +if (acpi_irq_penalty[irq] >=PIRQ_PENALTY_ISA_ALWAYS ) { + printk(KERN_ERR PREFIX "No IRQ available for %s [%s]. " +"Try pci=noacpi or acpi=off\n" , +acpi_device_name (link->device), + acpi_device_bid(link->device)); +return -ENODEV ; + }/* Attempt to enable the link device at this IRQ. */ if (acpi_pci_link_set (link, irq)) {@@ -821,6 +828,12 @@ void acpi_penalize_isa_irq(int irq, int active) } } +bool acpi_isa_irq_available (int irq) +{ +return irq >=0 && (irq >=ARRAY_SIZE (acpi_irq_penalty) || + acpi_irq_penalty[irq] <PIRQ_PENALTY_ISA_ALWAYS ); +} +/* * Penalize IRQ used by ACPI SCI. If ACPI SCI pin attributes conflict with * PCI IRQ attributes, mark ACPI SCI as ISA_ALWAYS so it won't be use for include/linux/acpi.h +1
-0@@ -217,6 +217,7 @@ struct pci_dev;int acpi_pci_irq_enable (struct pci_dev *dev);void acpi_penalize_isa_irq (int irq,int active); +bool acpi_isa_irq_available (int irq);void acpi_penalize_sci_irq (int irq,int trigger,int polarity);void acpi_pci_irq_disable (struct pci_dev *dev);Signature · 6 lines
1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 12 lines · Bjorn Helgaas
Quoted 11 lines · Jiang Liu
Avoid IRQs occupied by ISA IRQs when allocating IRQs for PCI link devices, otherwise it may cause interrupt storm due to incompatible pin attributes.
This issue was triggered on a KVM virtual machine, which
1) uses IRQ9 for SCI in high level mode.
2) defines an PCI interrupt link device (LNKS) with IRQ9 as the only possible irq.
3) has an PCI device referring to link device LNKS.
So it causes interrupt storm when enabling the PCI device because PCI IRQ works in low level mode.
Quoted 3 lines
Quoted 1 line
Signed-off-by Jiang Liu <[email protected]>Acked-by Bjorn Helgaas <[email protected]>
Thanks!
Queued up both this and the [2/2] for 4.3-rc4.
Thanks,
Rafael