Re: [PATCH 01/15] dmaengine: dw-edma: Cache DMA channel IDs in dw_edma_chip

Koichiro Den <[email protected]> Fri, 13 Mar 2026 17:51:18 +0900
Newsgroups dev.linux.lists.ntb,org.kernel.vger.dmaengine,org.kernel.vger.linux-doc,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pci
Message-ID <lrrh43qyixskxsbjnl5v4252zcqnbqsngvdfmj62eyjdhmen64@pjdypxohap6m>
On Thu, Mar 12, 2026 at 04:05:21PM -0400, Frank Li wrote:
> On Fri, Mar 13, 2026 at 01:49:51AM +0900, Koichiro Den wrote:
> > The exported-DMA path needs to describe each exposed descriptor window
> > with the DMAEngine channel ID that owns it. Those IDs are only assigned
> > once the channels have been registered.
> >
> > Cache the dma_chan IDs in dw_edma_chip after registration so controller
> > frontends can later publish them as auxiliary-resource metadata without
> > reaching back into the live channel objects.
> >
> > Signed-off-by: Koichiro Den <[email protected]>
> > ---
> >  drivers/dma/dw-edma/dw-edma-core.c | 18 +++++++++++++++++-
> >  include/linux/dma/edma.h           |  4 ++++
> >  2 files changed, 21 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c
> > index cd34a3ea602d..a13beacce2e7 100644
> > --- a/drivers/dma/dw-edma/dw-edma-core.c
> > +++ b/drivers/dma/dw-edma/dw-edma-core.c
> > @@ -837,6 +837,7 @@ static int dw_edma_channel_setup(struct dw_edma *dw, u32 wr_alloc, u32 rd_alloc)
> >  	struct dma_device *dma;
> >  	u32 i, ch_cnt;
> >  	u32 pos;
> > +	int ret;
> >
> >  	ch_cnt = dw->wr_ch_cnt + dw->rd_ch_cnt;
> >  	dma = &dw->dma;
> > @@ -932,7 +933,22 @@ static int dw_edma_channel_setup(struct dw_edma *dw, u32 wr_alloc, u32 rd_alloc)
> >  	dma_set_max_seg_size(dma->dev, U32_MAX);
> >
> >  	/* Register DMA device */
> > -	return dma_async_device_register(dma);
> > +	ret = dma_async_device_register(dma);
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* Cache dma_chan.id in dw_edma_chip */
> > +	for (i = 0; i < ch_cnt; i++) {
> > +		chan = &dw->chan[i];
> > +
> > +		if (i < dw->wr_ch_cnt)
> > +			chip->chan_ids_wr[i] = chan->vc.chan.chan_id;
> > +		else
> > +			chip->chan_ids_rd[i - dw->wr_ch_cnt] =
> > +						chan->vc.chan.chan_id;
> > +	}
> 
> why need cache in dw_edma_chip? you's cache into chan.

The reason I cached dma_chan::chan_id in dw_edma_chip is that
dw_pcie_ep_get_aux_resources() later needs to populate
PCI_EPC_AUX_DMA_CHAN_DESC with a key that can be matched against the struct
dma_chan instances returned by repeated dma_request_channel().

The delegated set returned by repeated dma_request_channel() is not
guaranteed to correspond to the first N READ channels, since some READ
channels may already be in use by another local consumer. So I do need some
explicit matching key.

If you have a cleaner way to correlate a delegated struct dma_chan with the
corresponding pci_epc_aux_resource, I would be happy to rework it.

(More fundamentally, for sparse channels export I think we will eventually
need to carry the hardware channel number separately as well.)

Thanks,
Koichiro

> 
> Frank
> > +
> > +	return 0;
> >  }
> >
> >  static inline void dw_edma_dec_irq_alloc(int *nr_irqs, u32 *alloc, u16 cnt)
> > diff --git a/include/linux/dma/edma.h b/include/linux/dma/edma.h
> > index 9da53c75e49b..0b861e8d305e 100644
> > --- a/include/linux/dma/edma.h
> > +++ b/include/linux/dma/edma.h
> > @@ -100,6 +100,10 @@ struct dw_edma_chip {
> >  	int			db_irq;
> >  	resource_size_t		db_offset;
> >
> > +	/* dma_chan ids */
> > +	int			chan_ids_wr[EDMA_MAX_WR_CH];
> > +	int			chan_ids_rd[EDMA_MAX_RD_CH];
> > +
> >  	enum dw_edma_map_format	mf;
> >
> >  	struct dw_edma		*dw;
> > --
> > 2.51.0
> >