On Sat, 9 Oct 2021 at 06:20, Xin Xiong <xiongx18@xxxxxxxxxxxx> wrote: > > The issue happens in several error handling paths on two refcounted > object related to the object "host" (dma_chan_rx, dma_chan_tx). In > these paths, the function forgets to decrement one or both objects' > reference count increased earlier by dma_request_chan(), causing > reference count leaks. > > Fix it by balancing the refcounts of both objects in some error > handling paths. In correspondence with the changes in moxart_probe(), > IS_ERR() is replaced with IS_ERR_OR_NULL() in moxart_remove() as well. > > Signed-off-by: Xin Xiong <xiongx18@xxxxxxxxxxxx> > Signed-off-by: Xiyu Yang <xiyuyang19@xxxxxxxxxxxx> > Signed-off-by: Xin Tan <tanxin.ctf@xxxxxxxxx> Applied for next, thanks! Kind regards Uffe > --- > drivers/mmc/host/moxart-mmc.c | 16 ++++++++++++++-- > 1 file changed, 14 insertions(+), 2 deletions(-) > > diff --git a/drivers/mmc/host/moxart-mmc.c b/drivers/mmc/host/moxart-mmc.c > index 6c9d38132..7b9fcef49 100644 > --- a/drivers/mmc/host/moxart-mmc.c > +++ b/drivers/mmc/host/moxart-mmc.c > @@ -621,6 +621,14 @@ static int moxart_probe(struct platform_device *pdev) > ret = -EPROBE_DEFER; > goto out; > } > + if (!IS_ERR(host->dma_chan_tx)) { > + dma_release_channel(host->dma_chan_tx); > + host->dma_chan_tx = NULL; > + } > + if (!IS_ERR(host->dma_chan_rx)) { > + dma_release_channel(host->dma_chan_rx); > + host->dma_chan_rx = NULL; > + } > dev_dbg(dev, "PIO mode transfer enabled\n"); > host->have_dma = false; > } else { > @@ -675,6 +683,10 @@ static int moxart_probe(struct platform_device *pdev) > return 0; > > out: > + if (!IS_ERR_OR_NULL(host->dma_chan_tx)) > + dma_release_channel(host->dma_chan_tx); > + if (!IS_ERR_OR_NULL(host->dma_chan_rx)) > + dma_release_channel(host->dma_chan_rx); > if (mmc) > mmc_free_host(mmc); > return ret; > @@ -687,9 +699,9 @@ static int moxart_remove(struct platform_device *pdev) > > dev_set_drvdata(&pdev->dev, NULL); > > - if (!IS_ERR(host->dma_chan_tx)) > + if (!IS_ERR_OR_NULL(host->dma_chan_tx)) > dma_release_channel(host->dma_chan_tx); > - if (!IS_ERR(host->dma_chan_rx)) > + if (!IS_ERR_OR_NULL(host->dma_chan_rx)) > dma_release_channel(host->dma_chan_rx); > mmc_remove_host(mmc); > mmc_free_host(mmc); > -- > 2.25.1 >