All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: Frank.Li@oss.nxp.com
Cc: dmaengine@vger.kernel.org, Frank.Li@kernel.org,
	imx@lists.linux.dev, linux-pci@vger.kernel.org, vkoul@kernel.org
Subject: Re: [PATCH v6 7/9] nvmet: pci-epf: Use dmaengine_prep_config_single_safe() API
Date: Thu, 21 May 2026 01:39:56 +0000	[thread overview]
Message-ID: <20260521013956.816211F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260520-dma_prep_config-v6-7-06e49b7acb38@nxp.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] Removing the mutex introduces a cascading teardown failure and use-after-free where a single DMA timeout forcefully terminates all concurrent transfers on the shared channel.
- [High] Massive CPU wastage and starvation due to un-serialized concurrent busy-waiting on the DMA channel.
- [Low] Unused mutex fields and their initialization/teardown code were left behind in the structure and lifecycle functions.
--

commit 9bda24c8bcaef3ff0459f6035b72408052dec87b
Author: Frank Li <Frank.Li@nxp.com>

nvmet: pci-epf: Use dmaengine_prep_config_single_safe() API

This commit replaces dmaengine_slave_config() and dmaengine_prep_slave_single()
with dmaengine_prep_config_single_safe(), combining the configuration and
preparation into a single call. It also removes the mutex locks under the
assumption that atomic configuration makes them unnecessary.

> diff --git a/drivers/nvme/target/pci-epf.c b/drivers/nvme/target/pci-epf.c
> index 2afe8f4d0e461..f917d6ec278b7 100644
> --- a/drivers/nvme/target/pci-epf.c
> +++ b/drivers/nvme/target/pci-epf.c
> @@ -368,18 +368,15 @@ static int nvmet_pci_epf_dma_transfer(struct nvmet_pci_epf *nvme_epf,
>  	struct dma_chan *chan;
>  	dma_cookie_t cookie;
>  	dma_addr_t dma_addr;
> -	struct mutex *lock;
>  	int ret;
>  
>  	switch (dir) {
>  	case DMA_FROM_DEVICE:
> -		lock = &nvme_epf->dma_rx_lock;
>  		chan = nvme_epf->dma_rx_chan;
>  		sconf.direction = DMA_DEV_TO_MEM;
>  		sconf.src_addr = seg->pci_addr;
>  		break;
>  	case DMA_TO_DEVICE:
> -		lock = &nvme_epf->dma_tx_lock;

[Severity: Low]
Are the dma_tx_lock and dma_rx_lock fields still needed in struct nvmet_pci_epf?

Since the locks are no longer used here, it seems the field declarations
and their initialization/teardown code might have been left behind.

>  		chan = nvme_epf->dma_tx_chan;
>  		sconf.direction = DMA_MEM_TO_DEV;
>  		sconf.dst_addr = seg->pci_addr;

[ ... ]

> @@ -388,22 +385,15 @@ static int nvmet_pci_epf_dma_transfer(struct nvmet_pci_epf *nvme_epf,
>  		return -EINVAL;
>  	}
>  
> -	mutex_lock(lock);
> -

[Severity: High]
Does removing the mutex introduce concurrent busy-waiting on the shared DMA
channel?

dma_sync_wait() internally uses a cpu_relax() loop to busy-wait for hardware
completion. Before this patch, the mutex ensured only one thread actively
polled the hardware at a time, while other concurrent workers slept efficiently
on mutex_lock().

By removing the mutex, it appears multiple worker threads could concurrently
enter dma_sync_wait() on the same channel, unnecessarily consuming 100% of
multiple CPU cores and potentially causing CPU exhaustion.

[Severity: High]
Can removing the mutex also lead to a cascading teardown failure and
use-after-free?

Because the mutex was removed, multiple worker threads can concurrently submit
and wait on the shared dma_tx_chan or dma_rx_chan. If one transfer times out
in dma_sync_wait(), the error path calls dmaengine_terminate_sync(chan).

It looks like this would forcefully abort the shared channel, destroying all
other active and pending descriptors belonging to concurrent NVMe commands.

Also, if Thread A calls dmaengine_terminate_sync(chan) while Thread B is
between dmaengine_prep_config_single_safe() and dmaengine_submit():

Thread B:
	desc = dmaengine_prep_config_single_safe(...)
	// Thread A calls dmaengine_terminate_sync() here
	cookie = dmaengine_submit(desc);

Could Thread B's descriptor be freed by the termination, resulting in a
use-after-free when Thread B attempts to submit it?

>  	dma_dev = dmaengine_get_dma_device(chan);
>  	dma_addr = dma_map_single(dma_dev, seg->buf, seg->length, dir);
>  	ret = dma_mapping_error(dma_dev, dma_addr);

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260520-dma_prep_config-v6-0-06e49b7acb38@nxp.com?part=7

  reply	other threads:[~2026-05-21  1:39 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-20 22:00 [PATCH v6 0/9] dmaengine: Add new API to combine configuration and descriptor preparation Frank.Li
2026-05-20 22:00 ` [PATCH v6 1/9] dmaengine: Add API to combine configuration and preparation (sg and single) Frank.Li
2026-05-20 22:00 ` [PATCH v6 2/9] dmaengine: Add safe API to combine configuration and preparation Frank.Li
2026-05-21  0:01   ` sashiko-bot
2026-05-21 14:56     ` Frank Li
2026-05-20 22:00 ` [PATCH v6 3/9] PCI: endpoint: pci-epf-test: Use dmaenigne_prep_config_single() to simplify code Frank.Li
2026-05-20 22:00 ` [PATCH v6 4/9] dmaengine: dw-edma: Use new .device_prep_config_sg() callback Frank.Li
2026-05-21  0:31   ` sashiko-bot
2026-05-21 14:59     ` Frank Li
2026-05-20 22:00 ` [PATCH v6 5/9] dmaengine: dw-edma: Pass dma_slave_config to dw_edma_device_transfer() Frank.Li
2026-05-21  0:51   ` sashiko-bot
2026-05-21 15:02     ` Frank Li
2026-05-20 22:00 ` [PATCH v6 6/9] nvmet: pci-epf: Remove unnecessary dmaengine_terminate_sync() on each DMA transfer Frank.Li
2026-05-20 22:00 ` [PATCH v6 7/9] nvmet: pci-epf: Use dmaengine_prep_config_single_safe() API Frank.Li
2026-05-21  1:39   ` sashiko-bot [this message]
2026-05-21 15:08     ` Frank Li
2026-05-20 22:00 ` [PATCH v6 8/9] PCI: epf-mhi: Use dmaengine_prep_config_single() to simplify code Frank.Li
2026-05-21  2:08   ` sashiko-bot
2026-05-21 15:09     ` Frank Li
2026-05-20 22:00 ` [PATCH v6 9/9] crypto: atmel: Use dmaengine_prep_config_sg() API Frank.Li
2026-05-21  2:33   ` sashiko-bot
2026-05-21 15:11     ` 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=20260521013956.816211F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=Frank.Li@kernel.org \
    --cc=Frank.Li@oss.nxp.com \
    --cc=dmaengine@vger.kernel.org \
    --cc=imx@lists.linux.dev \
    --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.