mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v6 0/9] dmaengine: add DMA channel bus and fsl-edma per-channel IOMMU support
@ 2026-11-12  7:53 Peng Fan (OSS)
  2026-11-12  7:53 ` [PATCH v6 1/9] dmaengine: fsl-edma: unregister channels before vchan cleanup Peng Fan (OSS)
                   ` (8 more replies)
  0 siblings, 9 replies; 15+ messages in thread
From: Peng Fan (OSS) @ 2026-11-12  7:53 UTC (permalink / raw)
  To: Frank Li, Vinod Koul, Joerg Roedel (AMD),
	Will Deacon, Robin Murphy, Laxman Dewangan, Jon Hunter,
	Thierry Reding, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: Frank Li, Larisa IIeana Grigore, imx, dmaengine, linux-kernel,
	iommu, linux-tegra, devicetree, linux-arm-kernel, Peng Fan

I used iommu-map for eDMA, but iommu experts rejected it:
"Using iommu-map to describe synthetic dma_chan_dev devices that the
kernel creates is the same kind of DT abuse from over here:"
More info: https://lore.kernel.org/all/20260917144804.GI3196566@ziepe.ca/

So I followed here [2] as Krzysztof wrote for QCOM VPU:
"Thanks Jason for context and detailed arguments. Robin did not chime in
yet, but from what I understood the DT-child-node approach will be the
way we should go here.

I accept above point of view and I am fine with this, thus Vishnu and
Vikash - please go ahead with DT-child-node solution we had some time ago."
[2] https://lore.kernel.org/linux-iommu/c7b956a9-d3e8-4e18-b780-5d08f5cd2ca1@kernel.org/

This series adds per-channel DT child node support to fsl-edma and, as a
prerequisite, introduces a proper bus for DMA channel devices.

The fsl-edma change allows each channel to carry its own reg, interrupts
and iommus properties.  Power domains remain attached at the parent level.
Parsing the child nodes is straightforward, but per-channel IOMMU
configuration is not: the DMA engine currently creates struct dma_chan_dev
as a class device without any bus, so of_dma_configure() has no bus to probe
the IOMMU with, and the IOMMU core does not have a bus notifier for DMA
channel devices.

Drivers that need per-channel IOMMU support currently work around this by
assigning dev->bus after dmaenginem_async_device_register().  That is unsafe
because bus_add_device() already ran with bus == NULL and did not take a bus
subsystem reference.  When the channel device is later unregistered,
bus_remove_device() drops a reference that was never acquired, leading to a
reference count underflow and a potential use-after-free.  Using
platform_bus_type is also wrong: platform_match() and platform_uevent()
expect the device to be embedded in a struct platform_device.

A dedicated bus for DMA channel devices solves this.  The channel devices are
converted from class devices to bus devices:

  - the bus is registered early, before iommu_subsys_init() consumes
    iommu_buses[];
  - the match callback always reports no match, so no driver binds to a
    channel device;
  - channel devices are registered on the bus before device_register(), so
    bus_add_device() and bus_remove_device() are balanced;
  - the bus is added to iommu_buses[], so the existing IOMMU notifier
    handles per-channel IOMMU probe and release.

The existing /sys/class/dma interface is preserved with class_compat, the
mechanism provided by the driver core for converting a class device family to
bus devices. A compatibility class named "dma" keeps
/sys/class/dma/dmaNchanM available, while the devices themselves live on the
DMA bus. The bus is named "dmaengine-chan" to avoid colliding with the SuperH DMA
bus, which is also named "dma". The uevent SUBSYSTEM and "subsystem" link
therefore use "dmaengine-chan", while /sys/class/dma is unchanged. dma_dev_groups
moves from the old class to the bus, and chan_dev_release is installed
directly as the device release callback.

