Re: bus: mhi: host: pci_generic: round up nr_irqs to a power of two

Javier Achirica <[email protected]> Thu, 2 Apr 2026 19:22:32 +0200
Newsgroups dev.linux.lists.mhi
Message-ID <CACixm23MW85ForXdy0k6D+iCZsW+MN9xTWs=xZ2ONkmQRvfqbA@mail.gmail.com>
On Thu, Apr 2, 2026 at 6:37 PM Manivannan Sadhasivam <[email protected]> wrote:
>
> On Thu, Apr 02, 2026 at 04:44:21PM +0200, Javier Achirica wrote:
> > Hello,
> >
> > I have an issue with a SDX55 modem in a TCL HH500V router, when trying
> > to make it work under kernel 6.12.x (OpenWrt).
> >
> > It looks like when an MHI device uses standard MSI, the PCI core
> > requires the allocated number of vectors to be a strict power of two.
> >
> > In this case, nr_irqs is 5, so the generated mask is wrong and it
> > won't properly work.
>
> Can you please explain what do you mean by 'won't properly work'?

Since 6.12.58, gicv2m_irq_domain_alloc in
drivers/irqchip/irq-gic-v2m.c looks like this:

....
        unsigned long align_mask = nr_irqs - 1;

        spin_lock(&v2m_lock);
        list_for_each_entry(tmp, &v2m_nodes, entry) {
                unsigned long align_off = tmp->spi_start -
(tmp->spi_start & ~align_mask);
....

If nr_irqs isn't a power of 2, align_mask won't be a proper mask (as
ending in 0's), so align_off won't be the expected alignment offset
and the interrupts won't be delivered properly.

In the specific case of nr_irqs = 5, align_mask will be 4 so
~align_mask will be 0xfffb instead of the expected 0xfff8.

> > It can be fixed by explicitly rounding up the
> > requested IRQ count using `roundup_pow_of_two()` before passing it to
> > `pci_alloc_irq_vectors()`.
> >
> > This patch, in 6.12.x tree, will fix it, but I'm not sure of the
> > impact of it on newer kernels and if it's the right way of fixing it.
> > Any tips on how to properly fix this issue?
> >
>
> This change is correct on its own. You just need to apply it to v7.0-rc1 and
> send it as proper patch to [email protected]. TBH this version itself is fine.
>
> But I'm more curious about the issue you are facing as we never saw it, though
> it is fundamentally wrong to request non-power-of-2 MSIs.

In the MHI PCI driver most of the devices request a non-power-of-2
irqs (they request one per event plus an additional one), so this
patch will fix that for all of them.

Javier

> - Mani
>
> > Thanks!
> > Javier
> >
> > Signed-off-by: Javier Achirica <[email protected]>
> > ---
> > diff --git a/drivers/bus/mhi/host/pci_generic.c
> > b/drivers/bus/mhi/host/pci_generic.c
> > --- a/drivers/bus/mhi/host/pci_generic.c        2026-02-19
> > 16:29:56.000000000 +0100
> > +++ b/drivers/bus/mhi/host/pci_generic.c        2026-03-29
> > 13:14:17.053879617 +0200
> > @@ -1014,7 +1014,7 @@
> >          */
> >         mhi_cntrl->nr_irqs = 1 + mhi_cntrl_config->num_events;
> >
> > -       nr_vectors = pci_alloc_irq_vectors(pdev, 1,
> > mhi_cntrl->nr_irqs, PCI_IRQ_MSI);
> > +       nr_vectors = pci_alloc_irq_vectors(pdev, 1,
> > roundup_pow_of_two(mhi_cntrl->nr_irqs), PCI_IRQ_MSI);
> >         if (nr_vectors < 0) {
> >                 dev_err(&pdev->dev, "Error allocating MSI vectors %d\n",
> >                         nr_vectors);
> >
>
> --
> மணிவண்ணன் சதாசிவம்