Re: [PATCH v3 07/11] dmaengine: switchtec-dma: disable channels before freeing on registration failure
Frank Li <[email protected]> Mon, 27 Jul 2026 17:21:36 -0400
| Newsgroups | org.kernel.vger.dmaengine,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pci |
|---|---|
| Message-ID | <amfL4H-ddHGONlUl@lizhi-Precision-Tower-5810> |
On Mon, Jul 27, 2026 at 12:15:22PM -0600, Logan Gunthorpe wrote: > When switchtec_dma_create() fails after channels have been added to > dma_dev->channels (either from switchtec_dma_chans_enumerate()'s own > error path, or from dma_async_device_register() failing), the channels > are released and freed but never removed from dma_dev->channels. > > Add switchtec_dma_chans_disable() which disables interrupts and > removes the channels from the list.. Call it before releasing and > freeing channels in both error paths. > > Reported-by: Sashiko <[email protected]> > Link: https://lore.kernel.org/dmaengine/[email protected] > Link: https://lore.kernel.org/dmaengine/[email protected] > Signed-off-by: Logan Gunthorpe <[email protected]> > --- > drivers/dma/switchtec_dma.c | 16 ++++++++++++++++ > 1 file changed, 16 insertions(+) > > diff --git a/drivers/dma/switchtec_dma.c b/drivers/dma/switchtec_dma.c > index 31feb2816e79..800d8ecd0717 100644 > --- a/drivers/dma/switchtec_dma.c > +++ b/drivers/dma/switchtec_dma.c > @@ -1184,6 +1184,20 @@ static void switchtec_dma_chans_free(struct switchtec_dma_dev *swdma_dev) > kfree(swdma_dev->swdma_chans); > } > > +static void switchtec_dma_chans_disable(struct pci_dev *pdev, > + struct switchtec_dma_dev *swdma_dev) > +{ > + int i; > + > + if (swdma_dev->chan_status_irq >= 0) { > + pci_free_irq(pdev, swdma_dev->chan_status_irq, swdma_dev); > + swdma_dev->chan_status_irq = -1; > + } > + > + for (i = 0; i < swdma_dev->chan_cnt; i++) > + list_del(&swdma_dev->swdma_chans[i]->dma_chan.device_node); > +} > + Maybe historic reason, it is not good to touch dma_chan::device_node. Suppose some hepler function to manage channels. Reviewed-by: Frank Li <[email protected]> > static int switchtec_dma_chans_enumerate(struct switchtec_dma_dev *swdma_dev, > struct pci_dev *pdev, int chan_cnt) > { > @@ -1217,6 +1231,7 @@ static int switchtec_dma_chans_enumerate(struct switchtec_dma_dev *swdma_dev, > return chan_cnt; > > err_exit: > + switchtec_dma_chans_disable(pdev, swdma_dev); > switchtec_dma_chans_release(pdev, swdma_dev); > switchtec_dma_chans_free(swdma_dev); > > @@ -1320,6 +1335,7 @@ static int switchtec_dma_create(struct pci_dev *pdev) > return 0; > > err_chans_release_exit: > + switchtec_dma_chans_disable(pdev, swdma_dev); > switchtec_dma_chans_release(pdev, swdma_dev); > switchtec_dma_chans_free(swdma_dev); > > -- > 2.47.3 >