While testing controller unbind, a pre-existing fsl-edma ordering bug was
found: fsl_edma_remove() removed all channels from dma_dev.channels before the
managed dma_async_device_unregister() action ran, so the channel devices and
their IOMMU groups were never released. Patch 1 fixes that ordering, which is
needed to make the bind/unbind lifecycle test meaningful.

Runtime-tested on i.MX95: repeated controller bind/unbind cycles with a
local DT based on the child-node conversion removed and recreated the
channel devices as expected, with no refcount, BUG, WARNING or suspicious
kobject diagnostics.  The per-channel IOMMU path was exercised with a local
DT adding iommus; that DT update is not part of this series.

The binding and driver support per-channel iommus, but patch 9 does not add
them to the i.MX95 DTS yet. That DT update will be sent separately when the
shared stream ID support are finalized.

I put all the patches in one patchset to give people a full picture.
If need to separate patches into multiple patchsets, I could do that
in next version.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
Changes in v6:
- Patch 2:
    Update commit message include more info regarding bus introduction. (Frank)
    name the DMA channel bus "dmaengine-chan" instead of "dma-chan" (Frank).
- Patch 6: new prep patch converting chan_masked tests from BIT() to
  BIT_ULL() for channels 32-63 (Frank).
- Patch 7: new prep patch converting fsl-edma to dmaengine_get_dma_device() (Frank).
- Patch 8: Use scoped api, avoid scan channel twice. (Frank)
- Link to v5: https://patch.msgid.link/20261111-edma-iommu-v3-v5-0-2537cebe6ca2@nxp.com

Changes in v5:
- Patch 2: Rename bus name to dma-chan per report from Sashiko.
- Patch 6: Address the issue reported by kernel bot:
  symbol '__udivdi3' undefined, using div_u64_rem
- Rebased to next-20261110
- Link to v4: https://lore.kernel.org/all/20261103-edma-iommu-v3-v4-0-470415d418c5@Example.Com/

Changes in v4:
- Patch 1, patch 4 and patch 5 are unchanged.
- Patch 2:
  Register the DMA channel bus from core_initcall so it exists before any
  IOMMU driver can call iommu_device_register(), which iterates
  iommu_buses[].
  Clean up the DMA unmap pools if dmaengine initialisation fails.
  Clarify that the bus match callback always reports no match.
- Patch 3:
  Update the ordering rationale for IOMMU drivers that register before
  arch_initcall. No functional change beyond patch 2's initcall move.
- Patch 6:
  - Validate child register resources: require them to be contained in the
    controller resource and aligned to chreg_space_sz.
  - Use div_u64() for the channel index calculation and reject values that
    do not fit in an int, avoiding 32-bit __aeabi_uldivmod/__udivdi3 issues.
  - Ignore child nodes beyond dma-channels, so imx95-navq.dts with
    dma-channels = <30> still probes.
  - Use BIT_ULL() for the 64-bit chan_masked bitmap, including channels
    32-63 on 32-bit builds.
  - Set chdev->dma_parms to the controller dma_parms so the per-channel
    device keeps the 0x7fff segment size limit.
  - Use dev_err_probe() for of_dma_configure() failures.
  - Reject channels for which iommus did not result in an IOMMU mapping
    instead of setting chan_dma_dev = true silently.
  - If child nodes are used, require every unmasked channel to have an
    available child node with a valid interrupt; otherwise fail probe with
    an error asking for dma-channel-mask.
  - Do not fall back to the parent flat interrupt array in child-node mode.
  - Keep the shared error IRQ on the parent node.
  - Clarify that child power-domains are not handled by this patch.
- Patch 7:
  - No functional change. The out-of-range child nodes used by
    imx95-navq.dts are handled by patch 6.
- The i.MX95 DTS still does not add per-channel iommus; that update will be
  submitted separately.
- Board test overlays are kept out of the upstream series.
- Link to v3: https://patch.msgid.link/20261102-edma-iommu-v3-v3-0-9d0e62a954eb@Example.Com

