Skip to content

Commit

Permalink
Revert "PCI/portdrv: Do not setup up IRQs if there are no users"
Browse files Browse the repository at this point in the history
commit 075b7d3 upstream.

This reverts commit 0e8ae5a.

0e8ae5a ("PCI/portdrv: Do not setup up IRQs if there are no users")
reduced usage of IRQs when we don't think we need them.  But Joey, Sergiu,
and David reported choppy GUI rendering, systems that became unresponsive
every few seconds, incorrect values reported by cpufreq, and high IRQ 16
CPU usage.

Joey bisected the issues to 0e8ae5a, so revert it until we figure out
a better solution.

Link: https://lore.kernel.org/r/20220210222717.GA658201@bhelgaas
Link: https://bugzilla.kernel.org/show_bug.cgi?id=215533
Link: https://bugzilla.kernel.org/show_bug.cgi?id=215546
Reported-by: Joey Corleone <joey.corleone@mail.ru>
Reported-by: Sergiu Deitsch <sergiu.deitsch@gmail.com>
Reported-by: David Spencer <dspencer577@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: stable@vger.kernel.org	# v5.16+
Cc: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
bjorn-helgaas authored and gregkh committed Feb 16, 2022
1 parent 4ad70fa commit 2d88a0f
Showing 1 changed file with 17 additions and 30 deletions.
47 changes: 17 additions & 30 deletions drivers/pci/pcie/portdrv_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ static int pcie_init_service_irqs(struct pci_dev *dev, int *irqs, int mask)
{
int ret, i;

for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++)
irqs[i] = -1;

/*
* If we support PME but can't use MSI/MSI-X for it, we have to
* fall back to INTx or other interrupts, e.g., a system shared
Expand Down Expand Up @@ -314,10 +317,8 @@ static int pcie_device_init(struct pci_dev *pdev, int service, int irq)
*/
int pcie_port_device_register(struct pci_dev *dev)
{
int status, capabilities, irq_services, i, nr_service;
int irqs[PCIE_PORT_DEVICE_MAXSERVICES] = {
[0 ... PCIE_PORT_DEVICE_MAXSERVICES-1] = -1
};
int status, capabilities, i, nr_service;
int irqs[PCIE_PORT_DEVICE_MAXSERVICES];

/* Enable PCI Express port device */
status = pci_enable_device(dev);
Expand All @@ -330,32 +331,18 @@ int pcie_port_device_register(struct pci_dev *dev)
return 0;

pci_set_master(dev);

irq_services = 0;
if (IS_ENABLED(CONFIG_PCIE_PME))
irq_services |= PCIE_PORT_SERVICE_PME;
if (IS_ENABLED(CONFIG_PCIEAER))
irq_services |= PCIE_PORT_SERVICE_AER;
if (IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE))
irq_services |= PCIE_PORT_SERVICE_HP;
if (IS_ENABLED(CONFIG_PCIE_DPC))
irq_services |= PCIE_PORT_SERVICE_DPC;
irq_services &= capabilities;

if (irq_services) {
/*
* Initialize service IRQs. Don't use service devices that
* require interrupts if there is no way to generate them.
* However, some drivers may have a polling mode (e.g.
* pciehp_poll_mode) that can be used in the absence of IRQs.
* Allow them to determine if that is to be used.
*/
status = pcie_init_service_irqs(dev, irqs, irq_services);
if (status) {
irq_services &= PCIE_PORT_SERVICE_HP;
if (!irq_services)
goto error_disable;
}
/*
* Initialize service irqs. Don't use service devices that
* require interrupts if there is no way to generate them.
* However, some drivers may have a polling mode (e.g. pciehp_poll_mode)
* that can be used in the absence of irqs. Allow them to determine
* if that is to be used.
*/
status = pcie_init_service_irqs(dev, irqs, capabilities);
if (status) {
capabilities &= PCIE_PORT_SERVICE_HP;
if (!capabilities)
goto error_disable;
}

/* Allocate child services if any */
Expand Down

0 comments on commit 2d88a0f

Please sign in to comment.