[PATCH v7 0/9] PCI: endpoint: pci-ep-msi: Add embedded doorbell fallback

Koichiro Den den at valinux.co.jp
Sun Feb 15 08:38:38 PST 2026


Hi,

Some endpoint platforms cannot use a GIC ITS-backed MSI domain for
EP-side doorbells. In those cases, endpoint function (EPF) drivers
cannot provide a doorbell to the root complex (RC), and features such as
vNTB may fall back to polling with significantly higher latency.

This series adds an alternate doorbell backend based on the DesignWare
PCIe controller's integrated eDMA interrupt-emulation feature. The RC
rings the doorbell by doing a single 32-bit MMIO write to an eDMA
doorbell location exposed in a BAR window. The EP side receives a Linux
IRQ that EPF drivers can use as a doorbell interrupt, without relying on
MSI message writes reaching the ITS.

To support this, the series:

  - Adds an EPC auxiliary resource query API so EPF drivers can discover
    controller-integrated resources (DMA MMIO, doorbell MMIO, and DMA LL
    memory).
  - Updates DesignWare EP controllers to report integrated eDMA
    resources via the new API.
  - Updates dw-edma to provide a dedicated virtual IRQ for interrupt
    emulation and to perform the core-specific deassert sequence.
  - Describes an RK3588 BAR4 reserved subregion so EPF drivers can reuse
    a platform-owned fixed BAR mapping for the doorbell target.
  - Updates pci-epf-test and pci-epf-vntb to reuse a pre-exposed
    BAR/offset and to honor per-doorbell IRQ flags.


Dependencies
------------

The following two split-out series are prerequisite for this series:

  (1). [PATCH 0/4] PCI: endpoint: Doorbell-related fixes
       https://lore.kernel.org/linux-pci/20260215150914.3392479-1-den@valinux.co.jp/
  (2). [PATCH 0/2] dmaengine: dw-edma: Interrupt-emulation doorbell support
       https://lore.kernel.org/dmaengine/20260215152216.3393561-1-den@valinux.co.jp/


Tested on
---------

I tested the embedded (DMA) doorbell fallback path (via pci-epf-test) on
R-Car Spider boards:

  $ ./pci_endpoint_test -t DOORBELL_TEST
  TAP version 13
  1..1
  # Starting 1 tests from 1 test cases.
  #  RUN           pcie_ep_doorbell.DOORBELL_TEST ...
  #            OK  pcie_ep_doorbell.DOORBELL_TEST
  ok 1 pcie_ep_doorbell.DOORBELL_TEST
  # PASSED: 1 / 1 tests passed.
  # Totals: pass:1 fail:0 xfail:0 xpass:0 skip:0 error:0

with the following message observed on the EP side:

  [  109.470756] pci_epf_test pci_epf_test.0: Can't find MSI domain for EPC
  [  109.471302] pci_epf_test pci_epf_test.0: Using embedded (DMA) doorbell fallback