Changes in V3:
- Patch [1-4] are new patches
- Add R-b for patch 5
- Patch 6: handle of_irq_get() -EPROBE_DEFER, drop the explicit bus
  assignment to "chdev->bus" which is resolved by patch [2-4].
- Rebased to linus/master v7.4-rc1
Changes in V2:
- Switch to add child node for dma channel.
- Link to V1: https://lore.kernel.org/dmaengine/20260916-edma-iommu-v1-0-e1731968081e@nxp.com/

---
Peng Fan (9):
      dmaengine: fsl-edma: unregister channels before vchan cleanup
      dmaengine: add a bus for DMA channel devices
      iommu: register the DMA channel bus for IOMMU notifications
      dmaengine: move channel devices to the DMA channel bus
      dt-bindings: dma: fsl,edma: add per-channel child node support
      dmaengine: fsl-edma: use BIT_ULL for 64-bit channel mask
      dmaengine: fsl-edma: use dmaengine_get_dma_device()
      dmaengine: fsl-edma: support per-channel DT child nodes
      arm64: dts: imx95: convert eDMA to per-channel child nodes

 .../devicetree/bindings/dma/fsl,edma.yaml          |  70 +-
 arch/arm64/boot/dts/freescale/imx95.dtsi           | 774 +++++++++++++++++----
 drivers/dma/dmaengine.c                            |  49 +-
 drivers/dma/fsl-edma-common.c                      |  10 +-
 drivers/dma/fsl-edma-common.h                      |   1 +
 drivers/dma/fsl-edma-main.c                        | 225 +++++-
 drivers/dma/tegra186-gpc-dma.c                     |   1 -
 drivers/iommu/iommu.c                              |   4 +
 include/linux/dmaengine.h                          |   4 +
 9 files changed, 979 insertions(+), 159 deletions(-)
---
base-commit: aaa2f954c21b205a0bcd0961e5b2be4e82e58455
change-id: 20261102-edma-iommu-v3-22b673717cf4

Best regards,
--  
Peng Fan <peng.fan@nxp.com>


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2026-11-12 16:46 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-12  7:53 [PATCH v6 0/9] dmaengine: add DMA channel bus and fsl-edma per-channel IOMMU support Peng Fan (OSS)
2026-11-12  7:53 ` [PATCH v6 1/9] dmaengine: fsl-edma: unregister channels before vchan cleanup Peng Fan (OSS)
2026-11-12  7:53 ` [PATCH v6 2/9] dmaengine: add a bus for DMA channel devices Peng Fan (OSS)
2026-11-12 15:47   ` Frank Li
2026-11-12  7:53 ` [PATCH v6 3/9] iommu: register the DMA channel bus for IOMMU notifications Peng Fan (OSS)
2026-11-12  7:53 ` [PATCH v6 4/9] dmaengine: move channel devices to the DMA channel bus Peng Fan (OSS)
2026-11-12 16:04   ` Frank Li
2026-11-12  7:53 ` [PATCH v6 5/9] dt-bindings: dma: fsl,edma: add per-channel child node support Peng Fan (OSS)
2026-11-12  7:53 ` [PATCH v6 6/9] dmaengine: fsl-edma: use BIT_ULL for 64-bit channel mask Peng Fan (OSS)
2026-11-12 16:05   ` Frank Li
2026-11-12  7:53 ` [PATCH v6 7/9] dmaengine: fsl-edma: use dmaengine_get_dma_device() Peng Fan (OSS)
2026-11-12 16:06   ` Frank Li
2026-11-12  7:53 ` [PATCH v6 8/9] dmaengine: fsl-edma: support per-channel DT child nodes Peng Fan (OSS)
2026-11-12 16:46   ` Frank Li
2026-11-12  7:53 ` [PATCH v6 9/9] arm64: dts: imx95: convert eDMA to per-channel " Peng Fan (OSS)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®