Re: [PATCH v2 3/3] dmaengine: dw-edma: Account for the MSI vector offset
From: Koichiro Den
Date: Sat Aug 29 2026 - 13:44:10 EST
On Fri, Aug 28, 2026 at 01:46:17PM -0500, Frank Li wrote:
> On Sat, Aug 29, 2026 at 01:36:11AM +0900, Koichiro Den wrote:
> > get_cached_msi_msg() returns the base message shared by a multi-MSI
> > descriptor. dw-edma currently derives per-channel data from its local IRQ
> > index and does not adjust a common IRQ at all. Both assume eDMA starts at
> > the descriptor's first vector.
> >
> > That is not true when eDMA receives a tail subset. Compose each message
> > from the IRQ offset relative to the descriptor base in both paths.
> >
> > While at it, avoid reading PCI MSI attributes from descriptors owned by
> > non-PCI devices.
> >
> > Signed-off-by: Koichiro Den <den@xxxxxxxxxxxxx>
> > ---
> > Changes in v2:
> > - Rework v1 patch 5 for an MSI allocation shared with vNTB.
> > https://lore.kernel.org/r/20260312165005.1148676-6-den@xxxxxxxxxxxxx/
> >
> > drivers/dma/dw-edma/dw-edma-core.c | 24 +++++++++++++++---------
> > 1 file changed, 15 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c
> > index a8c6bd508fcd..6af8a414e4a2 100644
> > --- a/drivers/dma/dw-edma/dw-edma-core.c
> > +++ b/drivers/dma/dw-edma/dw-edma-core.c
> > @@ -7,6 +7,7 @@
> > */
> >
> > #include <linux/module.h>
> > +#include <linux/pci.h>
> > #include <linux/delay.h>
> > #include <linux/device.h>
> > #include <linux/kernel.h>
> > @@ -1075,12 +1076,23 @@ static inline void dw_edma_dec_irq_alloc(int *nr_irqs, u32 *alloc, u16 cnt)
> > }
> > }
> >
> > +static void dw_edma_compose_msi(int irq, struct msi_msg *msi)
^(A)
> > +{
> > + struct msi_desc *desc = irq_get_msi_desc(irq);
> > +
> > + if (!desc)
> > + return;
> > +
> > + get_cached_msi_msg(irq, msi);
> > + if (dev_is_pci(desc->dev) && !desc->pci.msi_attrib.is_msix)
> > + msi->data += irq - desc->irq;
> > +}
> > +
> > static int dw_edma_irq_request(struct dw_edma *dw,
> > u32 *wr_alloc, u32 *rd_alloc)
> > {
> > struct dw_edma_chip *chip = dw->chip;
> > struct device *dev = dw->chip->dev;
> > - struct msi_desc *msi_desc;
> > int i, err = 0;
> > u32 ch_cnt;
> > int irq;
> > @@ -1105,8 +1117,7 @@ static int dw_edma_irq_request(struct dw_edma *dw,
> > return err;
> > }
> >
> > - if (irq_get_msi_desc(irq))
> > - get_cached_msi_msg(irq, &dw->irq[0].msi);
> > + dw_edma_compose_msi(irq, &dw->irq[0].msi);
>
> where this function? I missed dependence?
It's defined just above in this patch, as shown in (A).
Best regards,
Koichiro
>
> Frank
> >
> > dw->nr_irqs = 1;
> > } else {
> > @@ -1129,12 +1140,7 @@ static int dw_edma_irq_request(struct dw_edma *dw,
> > &dw->irq[i]);
> > if (err)
> > goto err_irq_free;
> > - msi_desc = irq_get_msi_desc(irq);
> > - if (msi_desc) {
> > - get_cached_msi_msg(irq, &dw->irq[i].msi);
> > - if (!msi_desc->pci.msi_attrib.is_msix)
> > - dw->irq[i].msi.data = dw->irq[0].msi.data + i;
> > - }
> > + dw_edma_compose_msi(irq, &dw->irq[i].msi);
> > }
> >
> > dw->nr_irqs = i;
> > --
> > 2.51.0
> >