Re: [PATCH] PCI: brcmstb: Reserve only the MSI vectors that are handed out

Bjorn Helgaas <[email protected]> Tue, 4 Aug 2026 07:50:57 -0500
Newsgroups org.kernel.vger.linux-pci,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-kernel
Message-ID <20260804125057.GA1834533@bhelgaas>
[+cc Marc, author of 4615fbc3788d ("genirq/irqdomain: Don't try to
free an interrupt that has no mapping"), Thomas; beginning of thread
about multiple MSI vector alloc/free:
https://lore.kernel.org/all/[email protected]]

On Tue, Aug 04, 2026 at 08:31:23PM +0900, Han / 한상우Sangwoo wrote:
> > Several other PCI controller drivers have similar code.
> 
> I agree - eleven of them look like they can have the same problem.
> 
> > I think we should fix them all at once (or explain why they don't need
> > similar fixes).  Might be worth a little helper so they all work the
> > same way (e.g., some use order_base_2(), others use get_count_order(),
> > which seems like a pointless difference).
> 
> I am working on a related fix for drivers/irqchip/irq-bcm2712-mip.c,

Similar pattern there, but it uses ilog2(), which differs from
order_base_2() and get_count_order() in more cases.

> which I can test here.  I would rather not send changes to drivers I
> cannot test, though, so I am leaving the eleven to whoever has the boards.
> What I looked at is in the appendix, in case it is useful to them.
> 
> Two things seem more useful from where I am sitting.
> 
>  - The failure is silent.  Appendix A describes the symptom, so that
>    anyone who hits it later can find this thread.
> 
>  - The contract is not written down.  It changed in 4615fbc3788d, where
>    irq_domain_free_irqs_hierarchy() started freeing one vector at a time.
> 
> order_base_2() and get_count_order() give the same answer for any
> nr_irqs >= 1, so consolidating those two is just cleanup.  Where a shared
> helper should live I am not sure either.

I don't know either, but I hate fixing an issue in one place and
leaving the same issue unfixed nearby.

> Appendix A - the symptom
> ========================
> 
> A PCIe device whose driver is unbound and rebound a few times, or whose
> module is reloaded, ends up with fewer MSI vectors than it asked for.  It
> does not recover until reboot.
> 
> Two things have to be true for it to happen: the device uses multi-MSI,
> and the vector count it asks for is not a power of two.  Devices that ask
> for a power of two are unaffected, and so is anything on MSI-X.
> 
> I have only seen the reduced-vector case.  A driver that insists on the
> full count would fail to probe instead, but I have not seen that happen.
> 
> 
> Appendix B - how I sorted the drivers
> =====================================
> 
> I went through drivers/pci/controller/ while working out what my own fix
> had to do, so this is that rather than a full audit.  Twenty of the
> drivers own an MSI hwirq pool.  I asked three things about each:
> 
>  - does .alloc reserve a rounded-up block, or a single slot
>  - does the core hand .free one vector at a time
>  - can nr_irqs > 1 reach the driver at all
> 
> Eleven answer yes to all three:
> 
>   dwc/pcie-designware-host.c   pci-aardvark.c        pcie-apple.c
>   pcie-aspeed.c                pcie-iproc-msi.c      pcie-mediatek-gen3.c
>   pcie-rcar-host.c             pcie-rzg3s-host.c     pcie-xilinx-dma-pl.c
>   pcie-xilinx-nwl.c            pci-hyperv.c
> 
> The other nine:
> 
>  - five reserve a single slot, so nothing rounds up:
>    mobiveil/pcie-mobiveil-host.c, pci-xgene-msi.c, pcie-altera-msi.c,
>    pcie-mediatek.c, plda/pcie-plda-host.c
> 
>  - vmd.c keeps a per-vector refcount instead of a bitmap
> 
>  - pci-tegra.c and pcie-xilinx.c reserve a rounded-up block, but neither
>    lists MSI_FLAG_MULTI_PCI_MSI in msi_parent_ops.supported_flags
> 
>  - pcie-brcmstb.c is the one you applied