Re: [PATCH] PCI: dwc: fall back to legacy IRQs when multiple devices are attached

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Apr 27, 2017 at 8:32 AM, Tim Harvey <tharvey@xxxxxxxxxxxxx> wrote:
> On Thu, Apr 27, 2017 at 1:43 AM, Lucas Stach <l.stach@xxxxxxxxxxxxxx> wrote:
>> Am Mittwoch, den 26.04.2017, 14:11 -0700 schrieb Tim Harvey:
>>> On Wed, Apr 26, 2017 at 11:15 AM, Lucas Stach <l.stach@xxxxxxxxxxxxxx> wrote:
>>> > The DWC host does not support legacy PCI IRQs and MSIs at the same time,
>>> > so we need to fall back to using only legacy IRQs if there is a chance
>>> > that multiple devices with differing MSI capabilities are connected to
>>> > the host. The only configuration where MSIs can be safely used is when
>>> > the device below the host bridge is not a bridge, i.e. the only device
>>> > connected to this host.
>>> >
>>> > By disallowing MSI allocation when multiple devices might be attached
>>> > we get those configurations in a working state. The only configurations
>>> > that depend on MSIs being available, that I am aware of, are some
>>> > embedded devices with a PCIe attached FPGA, that is incapable of
>>> > generating PCI legacy IRQs. Those are kept working by allowing MSIs
>>> > when only a single device is attached to the host.
>>> >
>>> > Signed-off-by: Lucas Stach <l.stach@xxxxxxxxxxxxxx>
>>> > ---
>>> >  drivers/pci/dwc/pcie-designware-host.c | 24 ++++++++++++++++++++++--
>>> >  drivers/pci/dwc/pcie-designware.h      |  1 +
>>> >  2 files changed, 23 insertions(+), 2 deletions(-)
>>> >
>>> > diff --git a/drivers/pci/dwc/pcie-designware-host.c b/drivers/pci/dwc/pcie-designware-host.c
>>> > index 5ba334938b52..be2b2762c944 100644
>>> > --- a/drivers/pci/dwc/pcie-designware-host.c
>>> > +++ b/drivers/pci/dwc/pcie-designware-host.c
>>> > @@ -92,6 +92,8 @@ void dw_pcie_msi_init(struct pcie_port *pp)
>>> >                             (u32)(msi_target & 0xffffffff));
>>> >         dw_pcie_wr_own_conf(pp, PCIE_MSI_ADDR_HI, 4,
>>> >                             (u32)(msi_target >> 32 & 0xffffffff));
>>> > +
>>> > +       pp->msi_disabled = false;
>>> >  }
>>> >
>>> >  static void dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq)
>>> > @@ -136,9 +138,11 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq)
>>> >  static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
>>> >  {
>>> >         int irq, pos0, i;
>>> > -       struct pcie_port *pp;
>>> > +       struct pcie_port *pp = (struct pcie_port *)msi_desc_to_pci_sysdata(desc);
>>> > +
>>> > +       if (pp->msi_disabled)
>>> > +               return -EINVAL;
>>> >
>>> > -       pp = (struct pcie_port *)msi_desc_to_pci_sysdata(desc);
>>> >         pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
>>> >                                        order_base_2(no_irqs));
>>> >         if (pos0 < 0)
>>> > @@ -410,6 +414,22 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>> >                 goto error;
>>> >         }
>>> >
>>> > +       /*
>>> > +        * The DWC host does not support legacy PCI IRQs and MSIs at the same
>>> > +        * time, so we need to fall back to using only legacy IRQs if there is
>>> > +        * a chance that multiple devices with differing MSI capabilities are
>>> > +        * connected to the host. The only configuration where MSIs can be
>>> > +        * safely used is when the device below the host bridge is not a bridge,
>>> > +        * i.e. the only device connected to this host.
>>> > +        */
>>> > +       child = list_first_entry(&bus->children, struct pci_bus, node);
>>> > +       if (!list_empty(&child->devices)) {
>>> > +               struct pci_dev *dev = list_first_entry(&child->devices,
>>> > +                                                      struct pci_dev, bus_list);
>>> > +               if (pci_is_bridge(dev))
>>> > +                       pp->msi_disabled = true;
>>> > +       }
>>> > +
>>> >         if (pp->ops->scan_bus)
>>> >                 pp->ops->scan_bus(pp);
>>> >
>>> > diff --git a/drivers/pci/dwc/pcie-designware.h b/drivers/pci/dwc/pcie-designware.h
>>> > index cd3b8713fe50..741bc31f8947 100644
>>> > --- a/drivers/pci/dwc/pcie-designware.h
>>> > +++ b/drivers/pci/dwc/pcie-designware.h
>>> > @@ -140,6 +140,7 @@ struct pcie_port {
>>> >         struct irq_domain       *irq_domain;
>>> >         unsigned long           msi_data;
>>> >         DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS);
>>> > +       bool                    msi_disabled;
>>> >  };
>>> >
>>> >  struct dw_pcie_ops {
>>> > --
>>> > 2.11.0
>>> >
>>>
>>> Lucas,
>>>
>>> Legacy interrupts are still not firing with this.
>>
>> Can you provide me the output of "cat /proc/interrupts" and "lspci -t"
>> on your system? I've tested this change on the GW54xx and legacy IRQs
>> seemed to work there.
>>
>
> Lucas,
>
> Right, I should have given you more detail. The legacy interrupts are
> firing for endpoints through a bridge, but not for boards without a
> bridge:
>
> GW54xx + ath9k:
> root@ventana:~# echo $(cat /proc/device-tree/model)
> Gateworks Ventana i.MX6 Dual/Quad GW54XX
> root@ventana:~# cat /proc/interrupts
>            CPU0       CPU1       CPU2       CPU3
>  16:       4343       1141       2358       1998     GIC-0  29 Edge      twd
>  17:         91         79         76         65       GPC  55 Level
>   i.MX Timer Tick
>  18:      93375          0          0          0       GPC  13 Level     mxs-dma
>  19:      21611          0          0          0       GPC  15 Level     bch
>  20:          0          0          0          0       GPC 115 Level
>   120000.hdmi
>  21:          0          0          0          0       GPC   9 Level
>   130000.gpu
>  22:          0          0          0          0       GPC  10 Level
>   134000.gpu
>  24:          3          0          0          0       GPC 120 Level
>   mx6-pcie-msi, ath9k
> ^^^^ correct legacy irq and its firing (3 interrupts)
>  26:          0          0          0          0       GPC  32 Level
>   200c000.ecspi
>  27:          0          0          0          0       GPC  26 Level
>   2020000.serial
>  28:          0          0          0          0       GPC  46 Level
>   2028000.ssi
>  29:          0          0          0          0       GPC  47 Level
>   202c000.ssi
>  30:          0          0          0          0       GPC  50 Level
>   2034000.asrc
>  31:          0          0          0          0       GPC  12 Level
>   2040000.vpu
>  49:          0          0          0          0       GPC  81 Level
>   20c0000.wdog
>  50:          0          0          0          0       GPC  49 Level
>   imx_thermal
>  55:          0          0          0          0       GPC  19 Level
>   rtc alarm
>  61:          2          0          0          0       GPC   2 Level     sdma
>  62:          0          0          0          0       GPC  43 Level
>   2184000.usb
>  63:         30          0          0          0       GPC  40 Level
>   2184200.usb
>  64:       1699          0          0          0     GIC-0 150 Level
>   2188000.ethernet
>  65:          0          0          0          0     GIC-0 151 Level
>   2188000.ethernet
>  66:          0          0          0          0       GPC  24 Level     mmc0
>  67:         30          0          0          0       GPC  36 Level
>   21a0000.i2c
>  68:         92          0          0          0       GPC  37 Level
>   21a4000.i2c
>  69:        298          0          0          0       GPC  38 Level
>   21a8000.i2c
>  70:          0          0          0          0       GPC  18 Level     vdoa
>  71:        500          0          0          0       GPC  27 Level
>   21e8000.serial
>  72:          0          0          0          0       GPC  30 Level
>   21f4000.serial
>  75:          0          0          0          0       GPC  39 Level
>   ahci-imx[2200000.sata]
>  76:          0          0          0          0       GPC  11 Level
>   2204000.gpu
> 271:          0          0          0          0  gpio-mxc   0 Edge
>   2198000.usdhc cd
> 335:          0          0          0          0       GPC 123 Level
>   PCIe PME, aerdrv
> 338:          0          0          0          0       IPU 457 Edge
>   2400000.ipu
> 339:          0          0          0          0       IPU 451 Edge
>   2400000.ipu
> 340:          0          0          0          0       IPU 457 Edge
>   2800000.ipu
> 341:          0          0          0          0       IPU 451 Edge
>   2800000.ipu
> 342:       1029          1          1          0       IPU  23 Edge      imx_drm
> 343:          0          0          0          0       IPU  28 Edge      imx_drm
> 344:          0          0          0          0       IPU  23 Edge      imx_drm
> 345:          0          0          0          0       IPU  28 Edge      imx_drm
> 346:          2          0          0          0       GPC 105 Level
>   2101000.jr0
> 347:          0          0          0          0       GPC 106 Level
>   2102000.jr1
> IPI0:          0          0          0          0  CPU wakeup interrupts
> IPI1:         25         36         15         22  Timer broadcast interrupts
> IPI2:        862       8482       4490       4783  Rescheduling interrupts
> IPI3:         36         29         41         44  Function call interrupts
> IPI4:          0          0          0          0  CPU stop interrupts
> IPI5:        229        174        430        250  IRQ work interrupts
> IPI6:          0          0          0          0  completion interrupts
> Err:          0
> root@ventana:~# lspci -t
> -[0000:00]---00.0-[01]--+-00.0-[02-09]--+-01.0-[03]--
>                         |               +-04.0-[04]--
>                         |               +-05.0-[05]--
>                         |               +-06.0-[06]--
>                         |               +-07.0-[07]----00.0
>                         |               +-08.0-[08]----00.0
>                         |               \-09.0-[09]--
>                         \-00.1
>
> GW51xx + ath9k (no bridge):
> root@ventana:~# echo $(cat /proc/device-tree/model)
> Gateworks Ventana i.MX6 Dual/Quad GW51XX
> root@ventana:~# cat /proc/interrupts
>            CPU0       CPU1       CPU2       CPU3
>  16:       3818        991       1747       2665     GIC-0  29 Edge      twd
>  17:         65         90         57         60       GPC  55 Level
>   i.MX Timer Tick
>  18:      39451          0          0          0       GPC  13 Level     mxs-dma
>  19:      10397          0          0          0       GPC  15 Level     bch
>  20:          0          0          0          0       GPC 115 Level
>   120000.hdmi
>  21:          0          0          0          0       GPC   9 Level
>   130000.gpu
>  22:          0          0          0          0       GPC  10 Level
>   134000.gpu
>  24:          0          0          0          0       GPC 120 Level
>   mx6-pcie-msi
>  26:          0          0          0          0       GPC  26 Level
>   2020000.serial
>  27:          0          0          0          0       GPC  50 Level
>   2034000.asrc
>  28:          0          0          0          0       GPC  12 Level
>   2040000.vpu
>  44:          0          0          0          0       GPC  49 Level
>   imx_thermal
>  49:          0          0          0          0       GPC  19 Level
>   rtc alarm
>  55:          0          0          0          0       GPC   2 Level     sdma
>  56:          0          0          0          0       GPC  43 Level
>   2184000.usb
>  57:          0          0          0          0       GPC  40 Level
>   2184200.usb
>  58:       2186          0          0          0     GIC-0 150 Level
>   2188000.ethernet
>  59:          0          0          0          0     GIC-0 151 Level
>   2188000.ethernet
>  60:         30          0          0          0       GPC  36 Level
>   21a0000.i2c
>  61:         61          0          0          0       GPC  37 Level
>   21a4000.i2c
>  62:          0          0          0          0       GPC  38 Level
>   21a8000.i2c
>  63:          0          0          0          0       GPC  18 Level     vdoa
>  64:        328          0          0          0       GPC  27 Level
>   21e8000.serial
>  65:          0          0          0          0       GPC  28 Level
>   21ec000.serial
>  66:          0          0          0          0       GPC  30 Level
>   21f4000.serial
>  69:          0          0          0          0       GPC  11 Level
>   2204000.gpu
>  80:          0          0          0          0  gpio-mxc   8 Level     ltc3676
> 296:          0          0          0          0   PCI-MSI   0 Edge
>   PCIe PME, aerdrv
> 328:          0          0          0          0       GPC 123 Level     ath9k
> ^^^^ correct legacy interrupt, but not firing (0 interrupts)
> 329:          0          0          0          0       IPU 457 Edge
>   2400000.ipu
> 330:          0          0          0          0       IPU 451 Edge
>   2400000.ipu
> 331:          0          0          0          0       IPU 457 Edge
>   2800000.ipu
> 332:          0          0          0          0       IPU 451 Edge
>   2800000.ipu
> 333:          0          0          0          0       IPU  23 Edge      imx_drm
> 334:          0          0          0          0       IPU  28 Edge      imx_drm
> 335:          0          0          0          0       IPU  23 Edge      imx_drm
> 336:          0          0          0          0       IPU  28 Edge      imx_drm
> 337:          2          0          0          0       GPC 105 Level
>   2101000.jr0
> 338:          0          0          0          0       GPC 106 Level
>   2102000.jr1
> IPI0:          0          0          0          0  CPU wakeup interrupts
> IPI1:         22         18         23         18  Timer broadcast interrupts
> IPI2:       1016       5415      18358       6131  Rescheduling interrupts
> IPI3:         40         44         34         50  Function call interrupts
> IPI4:          0          0          0          0  CPU stop interrupts
> IPI5:        455        152        326        609  IRQ work interrupts
> IPI6:          0          0          0          0  completion interrupts
> Err:          0
> root@ventana:~# lspci -t
> -[0000:00]---00.0-[01]----00.0
>
> A GW51xx + ath10k (no bridge, device requesting MSI interrupts) looks
> appropriate with the patch (uses MSI):
> root@ventana:~# echo $(cat /proc/device-tree/model)
> Gateworks Ventana i.MX6 Dual/Quad GW51XX
> root@ventana:~# cat /proc/interrupts
>            CPU0       CPU1       CPU2       CPU3
>  16:       1759       1224        771       2368     GIC-0  29 Edge      twd
>  17:         38         88         71         62       GPC  55 Level
>   i.MX Timer Tick
>  18:      39627          0          0          0       GPC  13 Level     mxs-dma
>  19:      10451          0          0          0       GPC  15 Level     bch
>  20:          0          0          0          0       GPC 115 Level
>   120000.hdmi
>  21:          0          0          0          0       GPC   9 Level
>   130000.gpu
>  22:          0          0          0          0       GPC  10 Level
>   134000.gpu
>  24:         78          0          0          0       GPC 120 Level
>   mx6-pcie-msi
>  26:          0          0          0          0       GPC  26 Level
>   2020000.serial
>  27:          0          0          0          0       GPC  50 Level
>   2034000.asrc
>  28:          0          0          0          0       GPC  12 Level
>   2040000.vpu
>  44:          0          0          0          0       GPC  49 Level
>   imx_thermal
>  49:          0          0          0          0       GPC  19 Level
>   rtc alarm
>  55:          0          0          0          0       GPC   2 Level     sdma
>  56:          0          0          0          0       GPC  43 Level
>   2184000.usb
>  57:          0          0          0          0       GPC  40 Level
>   2184200.usb
>  58:        806          0          0          0     GIC-0 150 Level
>   2188000.ethernet
>  59:          0          0          0          0     GIC-0 151 Level
>   2188000.ethernet
>  60:         30          0          0          0       GPC  36 Level
>   21a0000.i2c
>  61:         61          0          0          0       GPC  37 Level
>   21a4000.i2c
>  62:          0          0          0          0       GPC  38 Level
>   21a8000.i2c
>  63:          0          0          0          0       GPC  18 Level     vdoa
>  64:        201          0          0          0       GPC  27 Level
>   21e8000.serial
>  65:          0          0          0          0       GPC  28 Level
>   21ec000.serial
>  66:          0          0          0          0       GPC  30 Level
>   21f4000.serial
>  69:          0          0          0          0       GPC  11 Level
>   2204000.gpu
>  80:          0          0          0          0  gpio-mxc   8 Level     ltc3676
> 296:          0          0          0          0   PCI-MSI   0 Edge
>   PCIe PME, aerdrv
> 297:         78          0          0          0   PCI-MSI   1 Edge
>   ath10k_pci
> ^^^^ MSI interrupt and its firing (78 interrupts)
> 329:          0          0          0          0       IPU 457 Edge
>   2400000.ipu
> 330:          0          0          0          0       IPU 451 Edge
>   2400000.ipu
> 331:          0          0          0          0       IPU 457 Edge
>   2800000.ipu
> 332:          0          0          0          0       IPU 451 Edge
>   2800000.ipu
> 333:          0          0          0          0       IPU  23 Edge      imx_drm
> 334:          0          0          0          0       IPU  28 Edge      imx_drm
> 335:          0          0          0          0       IPU  23 Edge      imx_drm
> 336:          0          0          0          0       IPU  28 Edge      imx_drm
> 337:          2          0          0          0       GPC 105 Level
>   2101000.jr0
> 338:          0          0          0          0       GPC 106 Level
>   2102000.jr1
> IPI0:          0          0          0          0  CPU wakeup interrupts
> IPI1:         12         24         13         20  Timer broadcast interrupts
> IPI2:        905       7340      17490       6554  Rescheduling interrupts
> IPI3:         50         49         34         48  Function call interrupts
> IPI4:          0          0          0          0  CPU stop interrupts
> IPI5:        192        160         60         29  IRQ work interrupts
> IPI6:          0          0          0          0  completion interrupts
> Err:          0
> root@ventana:~# lspci -t
> -[0000:00]---00.0-[01]----00.0
> root@ventana:~# grep ath /proc/interrupts
> 297:         78          0          0          0   PCI-MSI   1 Edge
>   ath10k_pci
>
> Regards,
>
> Tim

Lucas,

Are you not able to repeat my findings?

Since Linux 4.8 IMX PCIe is completely broken for PCIe devices that do
not support MSI interrupts (and there are a whole lot of 802.11n
radios that fall into this category) as you can no longer disable MSI
because the IMX PCIe driver depends on it.

It seems like your patch is the right approach but something must
still be getting set that causes the legacy interrupts to not fire.

Regards,

Tim



[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux