All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/19] dmaengine: dw-edma: Support dynamic LL appends
@ 2026-07-23  8:41 Koichiro Den
  2026-07-23  8:41 ` [PATCH v2 01/19] dmaengine: dw-edma: Add dw_edma_core_ll_cur_idx() to get current LL entry index Koichiro Den
                   ` (18 more replies)
  0 siblings, 19 replies; 37+ messages in thread
From: Koichiro Den @ 2026-07-23  8:41 UTC (permalink / raw)
  To: Manivannan Sadhasivam, Vinod Koul, Frank Li, Gustavo Pimentel,
	Kees Cook, Krzysztof Wilczyński, Kishon Vijay Abraham I,
	Bjorn Helgaas, Christoph Hellwig, Serge Semin, Cai Huoqing,
	Niklas Cassel
  Cc: Devendra K Verma, dmaengine, linux-kernel

The existing driver treats each linked list as a finite transfer. It
waits for completion before publishing more work, so short and concurrent
requests repeatedly stop and restart the channel.

Turn the linked list into a circular producer/consumer ring and allow
new requests to be published while a channel is running. The hardware can
then continue into newly published entries instead of waiting for
software to rebuild and restart the list for every transfer.

v2 incorporates the v1 review feedback and a substantial rework based on
failures observed under intensive multi-channel traffic.

  v1:
  https://lore.kernel.org/r/20260615154111.2174161-1-den@valinux.co.jp/

  Frank's RFT:
  https://lore.kernel.org/r/20260109-edma_dymatic-v1-0-9a98c9c98536@nxp.com/

Why this is more than a ring change
===================================

Once entries from several DMAengine descriptors coexist in the ring, LL
ownership and descriptor completion no longer share one boundary.
Software must recycle entries as the hardware consumes them, but complete
a descriptor only after all of its entries have been consumed.

DMA_LLP provides that progress evidence, but its meaning depends on where
the channel was when it was sampled. A stopped sample points to the next
entry. A running sample can move ahead of payload completion, so keep it
one entry behind. Although the HDMA databook describes a watermark LLP as
a recycling boundary, testing on a DWC HDMA 6.30a integration showed that
using it directly for DMAengine completion let clients release mappings
while the hardware still accessed them. The series therefore records
IRQ-paired LLP samples and uses the same conservative running boundary for
both eDMA and HDMA.

A running channel consumes newly published entries without another
doorbell; a stopped channel with pending entries needs one. The series
keeps that decision in one helper, together with stopped-tail
reconciliation, so publication, completion, and restart use the same view
of the ring.

Recovery
========

The programming sections do not define how a second legacy-eDMA doorbell
is handled while a start or stop transition is still in flight. Register
traces point to two problematic transition windows. Channel Status can
still read STOPPED while a start from an earlier doorbell is in flight.
At the other end, DONE, STOPPED status, and zero transfer size can all be
visible before the internal stop has fully settled.

A doorbell aimed at an apparently stopped channel is suspected of
arriving while the previous start or stop transition is still in flight
inside the engine, leaving the channel stuck. The channel retains pending
entries but reports no progress or error interrupt. The exact internal
trigger is not known, and these observations should not be taken as a
rule for every integration.

Avoid doorbells while a channel reports running, and route every stopped
restart through the common helper. Since the visible registers cannot
prove that an apparent stop has fully settled, also provide an optional
recovery path. Repeated doorbell-path checks detect pending entries
without progress. Recovery gates the direction, waits for active channels
to stop, resets the engine, rebuilds configured LL contexts, and only then
enables it again. If ENGINE_EN does not clear, the direction remains
gated.

The recovery path was never entered during the fio/nvmet_pci_epf runs
used so far; whether much longer runs can reach it is unknown. It is a
safeguard for the intensive multi-channel failure, not part of normal
operation. The first stalled observation only starts the timeout and
still rings the doorbell. Recovery is queued only if a later check, after
the timeout, still sees pending work without progress, and the worker
revalidates it before reset.

Only the eDMA provider currently opts into direction recovery. Native HDMA
does not provide direction-reset operations, while HDMA compatibility
mode has no ENGINE_EN. The recovery trigger and timeout remain empirical
and need coverage on more integrations, as well as confirmation of reset
semantics from Synopsys.

Series flow
===========

- Patches 1-6 establish the circular ring and its interrupt policy.
- Patches 7-14 make progress accounting, completion, STOP/PAUSE, and ring
  reset work with multiple descriptors in flight.
