Re: [PATCH v3 1/3] dmaengine: Fix device kref underflow in dma_chan_put()

Frank Li <[email protected]>
Newsgroups org.kernel.vger.dmaengine,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <aoMYDJ3TdCIqTbEd@SMW015318>
On Sun, Aug 16, 2026 at 03:49:25PM +0000, Shivank Garg wrote:
> [You don't often get email from [email protected]. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
>
> dma_chan_get() takes chan->device->ref only on the slow path:
>
>         /* no kref on fast path */
>         if (chan->client_count) {
>                 __module_get(owner);
>                 chan->client_count++;
>                 return 0;
>         }
>         if (!try_module_get(owner))
>                 return -ENODEV;
>         ret = kref_get_unless_zero(&chan->device->ref);
>
> dma_chan_put() drops the ref unconditionally, so every fast-path
> get/put pair drops one extra device reference.
>
> The bug fires when two conditions hold together: a non-private
> provider has a persistent client holding chan->client_count > 0
> and another client cycles dmaengine_get()/dmaengine_put().
> When the kref hits zero, the subsequent dma_find_channel() returns
> NULL even though the provider module is still loaded.
>
> Fix this by dropping device->ref only on the last put, matching the
> single slow-path get.
>
> Fixes: 8ad342a86359 ("dmaengine: Add reference counting to dma_device struct")
> Signed-off-by: Shivank Garg <[email protected]>
> ---

Nit: add helper dma_device_get() to match dma_device_put() to make code
more symmetry.

Reviewed-by: Frank Li <[email protected]>

>  drivers/dma/dmaengine.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
> index 6ffd8bd82154..516d6d933208 100644
> --- a/drivers/dma/dmaengine.c
> +++ b/drivers/dma/dmaengine.c
> @@ -515,7 +515,9 @@ static void dma_chan_put(struct dma_chan *chan)
>                 chan->route_data = NULL;
>         }
>
> -       dma_device_put(chan->device);
> +       /* This channel is not in use anymore, drop the device ref */
> +       if (!chan->client_count)
> +               dma_device_put(chan->device);
>         module_put(dma_chan_to_owner(chan));
>  }
>
>
> --
> 2.43.0
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.