Commit 4a6e68bf authored by Sinan Kaya's avatar Sinan Kaya Committed by Rafael J. Wysocki

ACPI,PCI,IRQ: factor in PCI possible

The change introduced in commit 103544d8 (ACPI,PCI,IRQ: reduce
resource requirements) omitted the initially applied PCI_POSSIBLE
penalty when the IRQ is active.

Incorrect calculation of the penalty leads the ACPI code to assigning
a wrong interrupt number to a PCI INTx interrupt.

This would not be as bad as it sounds in theory.  It would just cause
the interrupts to be shared and result in performance penalty.

However, some drivers (like the parallel port driver) don't like
interrupt sharing and in the above case they will causes all of
the PCI drivers wanting to share the interrupt to be unable to
request it.

The issue has not been caught in testing because the behavior is
platform-specific and depends on the peripherals ending up sharing
the IRQ and their drivers.

Before the above commit the code would add the PCI_POSSIBLE value
divided by the number of possible IRQ users to the IRQ penalty
during initialization.

Later in that code path, if the IRQ is chosen as the active IRQ or
if it is used by ISA; additional penalties are added.

Fixes: 103544d8 (ACPI,PCI,IRQ: reduce resource requirements)
Signed-off-by: default avatarSinan Kaya <okaya@codeaurora.org>
Tested-by: default avatarWim Osterholt <wim@djo.tudelft.nl>
[ rjw: Changelog ]
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 54794580
...@@ -470,6 +470,7 @@ static int acpi_irq_pci_sharing_penalty(int irq) ...@@ -470,6 +470,7 @@ static int acpi_irq_pci_sharing_penalty(int irq)
{ {
struct acpi_pci_link *link; struct acpi_pci_link *link;
int penalty = 0; int penalty = 0;
int i;
list_for_each_entry(link, &acpi_link_list, list) { list_for_each_entry(link, &acpi_link_list, list) {
/* /*
...@@ -478,19 +479,15 @@ static int acpi_irq_pci_sharing_penalty(int irq) ...@@ -478,19 +479,15 @@ static int acpi_irq_pci_sharing_penalty(int irq)
*/ */
if (link->irq.active && link->irq.active == irq) if (link->irq.active && link->irq.active == irq)
penalty += PIRQ_PENALTY_PCI_USING; penalty += PIRQ_PENALTY_PCI_USING;
else {
int i;
/* /*
* If a link is inactive, penalize the IRQs it * penalize the IRQs PCI might use, but not as severely.
* might use, but not as severely.
*/ */
for (i = 0; i < link->irq.possible_count; i++) for (i = 0; i < link->irq.possible_count; i++)
if (link->irq.possible[i] == irq) if (link->irq.possible[i] == irq)
penalty += PIRQ_PENALTY_PCI_POSSIBLE / penalty += PIRQ_PENALTY_PCI_POSSIBLE /
link->irq.possible_count; link->irq.possible_count;
} }
}
return penalty; return penalty;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment