[PATCH v2] dmaengine: switchtec-dma: Fix device reference leak in switchtec_dma_create()

From: Wentao Liang

Date: Fri Nov 06 2026 - 03:48:09 EST


switchtec_dma_create() takes a reference on the PCI device with
get_device() and stores it in dma->dev. The reference is normally
dropped by switchtec_dma_release(), the device_release() callback, which
only runs once dma_async_device_register() has succeeded and the device
is later unregistered. If the registration fails, the error path frees
the dma device directly without ever dropping that extra reference,
leaking the reference taken on the PCI device.

Drop the reference with put_device() on the error path.

Fixes: d9587042b50f ("dmaengine: switchtec-dma: Introduce Switchtec DMA engine skeleton")
Cc: stable@xxxxxxxxxxxxxxx
Reviewed-by: Logan Gunthorpe <logang@xxxxxxxxxxxx>
Signed-off-by: Wentao Liang <vulab@xxxxxxxxxxx>
---
Changes in v2:
- Rebase on top of the switchtec-dma fixes from Logan Gunthorpe, which
are now in mainline. The change itself is unchanged, so the Reviewed-by
tag is kept.
- Link to v1: https://lore.kernel.org/all/20260916093332.2003909-1-vulab@xxxxxxxxxxx/
- Sorry for the very late reply; thanks for pointing me at your series.

To Frank's question in the thread: no, switchtec_dma_remove() does not
need put_device() either. switchtec_dma_release() is reached through
dma_device_release() once the registered device gets unregistered, and
that is where the reference taken by get_device() belongs; dropping it in
remove() as well would put the PCI device reference twice.

drivers/dma/switchtec_dma.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/dma/switchtec_dma.c b/drivers/dma/switchtec_dma.c
index a386c3a284e6..713ba7ba1125 100644
--- a/drivers/dma/switchtec_dma.c
+++ b/drivers/dma/switchtec_dma.c
@@ -1333,6 +1333,7 @@ static int switchtec_dma_create(struct pci_dev *pdev)
switchtec_dma_chans_disable(pdev, swdma_dev);
switchtec_dma_chans_release(pdev, swdma_dev);
switchtec_dma_chans_free(swdma_dev);
+ put_device(dma->dev);

err_exit:
if (swdma_dev->chan_status_irq >= 0)
--
2.34.1