From: sashiko-bot@kernel.org
To: "Koichiro Den" <den@valinux.co.jp>
Cc: dmaengine@vger.kernel.org, linux-pci@vger.kernel.org,
Frank.Li@kernel.org, vkoul@kernel.org
Subject: Re: [PATCH v7 01/10] dmaengine: Allow drivers to assign static channel IDs
Date: Thu, 13 Aug 2026 06:51:45 +0000 [thread overview]
Message-ID: <20260813065145.74D771F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260813063757.3131865-2-den@valinux.co.jp>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
Pre-existing issues:
- [High] Memory and ID leak in the error rollback path of dma_async_device_register() when a subset of channels fail to register.
- [High] Directly calling kfree() on a device struct after device_register() fails, leading to kobject resource leaks and potential use-after-free.
- [High] dma_channel_rebalance() is called without holding dma_list_mutex when dynamically registering or unregistering channels.
- [Medium] device->chancnt is incremented without synchronization, leading to data races during dynamic channel registration.
--
--- Patch [1]: [PATCH v7 01/10] dmaengine: Allow drivers to assign static channel IDs ---
commit d88a921ed93cbdf57ab5a802c1f278694ad4200a
Author: Koichiro Den <den@valinux.co.jp>
dmaengine: Allow drivers to assign static channel IDs
The dmaengine core assigns channel IDs in registration order. If a driver skips
a hardware channel, chan_id can differ from the hardware numbering and a client
cannot reliably correlate a requested channel with hardware resources. Let a
driver request an exact channel ID before device registration.
Link: https://lore.kernel.org/r/lm7tadnxsyrypu4mypptlkx5qkytex4qxsijdr5ydud2n3anvf@yakjfjg5ng4u/
> diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
> index 6ffd8bd82154a..cc64a4679e6fa 100644
> --- a/drivers/dma/dmaengine.c
> +++ b/drivers/dma/dmaengine.c
> @@ -1078,6 +1078,7 @@ static int __dma_async_device_channel_register(struct dma_device *device,
> struct dma_chan *chan,
> const char *name)
> {
> + unsigned int id;
> int rc;
>
> chan->local = alloc_percpu(typeof(*chan->local));
[ ... ]
> - /*
> - * When the chan_id is a negative value, we are dynamically adding
> - * the channel. Otherwise we are static enumerating.
> - */
> - chan->chan_id = ida_alloc(&device->chan_ida, GFP_KERNEL);
> + if (chan->chan_id & DMA_CHAN_ID_STATIC) {
> + id = chan->chan_id & ~DMA_CHAN_ID_STATIC;
> + chan->chan_id = ida_alloc_range(&device->chan_ida, id, id,
> + GFP_KERNEL);
> + } else {
> + chan->chan_id = ida_alloc(&device->chan_ida, GFP_KERNEL);
> + }
> if (chan->chan_id < 0) {
> pr_err("%s: unable to alloc ida for chan: %d\n",
> __func__, chan->chan_id);
[Severity: High]
This is a pre-existing issue, but does the error rollback path in
dma_async_device_register() leak IDs?
drivers/dma/dmaengine.c:dma_async_device_register() {
...
err_out:
/* if we never registered a channel just release the idr */
if (!device->chancnt) {
ida_free(&dma_ida, device->dev_id);
return rc;
}
list_for_each_entry(chan, &device->channels, device_node) {
if (chan->local == NULL)
continue;
mutex_lock(&dma_list_mutex);
chan->dev->chan = NULL;
mutex_unlock(&dma_list_mutex);
device_unregister(&chan->dev->device);
free_percpu(chan->local);
}
return rc;
}
If channel registration fails and one or more channels were already successfully
registered (device->chancnt > 0), it skips ida_free(&dma_ida, device->dev_id).
Additionally, the rollback loop unregisters the previously successful channels
but appears to miss calling ida_free(&device->chan_ida, chan->chan_id), which
could permanently leak the channel IDs and their associated memory.
[Severity: High]
This is a pre-existing issue, but is it safe to use kfree() after
device_register() fails?
drivers/dma/dmaengine.c:__dma_async_device_channel_register() {
...
rc = device_register(&chan->dev->device);
if (rc)
goto err_out_ida;
...
err_out_ida:
ida_free(&device->chan_ida, chan->chan_id);
err_free_dev:
kfree(chan->dev);
err_free_local:
free_percpu(chan->local);
...
}
If device_register(&chan->dev->device) fails, the error handler directly calls
kfree(chan->dev).
Once device_initialize() has been called (internally by device_register()),
shouldn't put_device() be used to clean up the kobject state and avoid leaking
the device name string?
[Severity: High]
This is a pre-existing issue, but are these list operations safe from data
races?
drivers/dma/dmaengine.c:dma_async_device_channel_register() {
...
dma_channel_rebalance();
...
}
drivers/dma/dmaengine.c:dma_async_device_channel_unregister() {
...
dma_channel_rebalance();
...
}
When dynamically registering or unregistering channels, dma_channel_rebalance()
is called without acquiring dma_list_mutex.
Since dma_channel_rebalance() locklessly iterates over the global
dma_device_list, could this cause list corruption if another device is
concurrently registered or unregistered?
[Severity: Medium]
This is a pre-existing issue, but does device->chancnt need synchronization
here?
drivers/dma/dmaengine.c:__dma_async_device_channel_register() {
...
chan->client_count = 0;
device->chancnt++;
...
}
The increment device->chancnt++ is performed without holding dma_list_mutex or
any other lock.
If multiple channels are dynamically registered concurrently on the same device,
could updates to this counter be lost?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260813063757.3131865-1-den@valinux.co.jp?part=1
next prev parent reply other threads:[~2026-08-13 6:51 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-13 6:37 [PATCH v7 00/10] PCI: endpoint: Add PCI DMA endpoint function Koichiro Den
2026-08-13 6:37 ` [PATCH v7 01/10] dmaengine: Allow drivers to assign static channel IDs Koichiro Den
2026-08-13 6:51 ` sashiko-bot [this message]
2026-08-13 6:37 ` [PATCH v7 02/10] PCI: endpoint: Define endpoint DMA BAR metadata format Koichiro Den
2026-08-13 6:40 ` sashiko-bot
2026-08-13 6:37 ` [PATCH v7 03/10] PCI: endpoint: Add DMA auxiliary resource metadata Koichiro Den
2026-08-13 6:41 ` sashiko-bot
2026-08-13 6:37 ` [PATCH v7 04/10] PCI: endpoint: Add API to delegate EPC DMA channels to the host Koichiro Den
2026-08-13 6:46 ` sashiko-bot
2026-08-13 6:37 ` [PATCH v7 05/10] dmaengine: dw-edma: Add channel delegation helpers Koichiro Den
2026-08-13 6:50 ` sashiko-bot
2026-08-13 6:37 ` [PATCH v7 06/10] PCI: dwc: Implement endpoint DMA channel delegation Koichiro Den
2026-08-13 6:47 ` sashiko-bot
2026-08-13 6:37 ` [PATCH v7 07/10] PCI: dwc: Expose endpoint DMA resources Koichiro Den
2026-08-13 6:45 ` sashiko-bot
2026-08-13 6:37 ` [PATCH v7 08/10] dmaengine: dw-edma-pcie: Discover endpoint DMA metadata Koichiro Den
2026-08-13 6:50 ` sashiko-bot
2026-08-13 6:37 ` [PATCH v7 09/10] PCI: endpoint: Add DMA endpoint function Koichiro Den
2026-08-13 6:53 ` sashiko-bot
2026-08-13 6:37 ` [PATCH v7 10/10] Documentation: PCI: Add PCI DMA endpoint function documentation Koichiro Den
2026-08-13 6:46 ` sashiko-bot
2026-08-13 11:46 ` [PATCH v7 00/10] PCI: endpoint: Add PCI DMA endpoint function Niklas Cassel
2026-08-13 12:50 ` Manivannan Sadhasivam
2026-08-13 14:15 ` Koichiro Den
2026-08-13 15:59 ` Frank Li
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260813065145.74D771F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=Frank.Li@kernel.org \
--cc=den@valinux.co.jp \
--cc=dmaengine@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=vkoul@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.