- Patches 15-17 add the optional engine recovery path.
- Patch 18 enables dynamic submission; patch 19 adds tracepoints.

Base
====

This series is based on dmaengine/next: commit 0613e7934ee2 ("dmaengine:
dw-edma: Program endpoint function numbers")

Testing
=======

I retested v2 on the following three testbeds.

- eDMA: RK3588 Rock 5B, DWC PCIe v5.60a
        R-Car S4, DWC PCIe v5.20a
- HDMA: SpacemiT K3, DWC PCIe v6.30a [1]

1. fio

   The fio setup uses nvmet_pci_epf with a null_blk-backed namespace,
   runtime=30s, ramp_time=5s. Before And After were alternated three
   times (B-A-B-A-B-A).

   NOTE: The fio tests use nvmet_pci_epf, which does not keep the DMA
         engine continuously busy. A workload that rarely lets the
         engine stop would show the benefit of dynamic appends more
         directly.

   - eDMA (RK3588)

     NOTE: The eDMA Before results include the separate regression
           described in [2].

     Summary by group (BW delta %)
       all          n=26 mean=+1202.7 median=+157.0 min= +55.6 max=+5551.2
       read         n=14 mean=+2086.1 median=+893.9 min= +62.3 max=+5551.2
       write        n=11 mean=+157.4 median=+130.1 min= +55.6 max=+356.8
       qd32         n=16 mean=+1871.7 median=+345.2 min= +99.6 max=+5551.2
       q1           n= 9 mean=+110.0 median=+108.7 min= +55.6 max=+165.2
       small 4K     n= 6 mean=+220.2 median=+163.2 min=+151.4 max=+356.8
       large >=128K n=20 mean=+1497.4 median=+139.3 min= +55.6 max=+5551.2

     Before mean -> After mean (MiB/s)
       Case                         Before             After              Delta
       ---------------------------  -----------------  -----------------  ------
       Rnd read     4KB q1  1j          19.2 (sd 7.5)      51.0 (sd 9.5)  +165.2%
       Rnd read     4KB q32 1j          88.7 (sd 2.1)    231.7 (sd 17.0)  +161.2%
       Rnd read     4KB q32 4j          88.7 (sd 1.3)    223.0 (sd 38.2)  +151.4%
       Rnd read   128KB q1  1j       420.0 (sd 134.6)   876.7 (sd 325.4)  +108.7%
       Rnd read   128KB q32 1j        142.0 (sd 37.7)   2701.3 (sd 56.2)  +1802.3%
       Rnd read   128KB q32 4j         63.7 (sd 10.6)   3121.7 (sd 27.3)  +4803.1%
       Rnd read   512KB q1  1j        572.0 (sd 35.8)    963.0 (sd 48.1)   +68.4%
       Rnd read   512KB q32 1j         66.8 (sd 10.8)   3097.0 (sd 24.8)  +4536.2%
       Rnd read   512KB q32 4j         55.4 (sd 12.0)   3132.7 (sd 39.3)  +5551.2%
       Rnd write    4KB q1  1j          20.7 (sd 7.0)      52.4 (sd 8.2)  +152.9%
       Rnd write    4KB q32 1j          42.5 (sd 0.9)    194.0 (sd 24.2)  +356.8%
       Rnd write    4KB q32 4j          41.7 (sd 1.6)    180.7 (sd 12.7)  +333.6%
       Rnd write  128KB q1  1j        330.0 (sd 90.1)   600.3 (sd 133.7)   +81.9%
       Rnd write  128KB q32 1j       624.0 (sd 111.5)   1426.3 (sd 43.7)  +128.6%
       Rnd write  128KB q32 4j        659.3 (sd 61.8)   1410.0 (sd 49.5)  +113.9%
       Seq read   128KB q1  1j        260.7 (sd 25.8)   690.3 (sd 184.6)  +164.8%
       Seq read   128KB q32 1j        149.7 (sd 30.9)   2578.3 (sd 60.5)  +1622.7%
       Seq read   512KB q1  1j        578.0 (sd 32.2)    938.0 (sd 46.9)   +62.3%
       Seq read   512KB q32 1j         65.0 (sd 10.6)   3106.7 (sd 21.6)  +4679.5%
       Seq read     1MB q32 1j         57.3 (sd 18.8)   3110.7 (sd 27.1)  +5328.7%
       Seq write  128KB q1  1j        272.3 (sd 62.0)   626.7 (sd 144.1)  +130.1%
       Seq write  128KB q32 1j       597.0 (sd 105.7)   1425.0 (sd 42.5)  +138.7%
       Seq write  512KB q1  1j        476.7 (sd 26.7)    741.7 (sd 25.4)   +55.6%
       Seq write  512KB q32 1j        710.7 (sd 44.0)   1418.7 (sd 47.7)   +99.6%
       Seq write    1MB q32 1j       546.0 (sd 100.4)   1310.0 (sd 39.9)  +139.9%
       Rnd rdwr  4K..1MB q8  4j       247.3 (sd 16.3)   1068.7 (sd 13.7)  +332.1%

   - HDMA (SpacemiT K3)

     Summary by group (BW delta %)
       all          n=26 mean= +89.0 median= +97.7 min= -18.9 max=+152.9
       read         n=14 mean= +78.2 median= +84.0 min= -18.9 max=+145.5
       write        n=11 mean= +96.9 median=+121.6 min=  -0.1 max=+145.0
       qd32         n=16 mean=+114.2 median=+112.2 min= +73.5 max=+145.5
       q1           n= 9 mean= +37.1 median= +18.7 min= -18.9 max=+121.6
       small 4K     n= 6 mean= +87.2 median=+106.8 min=  +8.6 max=+145.5
       large >=128K n=20 mean= +89.5 median= +91.9 min= -18.9 max=+152.9

     Before mean -> After mean (MiB/s)
       Case                         Before             After              Delta
       ---------------------------  -----------------  -----------------  ------
       Rnd read     4KB q1  1j          52.5 (sd 3.5)     57.1 (sd 16.3)    +8.6%
       Rnd read     4KB q32 1j        108.1 (sd 90.9)    265.3 (sd 74.2)  +145.5%
       Rnd read     4KB q32 4j        117.0 (sd 84.9)    273.0 (sd 80.0)  +133.3%
       Rnd read   128KB q1  1j       835.7 (sd 139.6)    678.0 (sd 67.5)   -18.9%
       Rnd read   128KB q32 1j        802.7 (sd 67.7)   1651.3 (sd 11.0)  +105.7%
       Rnd read   128KB q32 4j       931.3 (sd 262.1)   1685.3 (sd 12.7)   +81.0%
       Rnd read   512KB q1  1j       411.0 (sd 144.0)   799.7 (sd 243.1)   +94.6%
       Rnd read   512KB q32 1j       969.0 (sd 210.7)    1681.7 (sd 9.3)   +73.5%
       Rnd read   512KB q32 4j       889.7 (sd 298.0)   1684.0 (sd 17.4)   +89.3%
       Rnd write    4KB q1  1j         46.0 (sd 15.5)     56.4 (sd 21.3)   +22.5%
       Rnd write    4KB q32 1j         117.7 (sd 4.0)    236.3 (sd 46.3)  +100.8%
       Rnd write    4KB q32 4j         113.0 (sd 5.3)    240.3 (sd 47.9)  +112.7%
       Rnd write  128KB q1  1j       606.7 (sd 149.0)   606.3 (sd 139.3)    -0.1%
       Rnd write  128KB q32 1j       533.6 (sd 512.3)   1263.0 (sd 40.4)  +136.7%
       Rnd write  128KB q32 4j       526.0 (sd 514.9)   1263.0 (sd 40.9)  +140.1%
       Seq read   128KB q1  1j       626.3 (sd 247.5)   743.7 (sd 145.5)   +18.7%
       Seq read   128KB q32 1j        783.3 (sd 51.1)   1658.0 (sd 12.5)  +111.7%
       Seq read   512KB q1  1j       464.0 (sd 191.5)   855.3 (sd 147.2)   +84.3%
       Seq read   512KB q32 1j       918.3 (sd 241.8)    1681.7 (sd 9.2)   +83.1%
       Seq read     1MB q32 1j       918.7 (sd 290.5)   1688.0 (sd 12.5)   +83.7%
       Seq write  128KB q1  1j        611.0 (sd 79.8)   624.0 (sd 152.8)    +2.1%
       Seq write  128KB q32 1j       521.8 (sd 515.3)   1261.7 (sd 41.7)  +141.8%
       Seq write  512KB q1  1j       328.3 (sd 268.7)   727.7 (sd 127.6)  +121.6%
       Seq write  512KB q32 1j       519.6 (sd 516.6)   1262.7 (sd 40.1)  +143.0%
       Seq write    1MB q32 1j       515.1 (sd 517.8)   1262.3 (sd 39.8)  +145.0%
       Rnd rdwr  4K..1MB q8  4j       355.3 (sd 64.7)    898.7 (sd 43.0)  +152.9%

2. pci_endpoint_test

   READ_TEST and WRITE_TEST passed on all three testbeds.

3. R-Car S4 (PCIe Gen4 x2, DWC PCIe controller v5.20a, eDMA) stress

   The non-upstream NTB transport/netdev saturated four HW channels in
   each direction concurrently from multiple QPs. It reached EP->RC 18.7
   Gbit/s and RC->EP 15.7 Gbit/s with iperf3 -ub0, while keeping the DMA
   controller almost continuously busy.

[1] K3 was tested on an Ubuntu kernel with the prerequisite patches
    backported, not directly on the upstream base. The "Before" and
    "After" kernels differ only by this series.

[2] During final testing, I found a separate performance regression
    associated with commit 35de39e4511f ("dmaengine: dw-edma: Defer
    channel IRQ handling to workqueue"). In a spot check, reverting it
    from the eDMA Before kernel raised 512 KiB random-read QD32
    throughput from about 67 MiB/s to 2370 MiB/s.

    The large eDMA deltas above are therefore not the standalone gain
    from dynamic appends. They also reflect that queued transfers can
    continue without waiting for the deferred IRQ path to restart the
    channel. A separate fix for that regression is under investigation.

Best regards,
Koichiro
---
Changes in v2:
  - v2 is a substantial rework; per-patch changelogs contain the details:
    * Rebased onto dmaengine/next.
    * Moved the remaining v1 fixes and state serialization changes into
      the independent groundwork series, now merged in the base.
    * Reworked ring progress around IRQ-paired LLP samples, conservative
      running boundaries, and stopped-tail reconciliation.
    * Reworked STOP/PAUSE handling and added full ring resynchronization
      plus optional direction recovery before enabling dynamic
      submission.
    * Updated trace support for the reworked paths and added engine
      recovery tracing.

v1: https://lore.kernel.org/r/20260615154111.2174161-1-den@valinux.co.jp/


Frank Li (5):
  dmaengine: dw-edma: Add dw_edma_core_ll_cur_idx() to get current LL
    entry index
  dmaengine: dw-edma: Make DMA link list work as a circular buffer
  dmaengine: dw-edma: Move callback result helper before LL helpers
  dmaengine: dw-edma: Dynamically append requests while running
  dmaengine: dw-edma: Add trace support

Koichiro Den (14):
  dmaengine: dw-edma: Add dw_edma_core_ll_clear() to clear LL
    control-word
  dmaengine: dw-edma: Factor out linked-list transfer start
  dmaengine: dw-edma: Add LL interrupt placement policy
  dmaengine: dw-edma: Dispatch DONE interrupts by channel request
  dmaengine: dw-edma: Centralize LL doorbell decisions
  dmaengine: dw-edma: Reclaim issued descriptors from IRQ-paired LL
    progress
  dmaengine: dw-edma: Use HDMA watermarks as progress events
  dmaengine: dw-edma: Reconcile lost completions from a stopped LLP
    re-sample
  dmaengine: dw-edma: Recover stopped channels from tx_status()
  dmaengine: dw-edma: Make the LL ring reset a full channel resync
  dmaengine: dw-edma: Reset LL state after terminate and abort
  dmaengine: dw-edma: Add engine reset and enable operations
  dmaengine: dw-edma: Add engine recovery infrastructure
  dmaengine: dw-edma: Detect and recover a stalled eDMA engine

 drivers/dma/dw-edma/Makefile          |    2 +
 drivers/dma/dw-edma/dw-edma-core.c    | 1069 ++++++++++++++++++++++---
 drivers/dma/dw-edma/dw-edma-core.h    |  104 ++-
 drivers/dma/dw-edma/dw-edma-trace.c   |    4 +
 drivers/dma/dw-edma/dw-edma-trace.h   |  187 +++++
 drivers/dma/dw-edma/dw-edma-v0-core.c |  122 ++-
 drivers/dma/dw-edma/dw-hdma-v0-core.c |  141 +++-
 drivers/dma/dw-edma/dw-hdma-v0-regs.h |    1 +
 8 files changed, 1497 insertions(+), 133 deletions(-)
 create mode 100644 drivers/dma/dw-edma/dw-edma-trace.c
 create mode 100644 drivers/dma/dw-edma/dw-edma-trace.h

base-commit: 0613e7934ee233d726af8d8c89f251a1c4df738d
-- 
2.51.0


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

end of thread, other threads:[~2026-07-23 17:03 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-23  8:41 [PATCH v2 00/19] dmaengine: dw-edma: Support dynamic LL appends Koichiro Den
2026-07-23  8:41 ` [PATCH v2 01/19] dmaengine: dw-edma: Add dw_edma_core_ll_cur_idx() to get current LL entry index Koichiro Den
2026-07-23 16:25   ` Frank Li
2026-07-23  8:41 ` [PATCH v2 02/19] dmaengine: dw-edma: Add dw_edma_core_ll_clear() to clear LL control-word Koichiro Den
2026-07-23  8:41 ` [PATCH v2 03/19] dmaengine: dw-edma: Factor out linked-list transfer start Koichiro Den
2026-07-23 16:31   ` Frank Li
2026-07-23  8:41 ` [PATCH v2 04/19] dmaengine: dw-edma: Make DMA link list work as a circular buffer Koichiro Den
2026-07-23  9:07   ` sashiko-bot
2026-07-23 16:43     ` Frank Li
2026-07-23  8:41 ` [PATCH v2 05/19] dmaengine: dw-edma: Add LL interrupt placement policy Koichiro Den
2026-07-23  8:41 ` [PATCH v2 06/19] dmaengine: dw-edma: Move callback result helper before LL helpers Koichiro Den
2026-07-23 16:51   ` Frank Li
2026-07-23  8:41 ` [PATCH v2 07/19] dmaengine: dw-edma: Dispatch DONE interrupts by channel request Koichiro Den
2026-07-23  8:55   ` sashiko-bot
2026-07-23 16:57   ` Frank Li
2026-07-23  8:41 ` [PATCH v2 08/19] dmaengine: dw-edma: Centralize LL doorbell decisions Koichiro Den
2026-07-23  9:09   ` sashiko-bot
2026-07-23 17:02   ` Frank Li
2026-07-23  8:41 ` [PATCH v2 09/19] dmaengine: dw-edma: Reclaim issued descriptors from IRQ-paired LL progress Koichiro Den
2026-07-23  9:01   ` sashiko-bot
2026-07-23  8:41 ` [PATCH v2 10/19] dmaengine: dw-edma: Use HDMA watermarks as progress events Koichiro Den
2026-07-23  8:41 ` [PATCH v2 11/19] dmaengine: dw-edma: Reconcile lost completions from a stopped LLP re-sample Koichiro Den
2026-07-23  8:41 ` [PATCH v2 12/19] dmaengine: dw-edma: Recover stopped channels from tx_status() Koichiro Den
2026-07-23  8:59   ` sashiko-bot
2026-07-23  8:41 ` [PATCH v2 13/19] dmaengine: dw-edma: Make the LL ring reset a full channel resync Koichiro Den
2026-07-23  9:10   ` sashiko-bot
2026-07-23  8:41 ` [PATCH v2 14/19] dmaengine: dw-edma: Reset LL state after terminate and abort Koichiro Den
2026-07-23  9:14   ` sashiko-bot
2026-07-23  8:41 ` [PATCH v2 15/19] dmaengine: dw-edma: Add engine reset and enable operations Koichiro Den
2026-07-23  9:11   ` sashiko-bot
2026-07-23  8:41 ` [PATCH v2 16/19] dmaengine: dw-edma: Add engine recovery infrastructure Koichiro Den
2026-07-23  9:14   ` sashiko-bot
2026-07-23  8:41 ` [PATCH v2 17/19] dmaengine: dw-edma: Detect and recover a stalled eDMA engine Koichiro Den
2026-07-23  9:12   ` sashiko-bot
2026-07-23  8:41 ` [PATCH v2 18/19] dmaengine: dw-edma: Dynamically append requests while running Koichiro Den
2026-07-23  8:41 ` [PATCH v2 19/19] dmaengine: dw-edma: Add trace support Koichiro Den
2026-07-23  9:11   ` sashiko-bot

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.