All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/16] NTB: Add direct TX/RX using PCI endpoint DMA
@ 2026-08-10 16:51 Koichiro Den
  2026-08-10 16:51 ` [PATCH 01/16] NTB: ntb_transport: Abort link setup on QP MW allocation failure Koichiro Den
                   ` (15 more replies)
  0 siblings, 16 replies; 19+ messages in thread
From: Koichiro Den @ 2026-08-10 16:51 UTC (permalink / raw)
  To: Jon Mason, Dave Jiang, Frank Li, Allen Hubbe, Greg Kroah-Hartman,
	Niklas Cassel, Nicholas Bellinger
  Cc: ntb, netdev, linux-kernel

Hi,

This series lets ntb_transport transfer packets directly from client TX
buffers to peer RX buffers using PCI endpoint DMA, avoiding the
memory-window copy path. It raises throughput significantly.

My previous attempt at the same goal was:

  [RFC PATCH v4 00/38] NTB transport backed by PCI EP embedded DMA
  https://lore.kernel.org/r/20260118135440.1958279-1-den@valinux.co.jp/

Since that RFC, prerequisite work has entered mainline in a different
form. Unlike that RFC, this series extends ntb_transport itself and can
fall back to the existing memory-window copy path at runtime.

Some work needed to run this series on my R-Car S4 testbed is still under
review; see Dependencies below.

The series contains:

  * Patches 1-5   : small fixes and prerequisites
  * Patches 6-14  : the main implementation for direct TX/RX
  * Patches 15-16 : optional features


Summary
=======

ntb_transport currently copies each packet through a fixed slot in a
memory window. This series adds an optional path where the receiver
publishes client-buffer DMA addresses and the sender's DMA writes
packets directly to them. The existing copy path remains available, and
direct RX and TX are negotiated independently.

Bidirectional direct TX/RX requires a multi-function PCI endpoint. vNTB
uses one function, while the PCI DMA EPF on another exposes the endpoint
DMA controller to the host. Each sender needs an ordered channel that can
transfer from mapped system memory to peer-published DMA addresses. The
tested setup used dw-edma with the PCI DMA EPF on PF0 and vNTB on PF1.


Design
======

Session
-------

ntb_transport automatically reconnects a logical QP while the physical
NTB link and its shared MW remain up. One peer may therefore start the
next direct-DMA "session" while the other is still finishing the
previous teardown. A fresh session ID distinguishes the two instances,
and direct DMA remains disabled until both peers have acknowledged it.
Otherwise, stale RX addresses from the previous instance could be reused
after their mappings have been released.

Resetting the physical NTB link on every QP close would avoid this
overlap, but would also tear down all QPs for ordinary operations such
as ntb_netdev close/open, MTU changes, or queue reconfiguration. This
series keeps the existing automatic QP reconnect behavior instead.

Quiesce
-------

A published RX address must stay mapped until the sender can no longer
write to it. Closing the local QP alone does not prove this. During
teardown, each QP publishes its final issued TX boundary, then writes a
quiesce marker to tell the peer that this boundary is final and no more
TX will be issued for the session. The CPU-written marker can arrive
before earlier DMA writes when the two paths use different PCIe ordering
domains. The peer therefore waits until it has consumed completion words
through that boundary before acknowledging quiesce and releasing the RX
mappings. Local TX mappings remain owned until DMA completes or the
channel has been stopped and synchronized.

Completion ordering
-------------------

The payload and its completion word are submitted to the same ordered
DMA channel. A separate CPU MMIO completion would not provide that
ordering: its posted write could pass an earlier DMA write. The MSI or
doorbell sent after the DMA callback can still reach the peer before the
completion word is visible. A read-back from the completion destination
would close that window, but would add a non-posted PCIe round trip to
every packet. It hurt throughput in testing. Notifications are therefore
hints, while the completion word decides when an RX buffer can be
reused. Optional polling lets the receiver find a completion that
arrives after its notification.

Per-direction negotiation
-------------------------

A side may be able to map direct RX buffers even when it cannot reserve
all TX DMA channels. RX and TX are therefore negotiated separately,
allowing direct DMA in one direction while the other keeps using the
copy path.

Protocol compatibility
----------------------

The extension keeps protocol version 4 and the original QP layout for
peers that do not advertise direct DMA. Version 4 has been in use for
about 11 years.


Dependencies
============

