From: sashiko-bot@kernel.org
To: "Allen Pais" <allen.lkml@gmail.com>
Cc: dmaengine@vger.kernel.org, vkoul@kernel.org, Frank.Li@kernel.org
Subject: Re: [PATCH v4 02/33] dmaengine: back channel BH helpers with WQ_BH
Date: Tue, 10 Nov 2026 14:15:38 +0000 [thread overview]
Message-ID: <sashiko-outbox-207180@kernel.org> (raw)
In-Reply-To: <717bb0b82658f1dd800f6b1bc06b9cf283f77361.1794315350.git.allen.lkml@gmail.com>
Thank you for your contribution! Sashiko AI review found 2 potential
issues to consider:
- [High] dmaengine: dmaengine_kill_bh() returns with bh_work still
queued on re-schedule
- [Medium] dmaengine: flush_work() in dmaengine_kill_bh() triggers flush
dependency warn
--
commit e183b161b65ac0da135cdea21e6916bb3483d703
Author: Allen Pais <allen.lkml@gmail.com>
dmaengine: back channel BH helpers with WQ_BH
This commit replaces the per-channel BH tasklet implementation with a
dedicated WQ_BH | WQ_PERCPU workqueue while keeping the dmaengine_*_bh() API
unchanged.
> diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
> index f3c1283b161b6..97d8f9667ae5f 100644
> --- a/drivers/dma/dmaengine.c
> +++ b/drivers/dma/dmaengine.c
[ ... ]
> @@ -1449,9 +1451,34 @@ static void dmaengine_destroy_unmap_pool(void)
[ ... ]
> +static void dmaengine_flush_bh_work(struct work_struct *work)
> +{
> + if (!work)
> + return;
> +
> + flush_work(work);
> +}
> +
> +static void dma_chan_bh_entry(struct work_struct *work)
> +{
> + struct dma_chan *chan = container_of(work, struct dma_chan, bh_work);
> dmaengine_bh_work_fn fn = READ_ONCE(chan->bh_work_fn);
>
> if (fn)
> @@ -1467,7 +1494,7 @@ void dmaengine_init_bh(struct dma_chan *chan, dmaengine_bh_work_fn fn)
[ ... ]
> @@ -1487,7 +1513,7 @@ void dmaengine_kill_bh(struct dma_chan *chan)
> if (!chan->bh_work_initialized)
> return;
>
> - tasklet_kill(&chan->bh_tasklet);
> + dmaengine_flush_bh_work(&chan->bh_work);
> }
> EXPORT_SYMBOL_GPL(dmaengine_kill_bh);
[Severity: High]
Can dmaengine_kill_bh() return with chan->bh_work still queued on the
workqueue?
Unlike tasklet_kill(), which holds TASKLET_STATE_SCHED while waiting for a
running tasklet to finish so concurrent tasklet_schedule() calls cannot
re-queue it, process_one_work() clears WORK_STRUCT_PENDING_BIT before
invoking dma_chan_bh_entry(). When flush_work() runs while chan->bh_work is
executing, insert_wq_barrier() places the flush barrier on worker->scheduled,
ahead of pool->worklist:
CPU0 CPU1 (bh_worker)
process_one_work(&chan->bh_work)
set_work_pool_and_clear_pending()
dma_chan_bh_entry()
dmaengine_kill_bh(chan)
flush_work(&chan->bh_work)
insert_wq_barrier()
...
dmaengine_schedule_bh(chan)
queue_work(..., &chan->bh_work)
/* dma_chan_bh_entry() returns */
process_scheduled_works()
/* runs barrier from
* worker->scheduled */
/* flush_work() returns */
kfree(chan)
/* processes pool->worklist */
dma_chan_bh_entry()
chan->bh_work_fn <-- use-after-free
This is a regression when chan->bh_work is re-queued while
dma_chan_bh_entry() is running, for example when a BH callback reschedules
itself (such as dma_tasklet() in ste_dma40 or mv_chan_slot_cleanup() in
mv_xor) or when a driver calls dmaengine_kill_bh() before tearing down its
IRQ or timer (such as mtk_cqdma_remove() or tegra_adma_free_chan_resources()).
Using cancel_work_sync(&chan->bh_work) or disable_work_sync(&chan->bh_work)
depending on whether the channel may be used again would wait for any
in-flight execution while preventing or draining concurrent re-schedules.
> @@ -1687,15 +1713,28 @@ EXPORT_SYMBOL_GPL(dma_run_dependencies);
>
> static int __init dma_bus_init(void)
> {
> - int err = dmaengine_init_unmap_pool();
> + int err;
>
> + dmaengine_bh_wq = alloc_workqueue("dmaengine_bh",
> + WQ_BH | WQ_PERCPU, 0);
[Severity: Medium]
Does calling dmaengine_kill_bh() from a WQ_MEM_RECLAIM workqueue or a
PF_MEMALLOC task trigger a WARN_ONCE() in check_flush_dependency()?
dmaengine_bh_wq does not have WQ_MEM_RECLAIM set (and WQ_BH workqueues cannot
set WQ_MEM_RECLAIM). Because dmaengine_kill_bh() calls flush_work(), which
passes from_cancel = false to __flush_work() -> check_flush_dependency(),
flushing a pending or running chan->bh_work from a WQ_MEM_RECLAIM context
hits the dependency warning:
kernel/workqueue.c:check_flush_dependency() {
if (from_cancel || target_wq->flags & WQ_MEM_RECLAIM)
return;
WARN_ONCE(current->flags & PF_MEMALLOC, ...);
WARN_ONCE((worker && ((worker->current_pwq->wq->flags &
(WQ_MEM_RECLAIM | __WQ_LEGACY)) == WQ_MEM_RECLAIM)), ...);
}
For example, sdhci allocates host->complete_wq with WQ_MEM_RECLAIM and runs
sdhci_complete_work() -> sdhci_request_done() -> dmaengine_terminate_sync()
-> dmaengine_synchronize() -> vchan_synchronize() -> dmaengine_kill_bh().
Using cancel_work_sync() or disable_work_sync() in dmaengine_kill_bh() sets
from_cancel = true and avoids this warning.
--
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1794315350.git.allen.lkml@gmail.com?part=2
next prev parent reply other threads:[~2026-11-10 14:15 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-10 13:13 [PATCH v4 00/33] dmaengine: migrate channel tasklets to WQ_BH Allen Pais
2026-11-10 13:13 ` [PATCH v4 01/33] dmaengine: add tasklet-backed channel BH helpers Allen Pais
2026-11-10 13:13 ` Allen Pais
2026-11-10 13:13 ` [PATCH v4 02/33] dmaengine: back channel BH helpers with WQ_BH Allen Pais
2026-11-10 14:15 ` sashiko-bot [this message]
2026-11-10 13:13 ` [PATCH v4 03/33] dmaengine: apple-admac: use dmaengine BH callback Allen Pais
2026-11-10 13:13 ` [PATCH v4 04/33] dmaengine: at_xdmac: move irq bottom half to dmaengine BH Allen Pais
2026-11-10 13:13 ` [PATCH v4 05/33] dmaengine: ep93xx: hook callbacks via " Allen Pais
2026-11-10 13:13 ` [PATCH v4 06/33] dmaengine: fsldma: migrate tasklet to " Allen Pais
2026-11-10 13:13 ` [PATCH v4 07/33] dmaengine: fsl_raid: run completions via " Allen Pais
2026-11-10 13:13 ` [PATCH v4 08/33] dmaengine: imx-dma: flip per-chan tasklet to " Allen Pais
2026-11-10 13:13 ` [PATCH v4 09/33] dmaengine: ioat: convert cleanup " Allen Pais
2026-11-10 13:13 ` [PATCH v4 10/33] dmaengine: mmp_pdma: replace per-chan tasklet with " Allen Pais
2026-11-10 13:13 ` [PATCH v4 11/33] dmaengine: mmp_tdma: hook completions to " Allen Pais
2026-11-10 13:13 ` [PATCH v4 12/33] dmaengine: mv_xor: convert irq tasklet " Allen Pais
2026-11-10 13:13 ` [PATCH v4 13/33] dmaengine: mxs-dma: use dmaengine BH scheduling Allen Pais
2026-11-10 13:13 ` [PATCH v4 14/33] dmaengine: nbpfaxi: switch callbacks to dmaengine BH Allen Pais
2026-11-10 13:13 ` [PATCH v4 15/33] dmaengine: pch_dma: convert tasklet " Allen Pais
2026-11-10 13:13 ` [PATCH v4 16/33] dmaengine: ppc4xx: replace irq tasklet with " Allen Pais
2026-11-10 13:13 ` [PATCH v4 17/33] dmaengine: ste_dma40: convert per-channel tasklet to " Allen Pais
2026-11-10 17:08 ` sashiko-bot
2026-11-10 13:13 ` [PATCH v4 18/33] dmaengine: xgene-dma: wire descriptor cleanup " Allen Pais
2026-11-10 13:13 ` [PATCH v4 19/33] dmaengine: xilinx-dma: use dmaengine BH instead of tasklets Allen Pais
2026-11-10 17:35 ` sashiko-bot
2026-11-10 13:13 ` [PATCH v4 20/33] dmaengine: xilinx-dpdma: kill vchan BH on remove Allen Pais
2026-11-10 13:13 ` [PATCH v4 21/33] dmaengine: zynqmp-dma: switch completion tasklet to dmaengine BH Allen Pais
2026-11-10 13:13 ` [PATCH v4 22/33] dmaengine: tegra20-apb: use channel BH helpers Allen Pais
2026-11-10 13:13 ` [PATCH v4 23/33] dmaengine: timb_dma: route callbacks via channel BH Allen Pais
2026-11-10 18:04 ` sashiko-bot
2026-11-10 13:13 ` [PATCH v4 24/33] dmaengine: txx9dmac: " Allen Pais
2026-11-10 13:13 ` [PATCH v4 25/33] dmaengine: mv_xor_v2: use channel BH helpers Allen Pais
2026-11-10 13:13 ` [PATCH v4 26/33] dmaengine: mpc512x: route callbacks via channel BH Allen Pais
2026-11-10 18:44 ` sashiko-bot
2026-11-10 13:13 ` [PATCH v4 27/33] dmaengine: plx_dma: use channel BH helpers Allen Pais
2026-11-10 13:13 ` [PATCH v4 28/33] dmaengine: sf-pdma: route error callbacks through channel BH Allen Pais
2026-11-10 13:13 ` Allen Pais
2026-11-10 19:08 ` sashiko-bot
2026-11-10 13:13 ` [PATCH v4 29/33] dmaengine: pl330: route callbacks via " Allen Pais
2026-11-10 13:13 ` [PATCH v4 30/33] dmaengine: altera-msgdma: use channel BH helpers Allen Pais
2026-11-11 2:39 ` NG, ADRIAN HO YIN
2026-11-10 13:13 ` [PATCH v4 31/33] dmaengine: hidma: defer callbacks via channel BH Allen Pais
2026-11-10 19:51 ` sashiko-bot
2026-11-10 13:13 ` [PATCH v4 32/33] dmaengine: qcom-gpi: defer callbacks via vchan Allen Pais
2026-11-10 13:13 ` [PATCH v4 33/33] dmaengine: switchtec: use channel BH helpers Allen Pais
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=sashiko-outbox-207180@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=Frank.Li@kernel.org \
--cc=allen.lkml@gmail.com \
--cc=dmaengine@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.