(Note: for the test to pass on R-Car Spider, one of the following was required:
 - echo 1048576 > functions/pci_epf_test/func1/pci_epf_test.0/bar2_size
 - apply https://lore.kernel.org/linux-pci/20260210160315.2272930-1-den@valinux.co.jp/)


Performance test: vNTB ping latency
-----------------------------------

Setup:
  - configfs (R-Car Spider in EP mode):

      cd /sys/kernel/config/pci_ep/
      mkdir functions/pci_epf_vntb/func1
      echo 0x1912 >   functions/pci_epf_vntb/func1/vendorid
      echo 0x0030 >   functions/pci_epf_vntb/func1/deviceid
      echo 32 >       functions/pci_epf_vntb/func1/msi_interrupts
      echo 4 >        functions/pci_epf_vntb/func1/pci_epf_vntb.0/db_count
      echo 128 >      functions/pci_epf_vntb/func1/pci_epf_vntb.0/spad_count
      echo 1 >        functions/pci_epf_vntb/func1/pci_epf_vntb.0/num_mws
      echo 0x100000 > functions/pci_epf_vntb/func1/pci_epf_vntb.0/mw1
      echo 0x1912 >   functions/pci_epf_vntb/func1/pci_epf_vntb.0/vntb_vid
      echo 0x0030 >   functions/pci_epf_vntb/func1/pci_epf_vntb.0/vntb_pid
      echo 0x10 >     functions/pci_epf_vntb/func1/pci_epf_vntb.0/vbus_number
      echo 0 >        functions/pci_epf_vntb/func1/pci_epf_vntb.0/ctrl_bar
      echo 4 >        functions/pci_epf_vntb/func1/pci_epf_vntb.0/db_bar [*]
      echo 2 >        functions/pci_epf_vntb/func1/pci_epf_vntb.0/mw1_bar
      ln -s controllers/e65d0000.pcie-ep functions/pci_epf_vntb/func1/primary/
      echo 1 > controllers/e65d0000.pcie-ep/start

      [*]: On R-Car Spider, a hack is currently needed to use BAR4 for
	   the doorbell. I'll consider posting a patch for that
	   separately.

  - ensure ntb_transport/ntb_netdev are loaded on both sides

Results:

  - Without this series (pci.git main)

    $ ping -c 10 10.0.0.11
    PING 10.0.0.11 (10.0.0.11) 56(84) bytes of data.
    64 bytes from 10.0.0.11: icmp_seq=1 ttl=64 time=6.04 ms
    64 bytes from 10.0.0.11: icmp_seq=2 ttl=64 time=12.6 ms
    64 bytes from 10.0.0.11: icmp_seq=3 ttl=64 time=7.40 ms
    64 bytes from 10.0.0.11: icmp_seq=4 ttl=64 time=5.38 ms
    64 bytes from 10.0.0.11: icmp_seq=5 ttl=64 time=11.4 ms
    64 bytes from 10.0.0.11: icmp_seq=6 ttl=64 time=9.42 ms
    64 bytes from 10.0.0.11: icmp_seq=7 ttl=64 time=3.36 ms
    64 bytes from 10.0.0.11: icmp_seq=8 ttl=64 time=9.48 ms
    64 bytes from 10.0.0.11: icmp_seq=9 ttl=64 time=4.24 ms
    64 bytes from 10.0.0.11: icmp_seq=10 ttl=64 time=10.4 ms

  - With this series (on top of pci.git main + Dependency (1) and (2))

    $ ping -c 10 10.0.0.11
    PING 10.0.0.11 (10.0.0.11) 56(84) bytes of data.
    64 bytes from 10.0.0.11: icmp_seq=1 ttl=64 time=0.623 ms
    64 bytes from 10.0.0.11: icmp_seq=2 ttl=64 time=0.603 ms
    64 bytes from 10.0.0.11: icmp_seq=3 ttl=64 time=0.772 ms
    64 bytes from 10.0.0.11: icmp_seq=4 ttl=64 time=0.769 ms
    64 bytes from 10.0.0.11: icmp_seq=5 ttl=64 time=0.686 ms
    64 bytes from 10.0.0.11: icmp_seq=6 ttl=64 time=0.785 ms
    64 bytes from 10.0.0.11: icmp_seq=7 ttl=64 time=0.789 ms
    64 bytes from 10.0.0.11: icmp_seq=8 ttl=64 time=0.694 ms
    64 bytes from 10.0.0.11: icmp_seq=9 ttl=64 time=0.678 ms
    64 bytes from 10.0.0.11: icmp_seq=10 ttl=64 time=0.773 ms


Changelog
---------

* v6->v7 changes:
  - Split out preparatory patches to keep the series below 10 patches.
  - Add support for platforms where the eDMA register block is fixed
    within a reserved BAR window (e.g. RK3588 BAR4) and must be reused
    as-is.
  - Introduce a dedicated virtual IRQ and irq_chip (using
    handle_level_irq) for interrupt-emulation doorbells instead of
    reusing per-channel IRQs. This avoids delivery via different IRQs on
    platforms with chip->nr_irqs > 1.

* v5->v6 changes:
  - Fix a double-free in v5 Patch 8/8 caused by mixing __free(kfree) with
    an explicit kfree(). This is a functional bug (detectable by KASAN),
    hence the respin solely for this fix. Sorry for the noise. No other
    changes.

* v4->v5 changes:
  - Change the series subject now that the series has evolved into a
    consumer-driven set focused on the embedded doorbell fallback and its
    in-tree users (epf-test and epf-vntb).
  - Drop [PATCH v4 01/09] (dw-edma per-channel interrupt routing control)
    from this series for now, so the series focuses on what's needed by the
    current consumer (i.e. the doorbell fallback implementation).
  - Replace the v4 embedded-doorbell "test variant + host/kselftest
    plumbing" with a generic embedded-doorbell fallback in
    pci_epf_alloc_doorbell(), including exposing required IRQ request flags
    to EPF drivers.
  - Two preparatory fix patches (Patch 6/8 and 7/8) to clean up error
    handling and state management ahead of Patch 8/8.
  - Rename *_get_remote_resource() to *_get_aux_resources() and adjust
    relevant variable namings and kernel docs. Discussion may continue.
  - Rework dw-edma per-channel metadata exposure to cache the needed info
    in dw_edma_chip (IRQ number + emulation doorbell offset) and consume it
    from the DesignWare EPC auxiliary resource provider without calling back
    to dw-edma.

* v3->v4 changes:
  - Drop dma_slave_caps.hw_id and the dmaengine selfirq callback
    registration API. Instead, add a dw-edma specific dw_edma_chan_info()
    helper and extend the EPC remote resource metadata accordingly.
  - Add explicit acking for eDMA interrupt emulation and adjust the
    dw-edma IRQ path for embedded-doorbell usage.
  - Replace the previous EPC API smoke test with an embedded doorbell
    test variant (pci-epf-test + pci_endpoint_test/selftests).
  - Rebase onto pci.git controller/dwc commit 43d324eeb08c.

* v2->v3 changes:
  - Replace DWC-specific helpers with a generic EPC remote resource query API.
  - Add pci-epf-test smoke test and host/kselftest support for the new API.
  - Drop the dw-edma-specific notify-only channel and polling approach
    ([PATCH v2 4/7] and [PATCH v2 5/7]), and rework notification handling
    around a generic dmaengine_(un)register_selfirq() API implemented
    by dw-edma.

* v1->v2 changes:
  - Combine the two previously posted series into a single set (per Frank's
    suggestion). Order dmaengine/dw-edma patches first so hw_id support
    lands before the PCI LL-region helper, which assumes
    dma_slave_caps.hw_id availability.

v6: https://lore.kernel.org/all/20260209125316.2132589-1-den@valinux.co.jp/
v5: https://lore.kernel.org/all/20260209062952.2049053-1-den@valinux.co.jp/
v4: https://lore.kernel.org/all/20260206172646.1556847-1-den@valinux.co.jp/
v3: https://lore.kernel.org/all/20260204145440.950609-1-den@valinux.co.jp/
v2: https://lore.kernel.org/all/20260127033420.3460579-1-den@valinux.co.jp/
v1: https://lore.kernel.org/dmaengine/20260126073652.3293564-1-den@valinux.co.jp/
    +
    https://lore.kernel.org/linux-pci/20260126071550.3233631-1-den@valinux.co.jp/


Thanks for reviewing.

Many thanks to Frank and Niklas for the continued review and
constructive feedback throughout the development of this series.


Koichiro Den (9):
  PCI: endpoint: Describe reserved subregions within BARs
  PCI: dw-rockchip: Describe RK3588 BAR4 DMA ctrl window
  PCI: endpoint: Add auxiliary resource query API
  PCI: dwc: Record integrated eDMA register window
  PCI: dwc: ep: Expose integrated eDMA resources via EPC aux-resource
    API
  PCI: endpoint: pci-ep-msi: Refactor doorbell allocation for new
    backends
  PCI: endpoint: pci-epf-vntb: Reuse pre-exposed doorbells and IRQ flags
  PCI: endpoint: pci-epf-test: Reuse pre-exposed doorbell targets
  PCI: endpoint: pci-ep-msi: Add embedded eDMA doorbell fallback

 .../pci/controller/dwc/pcie-designware-ep.c   | 149 ++++++++++++++++++
 drivers/pci/controller/dwc/pcie-designware.c  |   4 +
 drivers/pci/controller/dwc/pcie-designware.h  |   2 +
 drivers/pci/controller/dwc/pcie-dw-rockchip.c |  15 +-
 drivers/pci/endpoint/functions/pci-epf-test.c |  84 ++++++----
 drivers/pci/endpoint/functions/pci-epf-vntb.c |  57 ++++++-
 drivers/pci/endpoint/pci-ep-msi.c             | 143 +++++++++++++++--
 drivers/pci/endpoint/pci-epc-core.c           |  41 +++++
 include/linux/pci-epc.h                       |  79 ++++++++++
 include/linux/pci-epf.h                       |  23 ++-
 10 files changed, 548 insertions(+), 49 deletions(-)

-- 
2.51.0




More information about the Linux-rockchip mailing list