The multi-function endpoint setup described above requires:

  1. [PATCH v6 0/6] PCI: endpoint: Expose endpoint DMA resources (part 2/3)
     (https://lore.kernel.org/r/20260804033855.2115817-1-den@valinux.co.jp/)

  2. [PATCH v5 0/3] PCI: endpoint: Add PCI DMA endpoint function (part 3/3)
     (https://lore.kernel.org/r/20260717050953.2145851-1-den@valinux.co.jp/)

  3. [PATCH 0/3] PCI: endpoint: Support vNTB as a non-first EPF
     (https://lore.kernel.org/r/20260728172306.2751813-1-den@valinux.co.jp/)

Series 1 and 2 will be combined in the next revision after the part 2
review settles, per Frank's feedback.


Performance improvement
=======================

The test used two R-Car S4 Spider boards connected with an OCuLink cable,
one as EP and the other as RC. The link was PCIe Gen4 x2 with DWC PCIe
controller IP v5.20 and eDMA (not HDMA). The workloads were:

- UDP: sudo iperf3 -ub0 -c $peer -l 65507 -w 512M -P 4 -t 10
- TCP: sudo iperf3 -Z -c $peer -l 65507 -P 8 -t 10

The results were:

  (unit: Gbps) (UL=EP->RC, DL=RC->EP)

          UL UDP  DL UDP   UL TCP  DL TCP
  ------- ------  -------  ------  ------
  Before  ~0.6     ~0.6     ~0.6     ~0.6
  After   ~19.5    ~17.3    ~12.3    ~10.8

Reaching the above throughput on R-Car S4 also requires:

- [PATCH 00/11] PCI/NTB: endpoint: packed vNTB memory windows
  (https://lore.kernel.org/r/20260803180439.1963864-1-den@valinux.co.jp/)
- [PATCH v4 00/24] dmaengine: dw-edma: Support dynamic LL appends
  (https://lore.kernel.org/r/20260729143036.3087722-1-den@valinux.co.jp/)

The test setup also used two unsubmitted platform changes: adding the PCIe
controller to the IPMMU allowlist and capping the EP DMA MRRS at 128 bytes.

The "After" result used:
- packed_mws=4 and `ethtool -L eth0 combined 4`
- `modprobe ntb_transport use_direct_dma=1 direct_dma_func=0 \
    direct_dma_ring_entries=256 direct_dma_poll=1`

Best regards,
Koichiro


Koichiro Den (16):
  NTB: ntb_transport: Abort link setup on QP MW allocation failure
  NTB: ntb_transport: Reject oversized TX buffers
  NTB: ntb_transport: Start TX offload thread after queue setup
  NTB: ntb_transport: Stop QP work before freeing a queue
  NTB: ntb_transport: Run RX processing on system workqueue
  NTB: ntb_transport: Define direct-DMA shared state
  NTB: ntb_transport: Negotiate direct-DMA queue layout
  NTB: ntb_transport: Add opt-in direct-DMA channel reservation
  NTB: ntb_transport: Allocate direct-DMA queue state
  NTB: ntb_transport: Implement direct-DMA QP session handshake
  NTB: ntb_transport: Implement direct-DMA RX buffer publication
  NTB: ntb_transport: Implement direct-DMA TX submission
  NTB: ntb_transport: Implement safe direct-DMA teardown
  NTB: ntb_transport: Enable direct-DMA queues
  NTB: ntb_transport: Report the direct-DMA payload limit
  NTB: ntb_transport: Add optional polling for direct-DMA RX

 drivers/net/ntb_netdev.c      |    4 +-
 drivers/ntb/ntb_transport.c   | 1523 +++++++++++++++++++++++++++++++--
 include/linux/ntb_transport.h |    1 +
 3 files changed, 1456 insertions(+), 72 deletions(-)

-- 
2.51.0


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

end of thread, other threads:[~2026-08-10 18:42 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-10 16:51 [PATCH 00/16] NTB: Add direct TX/RX using PCI endpoint DMA Koichiro Den
2026-08-10 16:51 ` [PATCH 01/16] NTB: ntb_transport: Abort link setup on QP MW allocation failure Koichiro Den
2026-08-10 18:41   ` Frank Li
2026-08-10 16:51 ` [PATCH 02/16] NTB: ntb_transport: Reject oversized TX buffers Koichiro Den
2026-08-10 16:51 ` [PATCH 03/16] NTB: ntb_transport: Start TX offload thread after queue setup Koichiro Den
2026-08-10 16:51 ` [PATCH 04/16] NTB: ntb_transport: Stop QP work before freeing a queue Koichiro Den
2026-08-10 16:51 ` [PATCH 05/16] NTB: ntb_transport: Run RX processing on system workqueue Koichiro Den
2026-08-10 16:51 ` [PATCH 06/16] NTB: ntb_transport: Define direct-DMA shared state Koichiro Den
2026-08-10 16:51 ` [PATCH 07/16] NTB: ntb_transport: Negotiate direct-DMA queue layout Koichiro Den
2026-08-10 16:51 ` [PATCH 08/16] NTB: ntb_transport: Add opt-in direct-DMA channel reservation Koichiro Den
2026-08-10 16:51 ` [PATCH 09/16] NTB: ntb_transport: Allocate direct-DMA queue state Koichiro Den
2026-08-10 16:51 ` [PATCH 10/16] NTB: ntb_transport: Implement direct-DMA QP session handshake Koichiro Den
2026-08-10 16:51 ` [PATCH 11/16] NTB: ntb_transport: Implement direct-DMA RX buffer publication Koichiro Den
2026-08-10 16:51 ` [PATCH 12/16] NTB: ntb_transport: Implement direct-DMA TX submission Koichiro Den
2026-08-10 16:51 ` [PATCH 13/16] NTB: ntb_transport: Implement safe direct-DMA teardown Koichiro Den
2026-08-10 16:51 ` [PATCH 14/16] NTB: ntb_transport: Enable direct-DMA queues Koichiro Den
2026-08-10 17:04   ` Koichiro Den
2026-08-10 16:51 ` [PATCH 15/16] NTB: ntb_transport: Report the direct-DMA payload limit Koichiro Den
2026-08-10 16:51 ` [PATCH 16/16] NTB: ntb_transport: Add optional polling for direct-DMA RX Koichiro Den

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.