Re: [RFC PATCH v4 00/38] NTB transport backed by PCI EP embedded DMA

Dave Jiang
2026-01-20T18:30:11Z

On 1/18/26 6:54 AM, Koichiro Den wrote:
> Hi,
>
> This is RFC v4 of the NTB/PCI/dmaengine series that introduces an
> optional NTB transport variant where payload data is moved by a PCI
> embedded-DMA engine (eDMA) residing on the endpoint side.

Just a fly by comment. This series is huge. I do suggest break it down to something more manageable to prevent review fatigue from patch reviewers. For example, linux network sub-system has a rule to restrict patch series to no more than 15 patches. NTB sub-system does not have that rule. But maybe split out the dmaengine changes and the hardware specific dw-edma bits from the ntb core changes.

DJ

>
> The primary target is Synopsys DesignWare PCIe endpoint controllers that
> integrate a DesignWare eDMA instance (dw-edma). In the remote
> embedded-DMA mode, payload is transferred by DMA directly between the
> two systems' memory, and NTB Memory Windows are used primarily for
> control/metadata and for exposing the endpoint eDMA resources (register
> window + linked-list rings) to the host.
>
> Compared to the existing cpu/dma memcpy-based implementation, this
> approach avoids window-backed payload rings and the associated extra
> copies, and it is less sensitive to scarce MW space. This also enables
> scaling out to multiple queue pairs, which is particularly beneficial
> for ntb_netdev. On R-Car S4, preliminary iperf3 results show 10~20x
> throughput improvement. Latency improvements are also observed.
>
> RFC history:
> RFC v3: https://lore.kernel.org/all/20251217151609.3162665-1-den@valinux.co.jp/
> RFC v2: https://lore.kernel.org/all/20251129160405.2568284-1-den@valinux.co.jp/
> RFC v1: https://lore.kernel.org/all/20251023071916.901355-1-den@valinux.co.jp/
>
> Parts of RFC v3 series have already been split out and posted separately
> (see "Kernel base / dependencies" section below). However, feedback on
> the remaining parts led to substantial restructuring and code changes,
> so I am sending an RFC v4 as a refreshed version of the full series.
>
> RFC v4 is still a large, cross-subsystem series. At this RFC stage,
> I am sending the full picture in a single set to make it easier to
> review the overall direction and architecture. Once the direction is
> agreed upon and no further large restructuring appears necessary, I will stop
> posting the new RFC-tagged revisions and continue development on
> separate threads, split by sub-topic.
>
> Many thanks for all the reviews and feedback from multiple perspectives.
>
>
> Software architecture overview (RFC v4)
> =======================================
>
> A major change in RFC v4 is the software layering and module split.
>
> The existing memcpy-based transport and the new remote embedded-DMA
> transport are implemented as two independent NTB client drivers on top
> of a shared core library:
>
> +--------------------+
> | ntb_transport_core |
> +--------------------+
> ^ ^
> | |
> ntb_transport -----+ +----- ntb_transport_edma
> (cpu/dma memcpy) (remote embedded DMA transfer)
> |
> v
> +-----------+
> | ntb_edma |
> +-----------+
> ^
> |
> +----------------+
> | |
> ntb_dw_edma [...]
>
> Key points:
> * ntb_transport_core provides the queue-pair abstraction used by upper
> layer clients (e.g. ntb_netdev).
> * ntb_transport is the legacy shared-memory transport client (CPU/DMA
> memcpy).
> * ntb_transport_edma is the remote embedded-DMA transport client.
> * ntb_transport_edma relies on an ntb_edma backend registry.
> This RFC provides an initial DesignWare backend (ntb_dw_edma).
> * Transport selection is per-NTB device via the standard
> driver_override mechanism. To enable that, this RFC adds
> driver_override support to ntb_bus. This allows mixing transports
> across multiple NTB ports and provides an explicit fallback path to
> the legacy transport.
>
> So, if ntb_transport / ntb_transport_edma are built as loadable modules,
> you can just run modprobe ntb_transport as before and the original cpu/dma
> memcpy-based implementation will be active. If they are built-in, whether
> ntb_transport or ntb_transport_edma are bound by default depends on
> initcall order. Regarding how to switch the driver, please see Patch 34
> ("Documentation: driver-api: ntb: Document remote embedded-DMA transport")
> for details.
>
>
> Data flow overview (remote embedded-DMA transport)
> ==================================================
>
> At a high level:
> * One MW is reserved as an "eDMA window". The endpoint exposes the
> eDMA register block plus LL descriptor rings through that window, so
> the peer can ioremap it and drive DMA reads remotely.
> * Remaining MWs carry only small control-plane rings used to exchange
> buffer addresses and completion information.
> * For RC->EP traffic, the RC drives endpoint DMA read channels through
> the peer-visible eDMA window.
> * For EP->RC traffic, the endpoint uses its local DMA write channels.
>
> The following figures illustrate the data flow when ntb_netdev sits on
> top of the transport:
>
> Figure 1. RC->EP traffic via ntb_netdev + ntb_transport_edma
> backed by ntb_edma/ntb_dw_edma
>
> EP RC
> phys addr phys addr
> space space
> +-+ +-+
> | | | |
> | | || | |
> +-+-----. || | |
> EDMA REG | | \ [A] || | |
> +-+----. '---+-+ || | |
> | | \ | |<---------[0-a]----------
> +-+-----------| |<----------[2]----------.
> EDMA LL | | | | || | | :
> | | | | || | | :
> +-+-----------+-+ || [B] | | :
> | | || ++ | | :
> ---------[0-b]----------->||----------------'
> | | ++ || || | |
> | | || || ++ | |
> | | ||<----------[4]-----------
> | | ++ || | |
> | | [C] || | |
> .--|#|<------------------------[3]------|#|<-.
> : |#| || |#| :
> [5] | | || | | [1]
> : | | || | | :
> '->|#| |#|--'
> |#| |#|
> | | | |
>
> Figure 2. EP->RC traffic via ntb_netdev + ntb_transport_edma
> backed by ntb_edma/ntb_dw_edma
>
> EP RC
> phys addr phys addr
> space space
> +-+ +-+
> | | | |
> | | || | |
> +-+ || | |
> EDMA REG | | || | |
> +-+ || | |
> ^ | | || | |
> : +-+ || | |
> : EDMA LL| | || | |
> : | | || | |
> : +-+ || [C] | |
> : | | || ++ | |
> : -----------[4]----------->|| | |
> : | | ++ || || | |
> : | | || || ++ | |
> '----------------[2]-----||<--------[0-b]-----------
> | | ++ || | |
> | | [B] || | |
> .->|#|--------[3]---------------------->|#|--.
> : |#| || |#| :
> [1] | | || | | [5]
> : | | || | | :
> '--|#| |#|<-'
> |#| |#|
> | | | |
>
> 0-a. configure remote embedded DMA (program endpoint DMA registers)
> 0-b. DMA-map and publish destination address (DAR)
> 1. network stack builds skb (copy from application/user memory)
> 2. consume DAR, DMA-map source address (SAR) and kick DMA transfer
> 3. DMA transfer (payload moves between RC/EP memory)
> 4. consume completion (commit)
> 5. network stack delivers data to application/user memory
>
> [A]: Dedicated MW that aggregates DMA regs and LL (peer ioremaps it)
> [B]: Control-plane ring buffer for "produce"
> [C]: Control-plane ring buffer for "consume"
>
>
> Kernel base / dependencies
> ==========================
>
> This series is based on:
>
> - next-20260114 (commit b775e489bec7)
>
> plus the following seven unmerged patch series or standalone patches:
>
> - [PATCH v4 0/7] PCI: endpoint/NTB: Harden vNTB resource management
> https://lore.kernel.org/all/20251202072348.2752371-1-den@valinux.co.jp/
>
> - [PATCH v2 0/2] NTB: ntb_transport: debugfs cleanups
> https://lore.kernel.org/all/20260107042458.1987818-1-den@valinux.co.jp/
>
> - [PATCH v3 0/9] dmaengine: Add new API to combine configuration and descriptor preparation
> https://lore.kernel.org/all/20260105-dma_prep_config-v3-0-a8480362fd42@nxp.com/
>
> - [PATCH v8 0/5] PCI: endpoint: BAR subrange mapping support
> https://lore.kernel.org/all/20260115084928.55701-1-den@valinux.co.jp/
>
> - [PATCH] PCI: endpoint: pci-epf-vntb: Use array_index_nospec() on mws_size[] access
> https://lore.kernel.org/all/20260105075606.1253697-1-den@valinux.co.jp/
>
> - [PATCH] dmaengine: dw-edma: Fix MSI data values for multi-vector IMWr interrupts
> https://lore.kernel.org/all/20260105075904.1254012-1-den@valinux.co.jp/
>
> - [PATCH v2 01/11] dmaengine: dw-edma: Add spinlock to protect DONE_INT_MASK and ABORT_INT_MASK
> https://lore.kernel.org/imx/20260109-edma_ll-v2-1-5c0b27b2c664@nxp.com/
> (only this single commit is cherry-picked from the series)
>
>
> Patch layout
> ============
>
> 1. dw-edma / DesignWare EP helpers needed for remote embedded-DMA (export
> register/LL windows, IRQ routing control, etc.)
>
> Patch 01 : dmaengine: dw-edma: Export helper to get integrated register window
> Patch 02 : dmaengine: dw-edma: Add per-channel interrupt routing control
> Patch 03 : dmaengine: dw-edma: Poll completion when local IRQ handling is disabled
> Patch 04 : dmaengine: dw-edma: Add notify-only channels support
> Patch 05 : dmaengine: dw-edma: Add a helper to query linked-list region
>
> 2. NTB EPF/core + vNTB prep (mwN_offset + versioning, MSI vector
> management, new ntb_dev_ops helpers, driver_override, vntb glue)
>
> Patch 06 : NTB: epf: Add mwN_offset support and config region versioning
> Patch 07 : NTB: epf: Reserve a subset of MSI vectors for non-NTB users
> Patch 08 : NTB: epf: Provide db_vector_count/db_vector_mask callbacks
> Patch 09 : NTB: core: Add mw_set_trans_ranges() for subrange programming
> Patch 10 : NTB: core: Add .get_private_data() to ntb_dev_ops
> Patch 11 : NTB: core: Add .get_dma_dev() to ntb_dev_ops
> Patch 12 : NTB: core: Add driver_override support for NTB devices
> Patch 13 : PCI: endpoint: pci-epf-vntb: Support BAR subrange mappings for MWs
> Patch 14 : PCI: endpoint: pci-epf-vntb: Implement .get_private_data() callback
> Patch 15 : PCI: endpoint: pci-epf-vntb: Implement .get_dma_dev()
>
> 3. ntb_transport refactor/modularization and backend infrastructure
>
> Patch 16 : NTB: ntb_transport: Move TX memory window setup into setup_qp_mw()
> Patch 17 : NTB: ntb_transport: Dynamically determine qp count
> Patch 18 : NTB: ntb_transport: Use ntb_get_dma_dev()
> Patch 19 : NTB: ntb_transport: Rename ntb_transport.c to ntb_transport_core.c
> Patch 20 : NTB: ntb_transport: Move internal types to ntb_transport_internal.h
> Patch 21 : NTB: ntb_transport: Export common helpers for modularization
> Patch 22 : NTB: ntb_transport: Split core library and default NTB client
> Patch 23 : NTB: ntb_transport: Add transport backend infrastructure
> Patch 24 : NTB: ntb_transport: Run ntb_set_mw() before link-up negotiation
>
> 4. ntb_edma backend registry + DesignWare backend + transport client
>
> Patch 25 : NTB: hw: Add remote eDMA backend registry and DesignWare backend
> Patch 26 : NTB: ntb_transport: Add remote embedded-DMA transport client
>
> 5. ntb_netdev multi-queue support
>
> Patch 27 : ntb_netdev: Multi-queue support
>
> 6. Renesas R-Car S4 enablement (IOMMU, DTs, quirks)
>
> Patch 28 : iommu: ipmmu-vmsa: Add PCIe ch0 to devices_allowlist
> Patch 29 : iommu: ipmmu-vmsa: Add support for reserved regions
> Patch 30 : arm64: dts: renesas: Add Spider RC/EP DTs for NTB with remote DW PCIe eDMA
> Patch 31 : NTB: epf: Add per-SoC quirk to cap MRRS for DWC eDMA (128B for R-Car)
> Patch 32 : NTB: epf: Add an additional memory window (MW2) barno mapping on Renesas R-Car
>
> 7. Documentation updates
>
> Patch 33 : Documentation: PCI: endpoint: pci-epf-vntb: Update and add mwN_offset usage
> Patch 34 : Documentation: driver-api: ntb: Document remote embedded-DMA transport
>
> 8. pci-epf-test / pci_endpoint_test / kselftest coverage for remote eDMA
>
> Patch 35 : PCI: endpoint: pci-epf-test: Add pci_epf_test_next_free_bar() helper
> Patch 36 : PCI: endpoint: pci-epf-test: Add remote eDMA-backed mode
> Patch 37 : misc: pci_endpoint_test: Add remote eDMA transfer test mode
> Patch 38 : selftests: pci_endpoint: Add remote eDMA transfer coverage
>
>
> Tested on
> =========
>
> * 2x Renesas R-Car S4 Spider (RC<->EP connected with OCuLink cable)
> * Kernel base as described above
>
>
> Performance notes
> =================
>
> The primary motivation remains improving throughput/latency for ntb_transport
> users (typically ntb_netdev). On R-Car S4, the earlier prototype (RFC v3)
> showed roughly 10-20x throughput improvement in preliminary iperf3 tests and
> lower ping RTT. I have not yet re-measured after the v4 refactor and
> module split.
>
>
> Changelog
> =========
>
> RFCv3->RFCv4 changes:
> - Major refactor of the transport layering:
> - Introduce ntb_transport_core as a shared library module.
> - Split the legacy shared-memory transport client (ntb_transport) and the
> remote embedded-DMA transport client (ntb_transport_edma).
> - Add driver_override support for ntb_bus and use it for per-port transport
> selection.
> - Introduce a vendor-agnostic remote embedded-DMA backend registry (ntb_edma)
> and add the initial DesignWare backend (ntb_dw_edma).
> - Rebase to next-20260114 and move several prerequisite/fixup patchsets into
> separate threads (listed above), including BAR subrange mapping support and
> dw-edma fixes.
> - Add PCI endpoint test coverage for the remote embedded-DMA path:
> - extend pci-epf-test / pci_endpoint_test
> - add a kselftest variant to exercise remote-eDMA transfers
> Note: to keep the changes as small as possible, I added a few #ifdefs
> in the main test code. Feedback on whether/how/to what extent this
> should be split into separate modules would be appreciated.
> - Expand documentation (Documentation/driver-api/ntb.rst) to describe transport
> variants, the new module structure, and the remote embedded-DMA data flow.
> - Addressed other feedbacks from the RFC v3 thread.
>
> RFCv2->RFCv3 changes:
> - Architecture
> - Have EP side use its local write channels, while leaving RC side to
> use remote read channels.
> - Abstraction/HW-specific stuff encapsulation improved.
> - Added control/config region versioning for the vNTB/EPF control region
> so that mismatched RC/EP kernels fail early instead of silently using an
> incompatible layout.
> - Reworked BAR subrange / multi-region mapping support:
> - Dropped the v2 approach that added new inbound mapping ops in the EPC
> core.
> - Introduced `struct pci_epf_bar.submap` and extended DesignWare EP to
> support BAR subrange inbound mapping via Address Match Mode IB iATU.
> - pci-epf-vntb now provides a subrange mapping hint to the EPC driver
> when offsets are used.
> - Changed .get_pci_epc() to .get_private_data()
> - Dropped two commits from RFC v2 that should be submitted separately:
> (1) ntb_transport debugfs seq_file conversion
> (2) DWC EP outbound iATU MSI mapping/cache fix (will be re-posted separately)
> - Added documentation updates.
> - Addressed assorted review nits from the RFC v2 thread (naming/structure).
>
> RFCv1->RFCv2 changes:
> - Architecture
> - Drop the generic interrupt backend + DW eDMA test-interrupt backend
> approach and instead adopt the remote eDMA-backed ntb_transport mode
> proposed by Frank Li. The BAR-sharing / mwN_offset / inbound
> mapping (Address Match Mode) infrastructure from RFC v1 is largely
> kept, with only minor refinements and code motion where necessary
> to fit the new transport-mode design.
> - For Patch 01
> - Rework the array_index_nospec() conversion to address review
> comments on "[RFC PATCH 01/25]".
>
> RFCv3: https://lore.kernel.org/all/20251217151609.3162665-1-den@valinux.co.jp/
> RFCv2: https://lore.kernel.org/all/20251129160405.2568284-1-den@valinux.co.jp/
> RFCv1: https://lore.kernel.org/all/20251023071916.901355-1-den@valinux.co.jp/
>
> Thank you for reviewing,
>
>
> Koichiro Den (38):
> dmaengine: dw-edma: Export helper to get integrated register window
> dmaengine: dw-edma: Add per-channel interrupt routing control
> dmaengine: dw-edma: Poll completion when local IRQ handling is
> disabled
> dmaengine: dw-edma: Add notify-only channels support
> dmaengine: dw-edma: Add a helper to query linked-list region
> NTB: epf: Add mwN_offset support and config region versioning
> NTB: epf: Reserve a subset of MSI vectors for non-NTB users
> NTB: epf: Provide db_vector_count/db_vector_mask callbacks
> NTB: core: Add mw_set_trans_ranges() for subrange programming
> NTB: core: Add .get_private_data() to ntb_dev_ops
> NTB: core: Add .get_dma_dev() to ntb_dev_ops
> NTB: core: Add driver_override support for NTB devices
> PCI: endpoint: pci-epf-vntb: Support BAR subrange mappings for MWs
> PCI: endpoint: pci-epf-vntb: Implement .get_private_data() callback
> PCI: endpoint: pci-epf-vntb: Implement .get_dma_dev()
> NTB: ntb_transport: Move TX memory window setup into setup_qp_mw()
> NTB: ntb_transport: Dynamically determine qp count
> NTB: ntb_transport: Use ntb_get_dma_dev()
> NTB: ntb_transport: Rename ntb_transport.c to ntb_transport_core.c
> NTB: ntb_transport: Move internal types to ntb_transport_internal.h
> NTB: ntb_transport: Export common helpers for modularization
> NTB: ntb_transport: Split core library and default NTB client
> NTB: ntb_transport: Add transport backend infrastructure
> NTB: ntb_transport: Run ntb_set_mw() before link-up negotiation
> NTB: hw: Add remote eDMA backend registry and DesignWare backend
> NTB: ntb_transport: Add remote embedded-DMA transport client
> ntb_netdev: Multi-queue support
> iommu: ipmmu-vmsa: Add PCIe ch0 to devices_allowlist
> iommu: ipmmu-vmsa: Add support for reserved regions
> arm64: dts: renesas: Add Spider RC/EP DTs for NTB with remote DW PCIe
> eDMA
> NTB: epf: Add per-SoC quirk to cap MRRS for DWC eDMA (128B for R-Car)
> NTB: epf: Add an additional memory window (MW2) barno mapping on
> Renesas R-Car
> Documentation: PCI: endpoint: pci-epf-vntb: Update and add mwN_offset
> usage
> Documentation: driver-api: ntb: Document remote embedded-DMA transport
> PCI: endpoint: pci-epf-test: Add pci_epf_test_next_free_bar() helper
> PCI: endpoint: pci-epf-test: Add remote eDMA-backed mode
> misc: pci_endpoint_test: Add remote eDMA transfer test mode
> selftests: pci_endpoint: Add remote eDMA transfer coverage
>
> Documentation/PCI/endpoint/pci-vntb-howto.rst | 19 +-
> Documentation/driver-api/ntb.rst | 193 ++
> arch/arm64/boot/dts/renesas/Makefile | 2 +
> .../boot/dts/renesas/r8a779f0-spider-ep.dts | 37 +
> .../boot/dts/renesas/r8a779f0-spider-rc.dts | 52 +
> drivers/dma/dw-edma/dw-edma-core.c | 207 +-
> drivers/dma/dw-edma/dw-edma-core.h | 10 +
> drivers/dma/dw-edma/dw-edma-v0-core.c | 26 +-
> drivers/iommu/ipmmu-vmsa.c | 7 +-
> drivers/misc/pci_endpoint_test.c | 633 +++++
> drivers/net/ntb_netdev.c | 341 ++-
> drivers/ntb/Kconfig | 13 +
> drivers/ntb/Makefile | 2 +
> drivers/ntb/core.c | 68 +
> drivers/ntb/hw/Kconfig | 1 +
> drivers/ntb/hw/Makefile | 1 +
> drivers/ntb/hw/edma/Kconfig | 28 +
> drivers/ntb/hw/edma/Makefile | 5 +
> drivers/ntb/hw/edma/backend.c | 87 +
> drivers/ntb/hw/edma/backend.h | 102 +
> drivers/ntb/hw/edma/ntb_dw_edma.c | 977 +++++++
> drivers/ntb/hw/epf/ntb_hw_epf.c | 199 +-
> drivers/ntb/ntb_transport.c | 2458 +---------------
> drivers/ntb/ntb_transport_core.c | 2523 +++++++++++++++++
> drivers/ntb/ntb_transport_edma.c | 1110 ++++++++
> drivers/ntb/ntb_transport_internal.h | 261 ++
> drivers/pci/controller/dwc/pcie-designware.c | 26 +
> drivers/pci/endpoint/functions/pci-epf-test.c | 497 +++-
> drivers/pci/endpoint/functions/pci-epf-vntb.c | 380 ++-
> include/linux/dma/edma.h | 106 +
> include/linux/ntb.h | 88 +
> include/uapi/linux/pcitest.h | 3 +-
> .../pci_endpoint/pci_endpoint_test.c | 17 +
> 33 files changed, 7855 insertions(+), 2624 deletions(-)
> create mode 100644 arch/arm64/boot/dts/renesas/r8a779f0-spider-ep.dts
> create mode 100644 arch/arm64/boot/dts/renesas/r8a779f0-spider-rc.dts
> create mode 100644 drivers/ntb/hw/edma/Kconfig
> create mode 100644 drivers/ntb/hw/edma/Makefile
> create mode 100644 drivers/ntb/hw/edma/backend.c
> create mode 100644 drivers/ntb/hw/edma/backend.h
> create mode 100644 drivers/ntb/hw/edma/ntb_dw_edma.c
> create mode 100644 drivers/ntb/ntb_transport_core.c
> create mode 100644 drivers/ntb/ntb_transport_edma.c
> create mode 100644 drivers/ntb/ntb_transport_internal.h
>