All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/13] raw/ntb: post-merge fixes
@ 2026-11-04 11:19 Raghavendra Ningoji
  2026-11-04 11:19 ` [PATCH 01/13] raw/ntb: fix device check in memory alignment query Raghavendra Ningoji
                   ` (29 more replies)
  0 siblings, 30 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-04 11:19 UTC (permalink / raw)
  To: dev
  Cc: jingjing.wu, thomas, selwin.sebastian, bhagyada.modali,
	bruce.richardson, david.marchand, stephen

This series addresses the post-merge review of the AMD NTB support
by Stephen. Some of the issues also exist in the Intel code and in
released versions; those patches are tagged for stable.

- Patches 1-4 fix the type confusion in rte_pmd_ntb_get_mem_align(),
  the unbounded peer memory window count, the off-by-one in the
  address remapping and the memory window leaks.

- Patch 5 fixes the doorbell interrupts with vfio-pci: only MSI-X
  vector 0 (DB0) was serviced, so the DB1/DB2 exchange of dev_stop
  never completed and the stop waited for its 1s timeout.

- Patch 7 removes the AMD hardware event handling, which could not run
  as wired, and documents that hardware events are not handled.

- Patches 8-9 fix the Rx path: a partially consumed packet was leaked
  and desynchronized the ring, and an mbuf owned by the application
  could be freed again on device stop.

- The other patches are documentation and cleanup.

The peer memory window size check suggested for the AMD handshake is
not added: all the AMD scratchpads are in use, and the window limit
register programmed with the local memzone length already bounds what
the peer can reach.

Tested with vfio-pci on two AMD EPYC Embedded hosts: handshake,
file transfer, and stop/quit with DB1/DB2 exchange.

Raghavendra Ningoji (13):
  raw/ntb: fix device check in memory alignment query
  raw/ntb: fix peer memory window count check
  raw/ntb: fix memory window bound in address remapping
  raw/ntb: fix memory leaks
  raw/ntb: fix doorbell interrupts with VFIO MSI-X
  raw/ntb: fix AMD processor names
  raw/ntb: remove AMD hardware event handling
  raw/ntb: fix Rx of incomplete packets
  raw/ntb: fix double free of Rx mbufs on stop
  examples/ntb: fix raw/ntb library linking
  doc: add NTB device info change to ABI section
  doc: add IOVA requirement for NTB
  raw/ntb: remove unused AMD register definitions

 doc/guides/rawdevs/ntb.rst             |  12 ++-
 doc/guides/rel_notes/release_26_11.rst |   6 +-
 drivers/raw/ntb/ntb.c                  | 136 ++++++++++++++++++++-----
 drivers/raw/ntb/ntb.h                  |   7 +-
 drivers/raw/ntb/ntb_hw_amd.c           |  54 ++--------
 drivers/raw/ntb/ntb_hw_amd.h           |  25 +----
 drivers/raw/ntb/ntb_hw_intel.c         |   9 +-
 examples/ntb/Makefile                  |   3 +-
 8 files changed, 149 insertions(+), 103 deletions(-)

-- 
2.34.1


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

* [PATCH 01/13] raw/ntb: fix device check in memory alignment query
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
@ 2026-11-04 11:19 ` Raghavendra Ningoji
  2026-11-04 11:19 ` [PATCH 02/13] raw/ntb: fix peer memory window count check Raghavendra Ningoji
                   ` (28 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-04 11:19 UTC (permalink / raw)
  To: dev
  Cc: jingjing.wu, thomas, selwin.sebastian, bhagyada.modali,
	bruce.richardson, david.marchand, stephen

rte_pmd_ntb_get_mem_align() only checked the device index range and
the presence of private data before casting it to struct ntb_hw.
Passing the id of a detached slot or of a rawdev from another driver
would then call through a garbage ops pointer.

Check that the device is attached and is driven by this PMD.

Also return 0 for an out of range memory window index, as documented,
instead of a cache line size.

Fixes: 5ce50c234ad1 ("raw/ntb: generalize framework for multiple vendors")

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index fe10782ecf..e42af0b9c5 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -33,6 +33,8 @@ static const struct rte_pci_id pci_id_ntb_map[] = {
 	{ .vendor_id = 0, /* sentinel */ },
 };
 
+static const struct rte_rawdev_ops ntb_ops;
+
 /* Align with enum ntb_xstats_idx */
 static struct rte_rawdev_xstats_name ntb_xstats_names[] = {
 	{"Tx-packets"},
@@ -722,15 +724,15 @@ rte_pmd_ntb_get_mem_align(uint16_t dev_id, uint32_t mw_id, uint64_t mw_len)
 	struct rte_rawdev *dev;
 	struct ntb_hw *hw;
 
-	if (dev_id >= RTE_RAWDEV_MAX_DEVS)
+	if (dev_id >= RTE_RAWDEV_MAX_DEVS || !rte_rawdev_pmd_is_valid_dev(dev_id))
 		return 0;
 	dev = rte_rawdev_pmd_get_dev(dev_id);
-	if (dev->dev_private == NULL)
+	if (dev->dev_ops != &ntb_ops)
 		return 0;
 
 	hw = dev->dev_private;
 	if (mw_id >= hw->mw_cnt)
-		return RTE_CACHE_LINE_SIZE;
+		return 0;
 
 	return (*hw->ntb_ops->mem_align)(dev, mw_id, mw_len);
 }
-- 
2.34.1


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

* [PATCH 02/13] raw/ntb: fix peer memory window count check
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
  2026-11-04 11:19 ` [PATCH 01/13] raw/ntb: fix device check in memory alignment query Raghavendra Ningoji
@ 2026-11-04 11:19 ` Raghavendra Ningoji
  2026-11-04 11:19 ` [PATCH 03/13] raw/ntb: fix memory window bound in address remapping Raghavendra Ningoji
                   ` (27 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-04 11:19 UTC (permalink / raw)
  To: dev
  Cc: jingjing.wu, thomas, selwin.sebastian, bhagyada.modali,
	bruce.richardson, david.marchand, stephen, stable

The number of memory windows used by the peer is read from a
scratchpad register written by the peer, and is then used as the loop
bound to fill peer_mw_base[], which is allocated with mw_cnt entries.
A peer advertising more windows (bug, version mismatch, or a stale
scratchpad) makes the driver write past the end of this array.
On Intel, the 32-bit register value was also silently truncated into
the 8-bit peer_used_mws field.

Reject a peer configuration using more windows than the local device
has.

Fixes: c39d1e082a4b ("raw/ntb: setup queues")
Fixes: d6dc5a7f8b06 ("raw/ntb: support AMD NTB")
Cc: stable@dpdk.org

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb_hw_amd.c   | 10 ++++++++--
 drivers/raw/ntb/ntb_hw_intel.c |  7 ++++++-
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/raw/ntb/ntb_hw_amd.c b/drivers/raw/ntb/ntb_hw_amd.c
index ab78675218..dba5b03671 100644
--- a/drivers/raw/ntb/ntb_hw_amd.c
+++ b/drivers/raw/ntb/ntb_hw_amd.c
@@ -502,7 +502,7 @@ static int
 amd_ntb_read_peer_config(const struct rte_rawdev *dev)
 {
 	struct ntb_hw *ntb = dev->dev_private;
-	uint32_t info, peer_qps, peer_qsz, lo, hi;
+	uint32_t info, peer_qps, peer_qsz, peer_used_mws, lo, hi;
 	int i;
 
 	info = amd_ntb_spad_read(dev, AMD_SPAD_CNT_INFO, 0);
@@ -520,7 +520,13 @@ amd_ntb_read_peer_config(const struct rte_rawdev *dev)
 		return -EINVAL;
 	}
 
-	ntb->peer_used_mws = (info >> 16) & 0xff;
+	peer_used_mws = (info >> 16) & 0xff;
+	if (peer_used_mws > ntb->mw_cnt) {
+		NTB_LOG(ERR, "Peer used mws %u > mw cnt %u.", peer_used_mws, ntb->mw_cnt);
+		return -EINVAL;
+	}
+	ntb->peer_used_mws = peer_used_mws;
+
 	for (i = 0; i < ntb->peer_used_mws; i++) {
 		lo = amd_ntb_spad_read(dev, AMD_SPAD_MW0_BA_L + 2 * i, 0);
 		hi = amd_ntb_spad_read(dev, AMD_SPAD_MW0_BA_H + 2 * i, 0);
diff --git a/drivers/raw/ntb/ntb_hw_intel.c b/drivers/raw/ntb/ntb_hw_intel.c
index 1b784055ca..78fce9ffac 100644
--- a/drivers/raw/ntb/ntb_hw_intel.c
+++ b/drivers/raw/ntb/ntb_hw_intel.c
@@ -724,7 +724,12 @@ intel_ntb_read_peer_config(const struct rte_rawdev *dev)
 		return -EINVAL;
 	}
 
-	hw->peer_used_mws = intel_ntb_spad_read(dev, SPAD_USED_MWS, 0);
+	peer_val = intel_ntb_spad_read(dev, SPAD_USED_MWS, 0);
+	if (peer_val > hw->mw_cnt) {
+		NTB_LOG(ERR, "Peer used mws %u > mw cnt %u.", peer_val, hw->mw_cnt);
+		return -EINVAL;
+	}
+	hw->peer_used_mws = peer_val;
 
 	for (i = 0; i < hw->peer_used_mws; i++) {
 		peer_base_h = intel_ntb_spad_read(dev, SPAD_MW0_BA_H + 2 * i, 0);
-- 
2.34.1


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

* [PATCH 03/13] raw/ntb: fix memory window bound in address remapping
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
  2026-11-04 11:19 ` [PATCH 01/13] raw/ntb: fix device check in memory alignment query Raghavendra Ningoji
  2026-11-04 11:19 ` [PATCH 02/13] raw/ntb: fix peer memory window count check Raghavendra Ningoji
@ 2026-11-04 11:19 ` Raghavendra Ningoji
  2026-11-04 11:19 ` [PATCH 04/13] raw/ntb: fix memory leaks Raghavendra Ningoji
                   ` (26 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-04 11:19 UTC (permalink / raw)
  To: dev
  Cc: jingjing.wu, thomas, selwin.sebastian, bhagyada.modali,
	bruce.richardson, david.marchand, stephen, stable

When translating a peer address into the local mapping of a memory
window, the end of the window was included in the accepted range,
so an address one byte past the window was mapped.

Exclude the end of the window.

Fixes: 11b5c7daf019 ("raw/ntb: add enqueue and dequeue functions")
Fixes: d6dc5a7f8b06 ("raw/ntb: support AMD NTB")
Cc: stable@dpdk.org

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb_hw_amd.c   | 2 +-
 drivers/raw/ntb/ntb_hw_intel.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/raw/ntb/ntb_hw_amd.c b/drivers/raw/ntb/ntb_hw_amd.c
index dba5b03671..64075501c2 100644
--- a/drivers/raw/ntb/ntb_hw_amd.c
+++ b/drivers/raw/ntb/ntb_hw_amd.c
@@ -166,7 +166,7 @@ amd_ntb_ioremap(const struct rte_rawdev *dev, uint64_t addr)
 
 	for (i = 0; i < ntb->peer_used_mws; i++) {
 		if (addr >= ntb->peer_mw_base[i] &&
-				addr <= ntb->peer_mw_base[i] + ntb->mw_size[i]) {
+				addr < ntb->peer_mw_base[i] + ntb->mw_size[i]) {
 			base = amd_ntb_get_peer_mw_addr(dev, i);
 			mapped = (void *)(size_t)(addr - ntb->peer_mw_base[i] + (size_t)base);
 			break;
diff --git a/drivers/raw/ntb/ntb_hw_intel.c b/drivers/raw/ntb/ntb_hw_intel.c
index 78fce9ffac..47d5d39339 100644
--- a/drivers/raw/ntb/ntb_hw_intel.c
+++ b/drivers/raw/ntb/ntb_hw_intel.c
@@ -312,7 +312,7 @@ intel_ntb_ioremap(const struct rte_rawdev *dev, uint64_t addr)
 
 	for (i = 0; i < hw->peer_used_mws; i++) {
 		if (addr >= hw->peer_mw_base[i] &&
-		    addr <= hw->peer_mw_base[i] + hw->mw_size[i]) {
+		    addr < hw->peer_mw_base[i] + hw->mw_size[i]) {
 			base = intel_ntb_get_peer_mw_addr(dev, i);
 			mapped = (void *)(size_t)(addr - hw->peer_mw_base[i] +
 				 (size_t)base);
-- 
2.34.1


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

* [PATCH 04/13] raw/ntb: fix memory leaks
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (2 preceding siblings ...)
  2026-11-04 11:19 ` [PATCH 03/13] raw/ntb: fix memory window bound in address remapping Raghavendra Ningoji
@ 2026-11-04 11:19 ` Raghavendra Ningoji
  2026-11-04 11:19 ` [PATCH 05/13] raw/ntb: fix doorbell interrupts with VFIO MSI-X Raghavendra Ningoji
                   ` (25 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-04 11:19 UTC (permalink / raw)
  To: dev
  Cc: jingjing.wu, thomas, selwin.sebastian, bhagyada.modali,
	bruce.richardson, david.marchand, stephen, stable

The memory window size array allocated by the vendor init at probe
time was never freed.
The peer memory window base array allocated at each device start was
only freed if the start failed, so it leaked on every stop/start cycle.

Free the peer memory window base array when stopping the device, and
the memory window size array when closing it (which also happens on
device removal and on probe failure).

Fixes: c39d1e082a4b ("raw/ntb: setup queues")
Cc: stable@dpdk.org

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index e42af0b9c5..af3fcd832b 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -820,6 +820,8 @@ ntb_dev_start(struct rte_rawdev *dev)
 
 err_up:
 	rte_free(hw->peer_mw_base);
+	hw->peer_mw_base = NULL;
+	hw->peer_used_mws = 0;
 err_q_init:
 	for (i = 0; i < hw->queue_pairs; i++) {
 		ntb_rxq_release_mbufs(hw->rx_queues[i]);
@@ -872,6 +874,10 @@ ntb_dev_stop(struct rte_rawdev *dev)
 		ntb_txq_release_mbufs(hw->tx_queues[i]);
 	}
 
+	rte_free(hw->peer_mw_base);
+	hw->peer_mw_base = NULL;
+	hw->peer_used_mws = 0;
+
 	dev->started = 0;
 }
 
@@ -890,6 +896,9 @@ ntb_dev_close(struct rte_rawdev *dev)
 		ntb_queue_release(dev, i);
 	hw->queue_pairs = 0;
 
+	rte_free(hw->mw_size);
+	hw->mw_size = NULL;
+
 	intr_handle = hw->pci_dev->intr_handle;
 	/* Disable interrupt only once */
 	if (!rte_intr_nb_efd_get(intr_handle) &&
-- 
2.34.1


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

* [PATCH 05/13] raw/ntb: fix doorbell interrupts with VFIO MSI-X
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (3 preceding siblings ...)
  2026-11-04 11:19 ` [PATCH 04/13] raw/ntb: fix memory leaks Raghavendra Ningoji
@ 2026-11-04 11:19 ` Raghavendra Ningoji
  2026-11-04 11:19 ` [PATCH 06/13] raw/ntb: fix AMD processor names Raghavendra Ningoji
                   ` (24 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-04 11:19 UTC (permalink / raw)
  To: dev
  Cc: jingjing.wu, thomas, selwin.sebastian, bhagyada.modali,
	bruce.richardson, david.marchand, stephen, stable

With VFIO MSI-X, each doorbell raises its own vector. Vector 0 is
signalled on the PCI device interrupt handle while the others are
signalled on the eventfds created by rte_intr_efd_enable(), but the
interrupt handler was only registered on the device interrupt handle.

As a result, doorbells other than DB0 were only noticed when DB0 fired
at the same time. In particular, the DB1 rung by the peer in its
dev_stop was never handled, the peer never got the DB2 answer and had
to wait for the 1s timeout.

Register the interrupt handler on each doorbell eventfd as well.

Fixes: 62012a76811e ("raw/ntb: add handshake process")
Cc: stable@dpdk.org

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb.c | 77 ++++++++++++++++++++++++++++++++++++++++++-
 drivers/raw/ntb/ntb.h |  4 +++
 2 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index af3fcd832b..a1993121dd 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -11,6 +11,7 @@
 #include <rte_lcore.h>
 #include <rte_cycles.h>
 #include <rte_eal.h>
+#include <rte_errno.h>
 #include <rte_log.h>
 #include <rte_pci.h>
 #include <rte_mbuf.h>
@@ -124,6 +125,74 @@ ntb_dev_intr_handler(void *param)
 		(*hw->ntb_ops->handle_hw_event)(dev);
 }
 
+static void
+ntb_db_intr_unregister(struct rte_rawdev *dev)
+{
+	struct ntb_hw *hw = dev->dev_private;
+	struct rte_intr_handle *handle;
+	uint16_t i;
+
+	for (i = 0; i < hw->nb_db_intr_handles; i++) {
+		handle = hw->db_intr_handles[i];
+		rte_intr_callback_unregister_sync(handle,
+						  ntb_dev_intr_handler, dev);
+		/* The eventfd is owned by the PCI device interrupt handle. */
+		rte_intr_fd_set(handle, -1);
+		rte_intr_instance_free(handle);
+	}
+	rte_free(hw->db_intr_handles);
+	hw->db_intr_handles = NULL;
+	hw->nb_db_intr_handles = 0;
+}
+
+/*
+ * With MSI-X, only vector 0 is serviced through the PCI device interrupt
+ * handle. Each other doorbell raises its own vector, signalled on the
+ * eventfds created by rte_intr_efd_enable(): register the handler on them.
+ */
+static int
+ntb_db_intr_register(struct rte_rawdev *dev,
+		     struct rte_intr_handle *intr_handle)
+{
+	struct ntb_hw *hw = dev->dev_private;
+	int nb_efd = rte_intr_nb_efd_get(intr_handle);
+	struct rte_intr_handle *handle;
+	int i, ret;
+
+	hw->db_intr_handles = rte_zmalloc("ntb_db_intr",
+				nb_efd * sizeof(*hw->db_intr_handles), 0);
+	if (hw->db_intr_handles == NULL)
+		return -ENOMEM;
+
+	for (i = 0; i < nb_efd; i++) {
+		handle = rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_PRIVATE);
+		if (handle == NULL) {
+			ret = -ENOMEM;
+			goto err;
+		}
+		hw->db_intr_handles[hw->nb_db_intr_handles++] = handle;
+
+		if (rte_intr_type_set(handle, RTE_INTR_HANDLE_VFIO_MSIX) ||
+		    rte_intr_fd_set(handle,
+				    rte_intr_efds_index_get(intr_handle, i))) {
+			ret = -rte_errno;
+			goto err;
+		}
+
+		ret = rte_intr_callback_register(handle,
+						 ntb_dev_intr_handler, dev);
+		if (ret)
+			goto err;
+	}
+
+	return 0;
+
+err:
+	NTB_LOG(ERR, "Failed to register doorbell interrupt %d.", i + 1);
+	ntb_db_intr_unregister(dev);
+	return ret;
+}
+
 static int
 ntb_queue_conf_get(struct rte_rawdev *dev,
 		   uint16_t queue_id,
@@ -905,6 +974,8 @@ ntb_dev_close(struct rte_rawdev *dev)
 	    !rte_intr_max_intr_get(intr_handle))
 		return 0;
 
+	ntb_db_intr_unregister(dev);
+
 	/* Clean datapath event and vec mapping */
 	rte_intr_efd_disable(intr_handle);
 	rte_intr_vec_list_free(intr_handle);
@@ -1308,7 +1379,11 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
 	 * by default for intel gen3. They are mapped to msix vec 1-32,
 	 * and hardware intr is mapped to 0. Map all to 0 for uio.
 	 */
-	if (!rte_intr_cap_multiple(intr_handle)) {
+	if (rte_intr_cap_multiple(intr_handle)) {
+		ret = ntb_db_intr_register(dev, intr_handle);
+		if (ret)
+			return ret;
+	} else {
 		for (i = 0; i < hw->db_cnt; i++) {
 			ret = (*hw->ntb_ops->vector_bind)(dev, i, 0);
 			if (ret)
diff --git a/drivers/raw/ntb/ntb.h b/drivers/raw/ntb/ntb.h
index 0181bec5c9..2787883160 100644
--- a/drivers/raw/ntb/ntb.h
+++ b/drivers/raw/ntb/ntb.h
@@ -219,6 +219,10 @@ struct ntb_hw {
 	struct rte_pci_device *pci_dev;
 	char *hw_addr;
 
+	/* Interrupt handles for the MSI-X doorbell vectors besides vector 0. */
+	struct rte_intr_handle **db_intr_handles;
+	uint16_t nb_db_intr_handles;
+
 	uint8_t peer_dev_up;
 	uint64_t *mw_size;
 	/* remote mem base addr */
-- 
2.34.1


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

* [PATCH 06/13] raw/ntb: fix AMD processor names
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (4 preceding siblings ...)
  2026-11-04 11:19 ` [PATCH 05/13] raw/ntb: fix doorbell interrupts with VFIO MSI-X Raghavendra Ningoji
@ 2026-11-04 11:19 ` Raghavendra Ningoji
  2026-11-04 11:19 ` [PATCH 07/13] raw/ntb: remove AMD hardware event handling Raghavendra Ningoji
                   ` (23 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-04 11:19 UTC (permalink / raw)
  To: dev
  Cc: jingjing.wu, thomas, selwin.sebastian, bhagyada.modali,
	bruce.richardson, david.marchand, stephen

Refer to the AMD processors integrating the NTB endpoints by their
EPYC Embedded 9004/9005/8004 series numbers rather than code names.

Fixes: d6dc5a7f8b06 ("raw/ntb: support AMD NTB")

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 doc/guides/rawdevs/ntb.rst             | 4 ++--
 doc/guides/rel_notes/release_26_11.rst | 4 ++--
 drivers/raw/ntb/ntb_hw_amd.h           | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/doc/guides/rawdevs/ntb.rst b/doc/guides/rawdevs/ntb.rst
index 99474745d6..37328cd9e6 100644
--- a/doc/guides/rawdevs/ntb.rst
+++ b/doc/guides/rawdevs/ntb.rst
@@ -41,7 +41,7 @@ AMD EPYC Embedded NTB
 ---------------------
 
 The driver also supports the NTB endpoints integrated in AMD EPYC Embedded
-"Turin", "Genoa" and "Siena" processors.
+9004/9005/8004 processors.
 These use a primary/secondary topology rather than the Intel back-to-back topology:
 one endpoint is enumerated as the primary (device ID ``0x14c0``) and
 the other as the secondary (device ID ``0x14c3``).
@@ -179,7 +179,7 @@ Limitation
 
 This PMD is supported on:
 
-- AMD EPYC Embedded "Turin", "Genoa" and "Siena" processors.
+- AMD EPYC Embedded 9004/9005/8004 processors.
 - 4th Generation Intel® Xeon® Scalable Processors.
 - 3rd Generation Intel® Xeon® Scalable Processors.
 - 2nd Generation Intel® Xeon® Scalable Processors.
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index 8ca8379cc6..6c76c60139 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -306,8 +306,8 @@ New Features
 
 * **Added AMD NTB support to the NTB rawdev driver.**
 
-  Added support for the NTB endpoints integrated in AMD EPYC Embedded "Turin", "Genoa"
-  and "Siena" processors to the ``raw/ntb`` driver.
+  Added support for the NTB endpoints integrated in AMD EPYC Embedded
+  9004/9005/8004 processors to the ``raw/ntb`` driver.
   The NTB rawdev framework was generalized to support multiple vendors,
   with AMD-specific hardware access, a primary/secondary topology
   and a packed scratchpad handshake.
diff --git a/drivers/raw/ntb/ntb_hw_amd.h b/drivers/raw/ntb/ntb_hw_amd.h
index 48f0db1ad4..b03aed7d08 100644
--- a/drivers/raw/ntb/ntb_hw_amd.h
+++ b/drivers/raw/ntb/ntb_hw_amd.h
@@ -7,7 +7,7 @@
 
 #include <stdint.h>
 
-/* NTB vendor and device IDs (EPYC Embedded Turin/Genoa/Siena). */
+/* NTB vendor and device IDs (EPYC Embedded 9004/9005/8004). */
 #define NTB_AMD_VENDOR_ID		0x1022
 #define NTB_AMD_DEV_ID_PRI		0x14c0	/* Primary NTB endpoint. */
 #define NTB_AMD_DEV_ID_SEC		0x14c3	/* Secondary NTB endpoint. */
-- 
2.34.1


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

* [PATCH 07/13] raw/ntb: remove AMD hardware event handling
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (5 preceding siblings ...)
  2026-11-04 11:19 ` [PATCH 06/13] raw/ntb: fix AMD processor names Raghavendra Ningoji
@ 2026-11-04 11:19 ` Raghavendra Ningoji
  2026-11-04 11:19 ` [PATCH 08/13] raw/ntb: fix Rx of incomplete packets Raghavendra Ningoji
                   ` (22 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-04 11:19 UTC (permalink / raw)
  To: dev
  Cc: jingjing.wu, thomas, selwin.sebastian, bhagyada.modali,
	bruce.richardson, david.marchand, stephen

The AMD hardware event handler could never run: the event interrupts
were never unmasked, their MSI-X vectors were never enabled and the
handler was only reached when no known doorbell was pending.
It also mishandled several simultaneous events and never cleared
the interrupt status.

Remove it, together with the now unused vendor operation and
register definitions, and document that hardware events are not
handled.

Fixes: d6dc5a7f8b06 ("raw/ntb: support AMD NTB")

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 doc/guides/rawdevs/ntb.rst   |  4 ++++
 drivers/raw/ntb/ntb.c        |  4 ----
 drivers/raw/ntb/ntb.h        |  3 ---
 drivers/raw/ntb/ntb_hw_amd.c | 42 +-----------------------------------
 drivers/raw/ntb/ntb_hw_amd.h | 21 ------------------
 5 files changed, 5 insertions(+), 69 deletions(-)

diff --git a/doc/guides/rawdevs/ntb.rst b/doc/guides/rawdevs/ntb.rst
index 37328cd9e6..c4ad2f05c4 100644
--- a/doc/guides/rawdevs/ntb.rst
+++ b/doc/guides/rawdevs/ntb.rst
@@ -53,6 +53,10 @@ The AMD NTB hardware exposes two memory windows (BAR23 and BAR45),
 The scratchpad bank is split into two disjoint 8-register sets, one owned by each side,
 so the driver uses a packed handshake layout that fits within 8 registers.
 
+The AMD NTB hardware events (link up/down, peer reset, power state changes)
+are not handled: a peer going away is only detected through the doorbell
+handshake done when the peer device is stopped.
+
 The AMD NTB uses an outbound translation window:
 a write to a memory window offset is forwarded to ``(base | offset)`` in the peer's memory
 rather than ``(base + offset)``.
diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index a1993121dd..d514ed669f 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -119,10 +119,6 @@ ntb_dev_intr_handler(void *param)
 
 	/* Clear other received doorbells. */
 	(*hw->ntb_ops->db_clear)(dev, db_bits);
-
-	/* Let the vendor process any hardware-specific events. */
-	if (hw->ntb_ops->handle_hw_event != NULL)
-		(*hw->ntb_ops->handle_hw_event)(dev);
 }
 
 static void
diff --git a/drivers/raw/ntb/ntb.h b/drivers/raw/ntb/ntb.h
index 2787883160..2434997e84 100644
--- a/drivers/raw/ntb/ntb.h
+++ b/drivers/raw/ntb/ntb.h
@@ -102,8 +102,6 @@ enum ntb_spad_idx {
  * @link_cleanup: Tear down the local scratchpad/translation state so the
  * peer can no longer reach local memory.
  * @mem_align: Base-address alignment required for a memory window memzone of a given length.
- * @handle_hw_event: Optional. Process vendor-specific hardware events from
- * the common interrupt handler. May be NULL.
  */
 struct ntb_dev_ops {
 	int (*ntb_dev_init)(const struct rte_rawdev *dev);
@@ -126,7 +124,6 @@ struct ntb_dev_ops {
 	int (*read_peer_config)(const struct rte_rawdev *dev);
 	void (*link_cleanup)(const struct rte_rawdev *dev);
 	uint64_t (*mem_align)(const struct rte_rawdev *dev, uint32_t mw_id, uint64_t mw_len);
-	void (*handle_hw_event)(const struct rte_rawdev *dev);
 };
 
 struct ntb_desc {
diff --git a/drivers/raw/ntb/ntb_hw_amd.c b/drivers/raw/ntb/ntb_hw_amd.c
index 64075501c2..47e4979619 100644
--- a/drivers/raw/ntb/ntb_hw_amd.c
+++ b/drivers/raw/ntb/ntb_hw_amd.c
@@ -445,7 +445,7 @@ static int
 amd_ntb_vector_bind(const struct rte_rawdev *dev __rte_unused, uint8_t intr __rte_unused,
 		uint8_t msix __rte_unused)
 {
-	/* Each doorbell/event maps to its MSI-X vector by default. */
+	/* Each doorbell maps to its MSI-X vector by default. */
 	return 0;
 }
 
@@ -569,45 +569,6 @@ amd_ntb_link_cleanup(const struct rte_rawdev *dev)
 		amd_ntb_mw_set_trans(dev, i, 0, 0);
 }
 
-/* Handle link/power-management events and acknowledge the SMU. Invoked from
- * the common interrupt handler when no inter-device doorbell is pending.
- */
-static void
-amd_ntb_handle_hw_event(const struct rte_rawdev *dev)
-{
-	struct ntb_hw *ntb = dev->dev_private;
-	uint32_t event, ack;
-
-	event = rte_read32((char *)ntb->hw_addr + AMD_INTSTAT_OFFSET);
-	event &= AMD_EVENT_INTMASK;
-	if (event == 0)
-		return;
-
-	switch (event) {
-	case AMD_PEER_FLUSH_EVENT:
-		NTB_LOG(INFO, "Peer flush event.");
-		break;
-	case AMD_PEER_D0_EVENT:
-		ack = rte_read32((char *)ntb->hw_addr + AMD_PMESTAT_OFFSET);
-		if (ack & 0x1)
-			NTB_LOG(INFO, "D0 wakeup completed for NTB.");
-		/* fall through to ack the SMU */
-		/* Falls through. */
-	case AMD_PEER_RESET_EVENT:
-	case AMD_LINK_DOWN_EVENT:
-	case AMD_PEER_D3_EVENT:
-	case AMD_PEER_PMETO_EVENT:
-	case AMD_LINK_UP_EVENT:
-		ack = rte_read32((char *)ntb->hw_addr + AMD_SMUACK_OFFSET);
-		ack |= event;
-		rte_write32(ack, (char *)ntb->hw_addr + AMD_SMUACK_OFFSET);
-		break;
-	default:
-		NTB_LOG(ERR, "Unknown interrupt event 0x%" PRIx32, event);
-		break;
-	}
-}
-
 static uint64_t
 amd_ntb_get_mem_align(const struct rte_rawdev *dev __rte_unused, uint32_t mw_id __rte_unused,
 		uint64_t mw_len)
@@ -634,5 +595,4 @@ const struct ntb_dev_ops amd_ntb_ops = {
 	.read_peer_config	= amd_ntb_read_peer_config,
 	.link_cleanup		= amd_ntb_link_cleanup,
 	.mem_align		= amd_ntb_get_mem_align,
-	.handle_hw_event	= amd_ntb_handle_hw_event,
 };
diff --git a/drivers/raw/ntb/ntb_hw_amd.h b/drivers/raw/ntb/ntb_hw_amd.h
index b03aed7d08..8fffa24348 100644
--- a/drivers/raw/ntb/ntb_hw_amd.h
+++ b/drivers/raw/ntb/ntb_hw_amd.h
@@ -16,7 +16,6 @@
 #define AMD_MW_COUNT			2
 #define AMD_DB_COUNT			16
 #define AMD_SPAD_COUNT			16
-#define AMD_MSIX_VECTOR_COUNT		24
 
 /* Peer register window: peer register = primary offset + 0x400. */
 #define AMD_PEER_OFFSET			0x400
@@ -37,10 +36,6 @@
 #define AMD_DBREQ_OFFSET		0x454	/* Doorbell request. */
 #define AMD_DBMASK_OFFSET		0x45C	/* Doorbell mask. */
 #define AMD_DBSTAT_OFFSET		0x460	/* Doorbell status. */
-#define AMD_INTMASK_OFFSET		0x470	/* Interrupt mask. */
-#define AMD_INTSTAT_OFFSET		0x474	/* Interrupt status. */
-#define AMD_PMESTAT_OFFSET		0x480	/* PME status. */
-#define AMD_SMUACK_OFFSET		0x4A0	/* SMU control (PSMU_ACK). */
 
 /* Link Status Register (0x408) bits, spec Table 5. */
 #define AMD_SIDE_MASK			(1 << 0) /* 0: primary, 1: secondary. */
@@ -50,22 +45,6 @@
 #define AMD_SMM_REG_CTL			(1 << 20)
 #define AMD_PMM_REG_CTL			(1 << 21)
 
-/* Interrupt Status/Mask event bits, spec Table 7. */
-#define AMD_PEER_FLUSH_EVENT		(1 << 0)
-#define AMD_PEER_RESET_EVENT		(1 << 1)
-#define AMD_PEER_D3_EVENT		(1 << 2)
-#define AMD_PEER_PMETO_EVENT		(1 << 3)
-#define AMD_PEER_D0_EVENT		(1 << 4)
-#define AMD_LINK_UP_EVENT		(1 << 5)
-#define AMD_LINK_DOWN_EVENT		(1 << 6)
-#define AMD_EVENT_INTMASK		(AMD_PEER_FLUSH_EVENT | \
-					 AMD_PEER_RESET_EVENT | \
-					 AMD_PEER_D3_EVENT | \
-					 AMD_PEER_PMETO_EVENT | \
-					 AMD_PEER_D0_EVENT | \
-					 AMD_LINK_UP_EVENT | \
-					 AMD_LINK_DOWN_EVENT)
-
 /* PCIe link status decoding (link speed/width). */
 #define AMD_LNK_STA_SPEED_MASK		0x000f
 #define AMD_LNK_STA_WIDTH_MASK		0x03f0
-- 
2.34.1


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

* [PATCH 08/13] raw/ntb: fix Rx of incomplete packets
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (6 preceding siblings ...)
  2026-11-04 11:19 ` [PATCH 07/13] raw/ntb: remove AMD hardware event handling Raghavendra Ningoji
@ 2026-11-04 11:19 ` Raghavendra Ningoji
  2026-11-04 11:19 ` [PATCH 09/13] raw/ntb: fix double free of Rx mbufs on stop Raghavendra Ningoji
                   ` (21 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-04 11:19 UTC (permalink / raw)
  To: dev
  Cc: jingjing.wu, thomas, selwin.sebastian, bhagyada.modali,
	bruce.richardson, david.marchand, stephen, stable

When a packet had no EOP descriptor among the ones walked, or when a
refill mbuf could not be allocated in the middle of a packet, the Rx
burst stopped with the packet partially consumed: the ring indexes had
moved, but the mbuf chain was neither returned nor freed, and the
refilled descriptors were not published to the peer if no packet had
been completed before.

The EOP guard also bounded the walk on the ring size rather than on
the descriptors actually published by the peer.

Only take a packet once all of its descriptors have been published,
and allocate its refill mbufs before consuming it, so that the ring
indexes are only advanced for complete packets.

Fixes: 11b5c7daf019 ("raw/ntb: add enqueue and dequeue functions")
Fixes: 5ce50c234ad1 ("raw/ntb: generalize framework for multiple vendors")
Cc: stable@dpdk.org

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb.c | 39 +++++++++++++++++++++------------------
 1 file changed, 21 insertions(+), 18 deletions(-)

diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index d514ed669f..87a35c796c 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -650,13 +650,14 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
 	struct ntb_rx_queue *rxq = hw->rx_queues[(size_t)context];
 	struct ntb_rx_entry *sw_ring = rxq->sw_ring;
 	struct ntb_desc rx_desc[NTB_MAX_DESC_SIZE];
-	struct rte_mbuf *first, *rxm_t;
+	struct rte_mbuf *new_mbufs[NTB_MAX_DESC_SIZE];
+	struct rte_mbuf *first = NULL, *rxm_t;
 	struct rte_mbuf *prev = NULL;
 	volatile struct ntb_used *rx_item;
 	uint16_t nb_mbufs = 0;
 	uint16_t nb_rx = 0;
 	uint64_t bytes = 0;
-	uint16_t off, last_avail, used_cnt, used_nb;
+	uint16_t off, last_avail, used_cnt, used_nb, nb_segs;
 	int i;
 
 	if (unlikely(dev->started == 0 || hw->peer_dev_up == 0)) {
@@ -673,13 +674,24 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
 	used_nb = (used_cnt - rxq->last_used) & (rxq->nb_rx_desc - 1);
 	count = RTE_MIN(count, used_nb);
 	for (nb_rx = 0; nb_rx < count; nb_rx++) {
-		i = 0;
-		while (true) {
-			if (unlikely(nb_mbufs >= rxq->nb_rx_desc)) {
-				NTB_LOG(ERR, "Malformed rx stream (no EOP); "
-					"aborting to avoid desc overflow.");
+		/* Only take a packet once the peer has published all of it. */
+		for (nb_segs = 1; ; nb_segs++) {
+			if (nb_segs > used_nb)
 				goto end_of_rx;
-			}
+			rx_item = rxq->rx_used_ring + ((rxq->last_used + nb_segs - 1) &
+						       (rxq->nb_rx_desc - 1));
+			if (rx_item->flags & NTB_FLAG_EOP)
+				break;
+		}
+
+		/* Get the refill mbufs first so a packet is never partially consumed. */
+		if (unlikely(rte_mbuf_raw_alloc_bulk(rxq->mpool, new_mbufs, nb_segs))) {
+			NTB_LOG(ERR, "recv alloc mbuf failed.");
+			goto end_of_rx;
+		}
+		used_nb -= nb_segs;
+
+		for (i = 0; i < nb_segs; i++) {
 			rx_item = rxq->rx_used_ring + rxq->last_used;
 			rxm_t = sw_ring[rxq->last_used].mbuf;
 			rxm_t->data_len = rx_item->len;
@@ -701,15 +713,9 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
 			rxq->last_used = (rxq->last_used + 1) &
 					 (rxq->nb_rx_desc - 1);
 
-			/* alloc new mbuf */
-			rxm_t = rte_mbuf_raw_alloc(rxq->mpool);
-			if (unlikely(rxm_t == NULL)) {
-				NTB_LOG(ERR, "recv alloc mbuf failed.");
-				goto end_of_rx;
-			}
+			rxm_t = new_mbufs[i];
 			rxm_t->port = rxq->port_id;
 			sw_ring[rxq->last_avail].mbuf = rxm_t;
-			i++;
 
 			/* fill new desc */
 			rx_desc[nb_mbufs].addr =
@@ -718,9 +724,6 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
 						  RTE_PKTMBUF_HEADROOM;
 			rxq->last_avail = (rxq->last_avail + 1) &
 					  (rxq->nb_rx_desc - 1);
-
-			if (rx_item->flags & NTB_FLAG_EOP)
-				break;
 		}
 		/* update stats */
 		bytes += first->pkt_len;
-- 
2.34.1


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

* [PATCH 09/13] raw/ntb: fix double free of Rx mbufs on stop
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (7 preceding siblings ...)
  2026-11-04 11:19 ` [PATCH 08/13] raw/ntb: fix Rx of incomplete packets Raghavendra Ningoji
@ 2026-11-04 11:19 ` Raghavendra Ningoji
  2026-11-04 11:19 ` [PATCH 10/13] examples/ntb: fix raw/ntb library linking Raghavendra Ningoji
                   ` (20 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-04 11:19 UTC (permalink / raw)
  To: dev
  Cc: jingjing.wu, thomas, selwin.sebastian, bhagyada.modali,
	bruce.richardson, david.marchand, stephen, stable

Once an Rx mbuf is handed to the application, its software ring entry
still references it until the slot is refilled. On device stop, all
referenced mbufs are freed, including the one now owned by the
application.

Clear the ring entry when the mbuf is taken.

Fixes: 11b5c7daf019 ("raw/ntb: add enqueue and dequeue functions")
Cc: stable@dpdk.org

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index 87a35c796c..d4c2de60bd 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -694,6 +694,7 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
 		for (i = 0; i < nb_segs; i++) {
 			rx_item = rxq->rx_used_ring + rxq->last_used;
 			rxm_t = sw_ring[rxq->last_used].mbuf;
+			sw_ring[rxq->last_used].mbuf = NULL;
 			rxm_t->data_len = rx_item->len;
 			rxm_t->data_off = RTE_PKTMBUF_HEADROOM;
 			rxm_t->port = rxq->port_id;
-- 
2.34.1


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

* [PATCH 10/13] examples/ntb: fix raw/ntb library linking
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (8 preceding siblings ...)
  2026-11-04 11:19 ` [PATCH 09/13] raw/ntb: fix double free of Rx mbufs on stop Raghavendra Ningoji
@ 2026-11-04 11:19 ` Raghavendra Ningoji
  2026-11-04 11:19 ` [PATCH 11/13] doc: add NTB device info change to ABI section Raghavendra Ningoji
                   ` (19 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-04 11:19 UTC (permalink / raw)
  To: dev
  Cc: jingjing.wu, thomas, selwin.sebastian, bhagyada.modali,
	bruce.richardson, david.marchand, stephen

The raw/ntb driver library was added to the linker flags of both the
shared and static targets. For static linking, it is already part of
the libdpdk pkg-config output, so only add it to the shared target,
as done in other examples.

Fixes: 5ce50c234ad1 ("raw/ntb: generalize framework for multiple vendors")

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 examples/ntb/Makefile | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/examples/ntb/Makefile b/examples/ntb/Makefile
index 6c0307c697..a074251646 100644
--- a/examples/ntb/Makefile
+++ b/examples/ntb/Makefile
@@ -23,11 +23,12 @@ static: build/$(APP)-static
 	ln -sf $(APP)-static build/$(APP)
 
 CFLAGS += -D_FILE_OFFSET_BITS=64
-LDFLAGS += -pthread -lrte_raw_ntb
+LDFLAGS += -pthread
 
 PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null)
 CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) -I build/
 LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk)
+LDFLAGS_SHARED += -lrte_raw_ntb
 LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk)
 
 build/commands.h: commands.list Makefile
-- 
2.34.1


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

* [PATCH 11/13] doc: add NTB device info change to ABI section
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (9 preceding siblings ...)
  2026-11-04 11:19 ` [PATCH 10/13] examples/ntb: fix raw/ntb library linking Raghavendra Ningoji
@ 2026-11-04 11:19 ` Raghavendra Ningoji
  2026-11-04 11:20 ` [PATCH 12/13] doc: add IOVA requirement for NTB Raghavendra Ningoji
                   ` (18 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-04 11:19 UTC (permalink / raw)
  To: dev
  Cc: jingjing.wu, thomas, selwin.sebastian, bhagyada.modali,
	bruce.richardson, david.marchand, stephen

Removing the mw_size_align field changed the layout of the installed
struct ntb_dev_info. Mention it in the ABI changes as well.

Fixes: 5ce50c234ad1 ("raw/ntb: generalize framework for multiple vendors")

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 doc/guides/rel_notes/release_26_11.rst | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index 6c76c60139..23980d5364 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -689,6 +689,8 @@ ABI Changes
 * cryptodev: The struct ``rte_crypto_rsa_op_param``
   was updated to include ``pss_salt``.
 
+* raw/ntb: The ``mw_size_align`` field was removed from ``struct ntb_dev_info``.
+
 
 Known Issues
 ------------
-- 
2.34.1


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

* [PATCH 12/13] doc: add IOVA requirement for NTB
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (10 preceding siblings ...)
  2026-11-04 11:19 ` [PATCH 11/13] doc: add NTB device info change to ABI section Raghavendra Ningoji
@ 2026-11-04 11:20 ` Raghavendra Ningoji
  2026-11-04 11:20 ` [PATCH 13/13] raw/ntb: remove unused AMD register definitions Raghavendra Ningoji
                   ` (17 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-04 11:20 UTC (permalink / raw)
  To: dev
  Cc: jingjing.wu, thomas, selwin.sebastian, bhagyada.modali,
	bruce.richardson, david.marchand, stephen

The memory window memzone is reserved with the alignment required by
the NTB hardware, but this alignment applies to the virtual address.
With IOVA as PA and a memzone larger than the hugepage size, the IOVA
may not be aligned and the device configuration fails.

Document that IOVA as VA mode or large enough hugepages are needed.

Fixes: 5ce50c234ad1 ("raw/ntb: generalize framework for multiple vendors")

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 doc/guides/rawdevs/ntb.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/doc/guides/rawdevs/ntb.rst b/doc/guides/rawdevs/ntb.rst
index c4ad2f05c4..8332c27de9 100644
--- a/doc/guides/rawdevs/ntb.rst
+++ b/doc/guides/rawdevs/ntb.rst
@@ -66,6 +66,10 @@ Different NTB hardware imposes different alignment constraints,
 so applications should not assume any particular value:
 reserve each memory window memzone with the alignment returned by ``rte_pmd_ntb_get_mem_align()``
 for that window and length. The ``ntb_fwd`` example shows this usage.
+The memzone alignment applies to its virtual address.
+With IOVA as PA, the IOVA of a memzone larger than the hugepage size
+is not guaranteed to be aligned, and the device configuration fails:
+use IOVA as VA mode, or hugepages at least as large as the memory window.
 
 Device Setup
 ------------
-- 
2.34.1


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

* [PATCH 13/13] raw/ntb: remove unused AMD register definitions
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (11 preceding siblings ...)
  2026-11-04 11:20 ` [PATCH 12/13] doc: add IOVA requirement for NTB Raghavendra Ningoji
@ 2026-11-04 11:20 ` Raghavendra Ningoji
  2026-11-04 12:24 ` [PATCH 00/13] raw/ntb: post-merge fixes Stephen Hemminger
                   ` (16 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-04 11:20 UTC (permalink / raw)
  To: dev
  Cc: jingjing.wu, thomas, selwin.sebastian, bhagyada.modali,
	bruce.richardson, david.marchand, stephen

The scratchpad mutex and doorbell flush mode registers are not used
by the driver.

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb_hw_amd.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/raw/ntb/ntb_hw_amd.h b/drivers/raw/ntb/ntb_hw_amd.h
index 8fffa24348..eec2041ad2 100644
--- a/drivers/raw/ntb/ntb_hw_amd.h
+++ b/drivers/raw/ntb/ntb_hw_amd.h
@@ -25,14 +25,12 @@
 
 /* Primary-side MMIO register offsets (BAR0), spec Table 1. */
 #define AMD_CNTL_OFFSET			0x200	/* Link Control. */
-#define AMD_SPADMUTEX_OFFSET		0x20C	/* Scratchpad mutex. */
 #define AMD_SPAD_OFFSET			0x210	/* Scratchpad registers. */
 #define AMD_SIDEINFO_OFFSET		0x408	/* Link Status (PSIDE_INFO). */
 #define AMD_BAR23_LIMIT_OFFSET		0x418	/* MW BAR23 size. */
 #define AMD_BAR45_LIMIT_OFFSET		0x420	/* MW BAR45 size. */
 #define AMD_BAR23_XLAT_OFFSET		0x438	/* MW BAR23 translation. */
 #define AMD_BAR45_XLAT_OFFSET		0x440	/* MW BAR45 translation. */
-#define AMD_DBFM_OFFSET			0x450	/* Doorbell flush mode. */
 #define AMD_DBREQ_OFFSET		0x454	/* Doorbell request. */
 #define AMD_DBMASK_OFFSET		0x45C	/* Doorbell mask. */
 #define AMD_DBSTAT_OFFSET		0x460	/* Doorbell status. */
-- 
2.34.1


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

* Re: [PATCH 00/13] raw/ntb: post-merge fixes
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (12 preceding siblings ...)
  2026-11-04 11:20 ` [PATCH 13/13] raw/ntb: remove unused AMD register definitions Raghavendra Ningoji
@ 2026-11-04 12:24 ` Stephen Hemminger
  2026-11-06  5:54   ` Raghavendra Ningoji
  2026-11-06  5:50 ` [PATCH v2 00/15] " Raghavendra Ningoji
                   ` (15 subsequent siblings)
  29 siblings, 1 reply; 52+ messages in thread
From: Stephen Hemminger @ 2026-11-04 12:24 UTC (permalink / raw)
  To: Raghavendra Ningoji
  Cc: dev, jingjing.wu, thomas, selwin.sebastian, bhagyada.modali,
	bruce.richardson, david.marchand

On Wed, 4 Nov 2026 16:49:48 +0530
Raghavendra Ningoji <raghavendra.ningoji@amd.com> wrote:

> This series addresses the post-merge review of the AMD NTB support
> by Stephen. Some of the issues also exist in the Intel code and in
> released versions; those patches are tagged for stable.
> 
> - Patches 1-4 fix the type confusion in rte_pmd_ntb_get_mem_align(),
>   the unbounded peer memory window count, the off-by-one in the
>   address remapping and the memory window leaks.
> 
> - Patch 5 fixes the doorbell interrupts with vfio-pci: only MSI-X
>   vector 0 (DB0) was serviced, so the DB1/DB2 exchange of dev_stop
>   never completed and the stop waited for its 1s timeout.
> 
> - Patch 7 removes the AMD hardware event handling, which could not run
>   as wired, and documents that hardware events are not handled.
> 
> - Patches 8-9 fix the Rx path: a partially consumed packet was leaked
>   and desynchronized the ring, and an mbuf owned by the application
>   could be freed again on device stop.
> 
> - The other patches are documentation and cleanup.
> 
> The peer memory window size check suggested for the AMD handshake is
> not added: all the AMD scratchpads are in use, and the window limit
> register programmed with the local memzone length already bounds what
> the peer can reach.
> 
> Tested with vfio-pci on two AMD EPYC Embedded hosts: handshake,
> file transfer, and stop/quit with DB1/DB2 exchange.
> 
> Raghavendra Ningoji (13):
>   raw/ntb: fix device check in memory alignment query
>   raw/ntb: fix peer memory window count check
>   raw/ntb: fix memory window bound in address remapping
>   raw/ntb: fix memory leaks
>   raw/ntb: fix doorbell interrupts with VFIO MSI-X
>   raw/ntb: fix AMD processor names
>   raw/ntb: remove AMD hardware event handling
>   raw/ntb: fix Rx of incomplete packets
>   raw/ntb: fix double free of Rx mbufs on stop
>   examples/ntb: fix raw/ntb library linking
>   doc: add NTB device info change to ABI section
>   doc: add IOVA requirement for NTB
>   raw/ntb: remove unused AMD register definitions
> 
>  doc/guides/rawdevs/ntb.rst             |  12 ++-
>  doc/guides/rel_notes/release_26_11.rst |   6 +-
>  drivers/raw/ntb/ntb.c                  | 136 ++++++++++++++++++++-----
>  drivers/raw/ntb/ntb.h                  |   7 +-
>  drivers/raw/ntb/ntb_hw_amd.c           |  54 ++--------
>  drivers/raw/ntb/ntb_hw_amd.h           |  25 +----
>  drivers/raw/ntb/ntb_hw_intel.c         |   9 +-
>  examples/ntb/Makefile                  |   3 +-
>  8 files changed, 149 insertions(+), 103 deletions(-)
> 

Lots of AI reported issues here:

Subject: Re: [PATCH 00/13] raw/ntb: post-merge fixes

Series applies to main (26.11-rc2) and builds at every commit with
-Dwerror=true (raw/ntb + examples/ntb).

Patch 04/13 raw/ntb: fix memory leaks

Warning: mw_size is freed in dev_close, but rte_rawdev_close() does not
detach the device; it stays attached and its ops remain reachable.

  +	rte_free(hw->mw_size);
  +	hw->mw_size = NULL;

After close, rte_pmd_ntb_get_mem_align() passes the new checks from
patch 1 (attached, dev_ops == &ntb_ops, mw_id < mw_cnt) and on Intel
calls intel_ntb_get_mem_align(), which does

	return hw->mw_size[mw_id];

i.e. a NULL dereference. A configure after close does the same in
intel_ntb_dev_handshake() (hw->mw_size[i]), and ntb_dev_info_get()
now hands the application mw_cnt = 2 with mw_size = NULL; ntb_fwd
indexes ntb_info.mw_size[0] unconditionally.

Both vendors have a fixed count of 2 windows (XEON_MW_COUNT,
AMD_MW_COUNT), so drop the allocation and embed the array in
struct ntb_hw. It then lives exactly as long as dev_private, the
info->mw_size pointer stays valid, and the leak goes away with no
free at all:

	#define NTB_MAX_MW	2
	...
	uint64_t mw_size[NTB_MAX_MW];

with RTE_BUILD_BUG_ON(XEON_MW_COUNT > NTB_MAX_MW) (and AMD) in the
vendor init, and the rte_zmalloc()/NULL check removed there.

Patch 05/13 raw/ntb: fix doorbell interrupts with VFIO MSI-X

Warning: db_intr_handles is an array of process-private pointers
(handles come from rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_PRIVATE))
used only by the control path. No reason to put it in hugepage memory.

  +	hw->db_intr_handles = rte_zmalloc("ntb_db_intr",
  +				nb_efd * sizeof(*hw->db_intr_handles), 0);

Use calloc(nb_efd, sizeof(*hw->db_intr_handles)) and free() in
ntb_db_intr_unregister().

Info (pre-existing, not introduced by this patch): peer_dev_up is a
plain uint8_t written by the interrupt thread (DB1/DB2 handlers,
"hw->peer_dev_up = 0;") and polled by ntb_dev_stop():

	while (hw->peer_dev_up && time_out) {

Now that DB2 is actually delivered, this loop is the normal stop path
rather than the timeout. It only works because rte_delay_us() is an
opaque call. Should be rte_atomic_store_explicit()/load with
release/acquire, as a separate patch.

Patch 08/13 raw/ntb: fix Rx of incomplete packets

Info (pre-existing, not introduced by this patch): the new on-stack

  +	struct rte_mbuf *new_mbufs[NTB_MAX_DESC_SIZE];

like the existing rx_desc[], is only bounded because nb_rx_desc is
assumed <= NTB_MAX_DESC_SIZE. ntb_rxq_setup() takes
"rxq->nb_rx_desc = rxq_conf->nb_desc;" without checking that, or that
it is a power of two (the ring indexes use & (nb_rx_desc - 1)); only
the ntb_fwd example range-checks it. The same function also leaks rxq
when rx_mp is NULL. Worth a separate fix:

	if (rxq_conf->rx_mp == NULL ||
	    rxq_conf->nb_desc < NTB_MIN_DESC_SIZE ||
	    rxq_conf->nb_desc > NTB_MAX_DESC_SIZE ||
	    !rte_is_power_of_2(rxq_conf->nb_desc))
		return -EINVAL;

placed before the rte_zmalloc_socket().

Review-Result: WARNING

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

* [PATCH v2 00/15] raw/ntb: post-merge fixes
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (13 preceding siblings ...)
  2026-11-04 12:24 ` [PATCH 00/13] raw/ntb: post-merge fixes Stephen Hemminger
@ 2026-11-06  5:50 ` Raghavendra Ningoji
  2026-11-06 12:50   ` Stephen Hemminger
  2026-11-11  7:06   ` [PATCH v3 00/16] " Raghavendra Ningoji
  2026-11-06  5:50 ` [PATCH v2 01/15] raw/ntb: fix device check in memory alignment query Raghavendra Ningoji
                   ` (14 subsequent siblings)
  29 siblings, 2 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-06  5:50 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson

This series addresses the post-merge review of the AMD NTB support
by Stephen. Some of the issues also exist in the Intel code and in
released versions; those patches are tagged for stable.

- Patches 1-4 fix the type confusion in rte_pmd_ntb_get_mem_align(),
  the unbounded peer memory window count, the off-by-one in the
  address remapping and the memory window leaks.

- Patch 5 fixes the doorbell interrupts with vfio-pci: only MSI-X
  vector 0 (DB0) was serviced, so the DB1/DB2 exchange of dev_stop
  never completed and the stop waited for its 1s timeout.

- Patch 7 removes the AMD hardware event handling, which could not run
  as wired, and documents that hardware events are not handled.

- Patches 8-9 fix the Rx path: a partially consumed packet was leaked
  and desynchronized the ring, and an mbuf owned by the application
  could be freed again on device stop.

- Patches 14-15 fix the peer device status accesses between the
  interrupt thread and the stop/data paths, and the missing checks at
  queue setup.

- The other patches are documentation and cleanup.

The peer memory window size check suggested for the AMD handshake is
not added: all the AMD scratchpads are in use, and the window limit
register programmed with the local memzone length already bounds what
the peer can reach.

Tested with vfio-pci on two AMD EPYC Embedded hosts: handshake,
file transfer, and stop/quit with DB1/DB2 exchange.

---
Changes since v1:
- Patch 4: embed the memory window size array in struct ntb_hw instead
  of freeing it on close, as the device stays attached after close and
  mw_size could then be dereferenced as NULL.
- Patch 5: allocate the doorbell interrupt handle array with calloc(),
  as it only holds process-private pointers.
- Added patch 14 for the peer device status atomic accesses.
- Added patch 15 for the queue setup checks, also covering the Tx side
  (unchecked nb_desc, and queue leak on invalid tx_free_thresh).

Raghavendra Ningoji (15):
  raw/ntb: fix device check in memory alignment query
  raw/ntb: fix peer memory window count check
  raw/ntb: fix memory window bound in address remapping
  raw/ntb: fix memory leaks
  raw/ntb: fix doorbell interrupts with VFIO MSI-X
  raw/ntb: fix AMD processor names
  raw/ntb: remove AMD hardware event handling
  raw/ntb: fix Rx of incomplete packets
  raw/ntb: fix double free of Rx mbufs on stop
  examples/ntb: fix raw/ntb library linking
  doc: add NTB device info change to ABI section
  doc: add IOVA requirement for NTB
  raw/ntb: remove unused AMD register definitions
  raw/ntb: fix peer device status access
  raw/ntb: fix queue setup checks

 doc/guides/rawdevs/ntb.rst             |  12 +-
 doc/guides/rel_notes/release_26_11.rst |   6 +-
 drivers/raw/ntb/ntb.c                  | 212 +++++++++++++++++++------
 drivers/raw/ntb/ntb.h                  |  17 +-
 drivers/raw/ntb/ntb_hw_amd.c           |  60 ++-----
 drivers/raw/ntb/ntb_hw_amd.h           |  25 +--
 drivers/raw/ntb/ntb_hw_intel.c         |  17 +-
 examples/ntb/Makefile                  |   3 +-
 8 files changed, 210 insertions(+), 142 deletions(-)

-- 
2.34.1


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

* [PATCH v2 01/15] raw/ntb: fix device check in memory alignment query
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (14 preceding siblings ...)
  2026-11-06  5:50 ` [PATCH v2 00/15] " Raghavendra Ningoji
@ 2026-11-06  5:50 ` Raghavendra Ningoji
  2026-11-06  5:50 ` [PATCH v2 02/15] raw/ntb: fix peer memory window count check Raghavendra Ningoji
                   ` (13 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-06  5:50 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson

rte_pmd_ntb_get_mem_align() only checked the device index range and
the presence of private data before casting it to struct ntb_hw.
Passing the id of a detached slot or of a rawdev from another driver
would then call through a garbage ops pointer.

Check that the device is attached and is driven by this PMD.

Also return 0 for an out of range memory window index, as documented,
instead of a cache line size.

Fixes: 5ce50c234ad1 ("raw/ntb: generalize framework for multiple vendors")

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index fe10782ecf..e42af0b9c5 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -33,6 +33,8 @@ static const struct rte_pci_id pci_id_ntb_map[] = {
 	{ .vendor_id = 0, /* sentinel */ },
 };
 
+static const struct rte_rawdev_ops ntb_ops;
+
 /* Align with enum ntb_xstats_idx */
 static struct rte_rawdev_xstats_name ntb_xstats_names[] = {
 	{"Tx-packets"},
@@ -722,15 +724,15 @@ rte_pmd_ntb_get_mem_align(uint16_t dev_id, uint32_t mw_id, uint64_t mw_len)
 	struct rte_rawdev *dev;
 	struct ntb_hw *hw;
 
-	if (dev_id >= RTE_RAWDEV_MAX_DEVS)
+	if (dev_id >= RTE_RAWDEV_MAX_DEVS || !rte_rawdev_pmd_is_valid_dev(dev_id))
 		return 0;
 	dev = rte_rawdev_pmd_get_dev(dev_id);
-	if (dev->dev_private == NULL)
+	if (dev->dev_ops != &ntb_ops)
 		return 0;
 
 	hw = dev->dev_private;
 	if (mw_id >= hw->mw_cnt)
-		return RTE_CACHE_LINE_SIZE;
+		return 0;
 
 	return (*hw->ntb_ops->mem_align)(dev, mw_id, mw_len);
 }
-- 
2.34.1


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

* [PATCH v2 02/15] raw/ntb: fix peer memory window count check
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (15 preceding siblings ...)
  2026-11-06  5:50 ` [PATCH v2 01/15] raw/ntb: fix device check in memory alignment query Raghavendra Ningoji
@ 2026-11-06  5:50 ` Raghavendra Ningoji
  2026-11-06  5:50 ` [PATCH v2 03/15] raw/ntb: fix memory window bound in address remapping Raghavendra Ningoji
                   ` (12 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-06  5:50 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson, stable

The number of memory windows used by the peer is read from a
scratchpad register written by the peer, and is then used as the loop
bound to fill peer_mw_base[], which is allocated with mw_cnt entries.
A peer advertising more windows (bug, version mismatch, or a stale
scratchpad) makes the driver write past the end of this array.
On Intel, the 32-bit register value was also silently truncated into
the 8-bit peer_used_mws field.

Reject a peer configuration using more windows than the local device
has.

Fixes: c39d1e082a4b ("raw/ntb: setup queues")
Fixes: d6dc5a7f8b06 ("raw/ntb: support AMD NTB")
Cc: stable@dpdk.org

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb_hw_amd.c   | 10 ++++++++--
 drivers/raw/ntb/ntb_hw_intel.c |  7 ++++++-
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/raw/ntb/ntb_hw_amd.c b/drivers/raw/ntb/ntb_hw_amd.c
index ab78675218..dba5b03671 100644
--- a/drivers/raw/ntb/ntb_hw_amd.c
+++ b/drivers/raw/ntb/ntb_hw_amd.c
@@ -502,7 +502,7 @@ static int
 amd_ntb_read_peer_config(const struct rte_rawdev *dev)
 {
 	struct ntb_hw *ntb = dev->dev_private;
-	uint32_t info, peer_qps, peer_qsz, lo, hi;
+	uint32_t info, peer_qps, peer_qsz, peer_used_mws, lo, hi;
 	int i;
 
 	info = amd_ntb_spad_read(dev, AMD_SPAD_CNT_INFO, 0);
@@ -520,7 +520,13 @@ amd_ntb_read_peer_config(const struct rte_rawdev *dev)
 		return -EINVAL;
 	}
 
-	ntb->peer_used_mws = (info >> 16) & 0xff;
+	peer_used_mws = (info >> 16) & 0xff;
+	if (peer_used_mws > ntb->mw_cnt) {
+		NTB_LOG(ERR, "Peer used mws %u > mw cnt %u.", peer_used_mws, ntb->mw_cnt);
+		return -EINVAL;
+	}
+	ntb->peer_used_mws = peer_used_mws;
+
 	for (i = 0; i < ntb->peer_used_mws; i++) {
 		lo = amd_ntb_spad_read(dev, AMD_SPAD_MW0_BA_L + 2 * i, 0);
 		hi = amd_ntb_spad_read(dev, AMD_SPAD_MW0_BA_H + 2 * i, 0);
diff --git a/drivers/raw/ntb/ntb_hw_intel.c b/drivers/raw/ntb/ntb_hw_intel.c
index 1b784055ca..78fce9ffac 100644
--- a/drivers/raw/ntb/ntb_hw_intel.c
+++ b/drivers/raw/ntb/ntb_hw_intel.c
@@ -724,7 +724,12 @@ intel_ntb_read_peer_config(const struct rte_rawdev *dev)
 		return -EINVAL;
 	}
 
-	hw->peer_used_mws = intel_ntb_spad_read(dev, SPAD_USED_MWS, 0);
+	peer_val = intel_ntb_spad_read(dev, SPAD_USED_MWS, 0);
+	if (peer_val > hw->mw_cnt) {
+		NTB_LOG(ERR, "Peer used mws %u > mw cnt %u.", peer_val, hw->mw_cnt);
+		return -EINVAL;
+	}
+	hw->peer_used_mws = peer_val;
 
 	for (i = 0; i < hw->peer_used_mws; i++) {
 		peer_base_h = intel_ntb_spad_read(dev, SPAD_MW0_BA_H + 2 * i, 0);
-- 
2.34.1


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

* [PATCH v2 03/15] raw/ntb: fix memory window bound in address remapping
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (16 preceding siblings ...)
  2026-11-06  5:50 ` [PATCH v2 02/15] raw/ntb: fix peer memory window count check Raghavendra Ningoji
@ 2026-11-06  5:50 ` Raghavendra Ningoji
  2026-11-06  5:50 ` [PATCH v2 04/15] raw/ntb: fix memory leaks Raghavendra Ningoji
                   ` (11 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-06  5:50 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson, stable

When translating a peer address into the local mapping of a memory
window, the end of the window was included in the accepted range,
so an address one byte past the window was mapped.

Exclude the end of the window.

Fixes: 11b5c7daf019 ("raw/ntb: add enqueue and dequeue functions")
Fixes: d6dc5a7f8b06 ("raw/ntb: support AMD NTB")
Cc: stable@dpdk.org

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb_hw_amd.c   | 2 +-
 drivers/raw/ntb/ntb_hw_intel.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/raw/ntb/ntb_hw_amd.c b/drivers/raw/ntb/ntb_hw_amd.c
index dba5b03671..64075501c2 100644
--- a/drivers/raw/ntb/ntb_hw_amd.c
+++ b/drivers/raw/ntb/ntb_hw_amd.c
@@ -166,7 +166,7 @@ amd_ntb_ioremap(const struct rte_rawdev *dev, uint64_t addr)
 
 	for (i = 0; i < ntb->peer_used_mws; i++) {
 		if (addr >= ntb->peer_mw_base[i] &&
-				addr <= ntb->peer_mw_base[i] + ntb->mw_size[i]) {
+				addr < ntb->peer_mw_base[i] + ntb->mw_size[i]) {
 			base = amd_ntb_get_peer_mw_addr(dev, i);
 			mapped = (void *)(size_t)(addr - ntb->peer_mw_base[i] + (size_t)base);
 			break;
diff --git a/drivers/raw/ntb/ntb_hw_intel.c b/drivers/raw/ntb/ntb_hw_intel.c
index 78fce9ffac..47d5d39339 100644
--- a/drivers/raw/ntb/ntb_hw_intel.c
+++ b/drivers/raw/ntb/ntb_hw_intel.c
@@ -312,7 +312,7 @@ intel_ntb_ioremap(const struct rte_rawdev *dev, uint64_t addr)
 
 	for (i = 0; i < hw->peer_used_mws; i++) {
 		if (addr >= hw->peer_mw_base[i] &&
-		    addr <= hw->peer_mw_base[i] + hw->mw_size[i]) {
+		    addr < hw->peer_mw_base[i] + hw->mw_size[i]) {
 			base = intel_ntb_get_peer_mw_addr(dev, i);
 			mapped = (void *)(size_t)(addr - hw->peer_mw_base[i] +
 				 (size_t)base);
-- 
2.34.1


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

* [PATCH v2 04/15] raw/ntb: fix memory leaks
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (17 preceding siblings ...)
  2026-11-06  5:50 ` [PATCH v2 03/15] raw/ntb: fix memory window bound in address remapping Raghavendra Ningoji
@ 2026-11-06  5:50 ` Raghavendra Ningoji
  2026-11-06  5:50 ` [PATCH v2 05/15] raw/ntb: fix doorbell interrupts with VFIO MSI-X Raghavendra Ningoji
                   ` (10 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-06  5:50 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson, stable

The memory window size array allocated by the vendor init at probe
time was never freed.
The peer memory window base array allocated at each device start was
only freed if the start failed, so it leaked on every stop/start cycle.

As the number of memory windows is fixed for all supported devices,
embed the memory window size array in the device private data instead
of allocating it: it lives as long as the device and remains valid for
the info get after close.
Free the peer memory window base array when stopping the device.

Fixes: c39d1e082a4b ("raw/ntb: setup queues")
Fixes: d6dc5a7f8b06 ("raw/ntb: support AMD NTB")
Cc: stable@dpdk.org

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb.c          | 6 ++++++
 drivers/raw/ntb/ntb.h          | 5 ++++-
 drivers/raw/ntb/ntb_hw_amd.c   | 6 +-----
 drivers/raw/ntb/ntb_hw_intel.c | 8 +-------
 4 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index e42af0b9c5..5985604cce 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -820,6 +820,8 @@ ntb_dev_start(struct rte_rawdev *dev)
 
 err_up:
 	rte_free(hw->peer_mw_base);
+	hw->peer_mw_base = NULL;
+	hw->peer_used_mws = 0;
 err_q_init:
 	for (i = 0; i < hw->queue_pairs; i++) {
 		ntb_rxq_release_mbufs(hw->rx_queues[i]);
@@ -872,6 +874,10 @@ ntb_dev_stop(struct rte_rawdev *dev)
 		ntb_txq_release_mbufs(hw->tx_queues[i]);
 	}
 
+	rte_free(hw->peer_mw_base);
+	hw->peer_mw_base = NULL;
+	hw->peer_used_mws = 0;
+
 	dev->started = 0;
 }
 
diff --git a/drivers/raw/ntb/ntb.h b/drivers/raw/ntb/ntb.h
index 0181bec5c9..31bf0f3260 100644
--- a/drivers/raw/ntb/ntb.h
+++ b/drivers/raw/ntb/ntb.h
@@ -17,6 +17,9 @@ extern int ntb_logtype;
 #define NTB_SPAD_USER               "spad_user_"
 #define NTB_SPAD_USER_LEN           (sizeof(NTB_SPAD_USER) - 1)
 #define NTB_SPAD_USER_MAX_NUM       4
+
+/* Maximum number of memory windows of supported devices. */
+#define NTB_MAX_MW                  2
 #define NTB_ATTR_NAME_LEN           30
 
 #define NTB_DFLT_TX_FREE_THRESH     256
@@ -220,7 +223,7 @@ struct ntb_hw {
 	char *hw_addr;
 
 	uint8_t peer_dev_up;
-	uint64_t *mw_size;
+	uint64_t mw_size[NTB_MAX_MW];
 	/* remote mem base addr */
 	uint64_t *peer_mw_base;
 
diff --git a/drivers/raw/ntb/ntb_hw_amd.c b/drivers/raw/ntb/ntb_hw_amd.c
index 64075501c2..9b274bc6b9 100644
--- a/drivers/raw/ntb/ntb_hw_amd.c
+++ b/drivers/raw/ntb/ntb_hw_amd.c
@@ -53,6 +53,7 @@ amd_ntb_dev_init(const struct rte_rawdev *dev)
 	NTB_LOG(INFO, "Device topology: %s (sideinfo 0x%" PRIx32 ")",
 		ntb->topo == NTB_TOPO_SEC ? "secondary" : "primary", sideinfo);
 
+	RTE_BUILD_BUG_ON(AMD_MW_COUNT > NTB_MAX_MW);
 	ntb->mw_cnt = AMD_MW_COUNT;
 	ntb->db_cnt = AMD_DB_COUNT;
 	/* The 16-register scratchpad bank is split into two halves, so only
@@ -60,11 +61,6 @@ amd_ntb_dev_init(const struct rte_rawdev *dev)
 	 */
 	ntb->spad_cnt = AMD_SPAD_PER_SIDE;
 
-	ntb->mw_size = rte_zmalloc("ntb_mw_size", ntb->mw_cnt * sizeof(uint64_t), 0);
-	if (ntb->mw_size == NULL) {
-		NTB_LOG(ERR, "Cannot allocate memory for mw size.");
-		return -ENOMEM;
-	}
 	for (i = 0; i < ntb->mw_cnt; i++) {
 		bar = amd_ntb_bar[i];
 		ntb->mw_size[i] = ntb->pci_dev->mem_resource[bar].len;
diff --git a/drivers/raw/ntb/ntb_hw_intel.c b/drivers/raw/ntb/ntb_hw_intel.c
index 47d5d39339..ad8e330199 100644
--- a/drivers/raw/ntb/ntb_hw_intel.c
+++ b/drivers/raw/ntb/ntb_hw_intel.c
@@ -194,17 +194,11 @@ intel_ntb_dev_init(const struct rte_rawdev *dev)
 	if (ret)
 		return ret;
 
+	RTE_BUILD_BUG_ON(XEON_MW_COUNT > NTB_MAX_MW);
 	hw->mw_cnt = XEON_MW_COUNT;
 	hw->db_cnt = XEON_DB_COUNT;
 	hw->spad_cnt = XEON_SPAD_COUNT;
 
-	hw->mw_size = rte_zmalloc("ntb_mw_size",
-				  hw->mw_cnt * sizeof(uint64_t), 0);
-	if (hw->mw_size == NULL) {
-		NTB_LOG(ERR, "Cannot allocate memory for mw size.");
-		return -ENOMEM;
-	}
-
 	for (i = 0; i < hw->mw_cnt; i++) {
 		bar = intel_ntb_bar[i];
 		hw->mw_size[i] = hw->pci_dev->mem_resource[bar].len;
-- 
2.34.1


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

* [PATCH v2 05/15] raw/ntb: fix doorbell interrupts with VFIO MSI-X
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (18 preceding siblings ...)
  2026-11-06  5:50 ` [PATCH v2 04/15] raw/ntb: fix memory leaks Raghavendra Ningoji
@ 2026-11-06  5:50 ` Raghavendra Ningoji
  2026-11-06  5:50 ` [PATCH v2 06/15] raw/ntb: fix AMD processor names Raghavendra Ningoji
                   ` (9 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-06  5:50 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson, stable

With VFIO MSI-X, each doorbell raises its own vector. Vector 0 is
signalled on the PCI device interrupt handle while the others are
signalled on the eventfds created by rte_intr_efd_enable(), but the
interrupt handler was only registered on the device interrupt handle.

As a result, doorbells other than DB0 were only noticed when DB0 fired
at the same time. In particular, the DB1 rung by the peer in its
dev_stop was never handled, the peer never got the DB2 answer and had
to wait for the 1s timeout.

Register the interrupt handler on each doorbell eventfd as well.

Fixes: 62012a76811e ("raw/ntb: add handshake process")
Cc: stable@dpdk.org

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb.c | 77 ++++++++++++++++++++++++++++++++++++++++++-
 drivers/raw/ntb/ntb.h |  4 +++
 2 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index 5985604cce..bde17c3c86 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -3,6 +3,7 @@
  */
 #include <stdint.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <errno.h>
 
@@ -11,6 +12,7 @@
 #include <rte_lcore.h>
 #include <rte_cycles.h>
 #include <rte_eal.h>
+#include <rte_errno.h>
 #include <rte_log.h>
 #include <rte_pci.h>
 #include <rte_mbuf.h>
@@ -124,6 +126,73 @@ ntb_dev_intr_handler(void *param)
 		(*hw->ntb_ops->handle_hw_event)(dev);
 }
 
+static void
+ntb_db_intr_unregister(struct rte_rawdev *dev)
+{
+	struct ntb_hw *hw = dev->dev_private;
+	struct rte_intr_handle *handle;
+	uint16_t i;
+
+	for (i = 0; i < hw->nb_db_intr_handles; i++) {
+		handle = hw->db_intr_handles[i];
+		rte_intr_callback_unregister_sync(handle,
+						  ntb_dev_intr_handler, dev);
+		/* The eventfd is owned by the PCI device interrupt handle. */
+		rte_intr_fd_set(handle, -1);
+		rte_intr_instance_free(handle);
+	}
+	free(hw->db_intr_handles);
+	hw->db_intr_handles = NULL;
+	hw->nb_db_intr_handles = 0;
+}
+
+/*
+ * With MSI-X, only vector 0 is serviced through the PCI device interrupt
+ * handle. Each other doorbell raises its own vector, signalled on the
+ * eventfds created by rte_intr_efd_enable(): register the handler on them.
+ */
+static int
+ntb_db_intr_register(struct rte_rawdev *dev,
+		     struct rte_intr_handle *intr_handle)
+{
+	struct ntb_hw *hw = dev->dev_private;
+	int nb_efd = rte_intr_nb_efd_get(intr_handle);
+	struct rte_intr_handle *handle;
+	int i, ret;
+
+	hw->db_intr_handles = calloc(nb_efd, sizeof(*hw->db_intr_handles));
+	if (hw->db_intr_handles == NULL)
+		return -ENOMEM;
+
+	for (i = 0; i < nb_efd; i++) {
+		handle = rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_PRIVATE);
+		if (handle == NULL) {
+			ret = -ENOMEM;
+			goto err;
+		}
+		hw->db_intr_handles[hw->nb_db_intr_handles++] = handle;
+
+		if (rte_intr_type_set(handle, RTE_INTR_HANDLE_VFIO_MSIX) ||
+		    rte_intr_fd_set(handle,
+				    rte_intr_efds_index_get(intr_handle, i))) {
+			ret = -rte_errno;
+			goto err;
+		}
+
+		ret = rte_intr_callback_register(handle,
+						 ntb_dev_intr_handler, dev);
+		if (ret)
+			goto err;
+	}
+
+	return 0;
+
+err:
+	NTB_LOG(ERR, "Failed to register doorbell interrupt %d.", i + 1);
+	ntb_db_intr_unregister(dev);
+	return ret;
+}
+
 static int
 ntb_queue_conf_get(struct rte_rawdev *dev,
 		   uint16_t queue_id,
@@ -902,6 +971,8 @@ ntb_dev_close(struct rte_rawdev *dev)
 	    !rte_intr_max_intr_get(intr_handle))
 		return 0;
 
+	ntb_db_intr_unregister(dev);
+
 	/* Clean datapath event and vec mapping */
 	rte_intr_efd_disable(intr_handle);
 	rte_intr_vec_list_free(intr_handle);
@@ -1305,7 +1376,11 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
 	 * by default for intel gen3. They are mapped to msix vec 1-32,
 	 * and hardware intr is mapped to 0. Map all to 0 for uio.
 	 */
-	if (!rte_intr_cap_multiple(intr_handle)) {
+	if (rte_intr_cap_multiple(intr_handle)) {
+		ret = ntb_db_intr_register(dev, intr_handle);
+		if (ret)
+			return ret;
+	} else {
 		for (i = 0; i < hw->db_cnt; i++) {
 			ret = (*hw->ntb_ops->vector_bind)(dev, i, 0);
 			if (ret)
diff --git a/drivers/raw/ntb/ntb.h b/drivers/raw/ntb/ntb.h
index 31bf0f3260..f867f0323d 100644
--- a/drivers/raw/ntb/ntb.h
+++ b/drivers/raw/ntb/ntb.h
@@ -222,6 +222,10 @@ struct ntb_hw {
 	struct rte_pci_device *pci_dev;
 	char *hw_addr;
 
+	/* Interrupt handles for the MSI-X doorbell vectors besides vector 0. */
+	struct rte_intr_handle **db_intr_handles;
+	uint16_t nb_db_intr_handles;
+
 	uint8_t peer_dev_up;
 	uint64_t mw_size[NTB_MAX_MW];
 	/* remote mem base addr */
-- 
2.34.1


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

* [PATCH v2 06/15] raw/ntb: fix AMD processor names
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (19 preceding siblings ...)
  2026-11-06  5:50 ` [PATCH v2 05/15] raw/ntb: fix doorbell interrupts with VFIO MSI-X Raghavendra Ningoji
@ 2026-11-06  5:50 ` Raghavendra Ningoji
  2026-11-06  5:50 ` [PATCH v2 07/15] raw/ntb: remove AMD hardware event handling Raghavendra Ningoji
                   ` (8 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-06  5:50 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson

Refer to the AMD processors integrating the NTB endpoints by their
EPYC Embedded 9004/9005/8004 series numbers rather than code names.

Fixes: d6dc5a7f8b06 ("raw/ntb: support AMD NTB")

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 doc/guides/rawdevs/ntb.rst             | 4 ++--
 doc/guides/rel_notes/release_26_11.rst | 4 ++--
 drivers/raw/ntb/ntb_hw_amd.h           | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/doc/guides/rawdevs/ntb.rst b/doc/guides/rawdevs/ntb.rst
index 99474745d6..37328cd9e6 100644
--- a/doc/guides/rawdevs/ntb.rst
+++ b/doc/guides/rawdevs/ntb.rst
@@ -41,7 +41,7 @@ AMD EPYC Embedded NTB
 ---------------------
 
 The driver also supports the NTB endpoints integrated in AMD EPYC Embedded
-"Turin", "Genoa" and "Siena" processors.
+9004/9005/8004 processors.
 These use a primary/secondary topology rather than the Intel back-to-back topology:
 one endpoint is enumerated as the primary (device ID ``0x14c0``) and
 the other as the secondary (device ID ``0x14c3``).
@@ -179,7 +179,7 @@ Limitation
 
 This PMD is supported on:
 
-- AMD EPYC Embedded "Turin", "Genoa" and "Siena" processors.
+- AMD EPYC Embedded 9004/9005/8004 processors.
 - 4th Generation Intel® Xeon® Scalable Processors.
 - 3rd Generation Intel® Xeon® Scalable Processors.
 - 2nd Generation Intel® Xeon® Scalable Processors.
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index 8ca8379cc6..6c76c60139 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -306,8 +306,8 @@ New Features
 
 * **Added AMD NTB support to the NTB rawdev driver.**
 
-  Added support for the NTB endpoints integrated in AMD EPYC Embedded "Turin", "Genoa"
-  and "Siena" processors to the ``raw/ntb`` driver.
+  Added support for the NTB endpoints integrated in AMD EPYC Embedded
+  9004/9005/8004 processors to the ``raw/ntb`` driver.
   The NTB rawdev framework was generalized to support multiple vendors,
   with AMD-specific hardware access, a primary/secondary topology
   and a packed scratchpad handshake.
diff --git a/drivers/raw/ntb/ntb_hw_amd.h b/drivers/raw/ntb/ntb_hw_amd.h
index 48f0db1ad4..b03aed7d08 100644
--- a/drivers/raw/ntb/ntb_hw_amd.h
+++ b/drivers/raw/ntb/ntb_hw_amd.h
@@ -7,7 +7,7 @@
 
 #include <stdint.h>
 
-/* NTB vendor and device IDs (EPYC Embedded Turin/Genoa/Siena). */
+/* NTB vendor and device IDs (EPYC Embedded 9004/9005/8004). */
 #define NTB_AMD_VENDOR_ID		0x1022
 #define NTB_AMD_DEV_ID_PRI		0x14c0	/* Primary NTB endpoint. */
 #define NTB_AMD_DEV_ID_SEC		0x14c3	/* Secondary NTB endpoint. */
-- 
2.34.1


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

* [PATCH v2 07/15] raw/ntb: remove AMD hardware event handling
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (20 preceding siblings ...)
  2026-11-06  5:50 ` [PATCH v2 06/15] raw/ntb: fix AMD processor names Raghavendra Ningoji
@ 2026-11-06  5:50 ` Raghavendra Ningoji
  2026-11-06  5:50 ` [PATCH v2 08/15] raw/ntb: fix Rx of incomplete packets Raghavendra Ningoji
                   ` (7 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-06  5:50 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson

The AMD hardware event handler could never run: the event interrupts
were never unmasked, their MSI-X vectors were never enabled and the
handler was only reached when no known doorbell was pending.
It also mishandled several simultaneous events and never cleared
the interrupt status.

Remove it, together with the now unused vendor operation and
register definitions, and document that hardware events are not
handled.

Fixes: d6dc5a7f8b06 ("raw/ntb: support AMD NTB")

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 doc/guides/rawdevs/ntb.rst   |  4 ++++
 drivers/raw/ntb/ntb.c        |  4 ----
 drivers/raw/ntb/ntb.h        |  3 ---
 drivers/raw/ntb/ntb_hw_amd.c | 42 +-----------------------------------
 drivers/raw/ntb/ntb_hw_amd.h | 21 ------------------
 5 files changed, 5 insertions(+), 69 deletions(-)

diff --git a/doc/guides/rawdevs/ntb.rst b/doc/guides/rawdevs/ntb.rst
index 37328cd9e6..c4ad2f05c4 100644
--- a/doc/guides/rawdevs/ntb.rst
+++ b/doc/guides/rawdevs/ntb.rst
@@ -53,6 +53,10 @@ The AMD NTB hardware exposes two memory windows (BAR23 and BAR45),
 The scratchpad bank is split into two disjoint 8-register sets, one owned by each side,
 so the driver uses a packed handshake layout that fits within 8 registers.
 
+The AMD NTB hardware events (link up/down, peer reset, power state changes)
+are not handled: a peer going away is only detected through the doorbell
+handshake done when the peer device is stopped.
+
 The AMD NTB uses an outbound translation window:
 a write to a memory window offset is forwarded to ``(base | offset)`` in the peer's memory
 rather than ``(base + offset)``.
diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index bde17c3c86..bface8d497 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -120,10 +120,6 @@ ntb_dev_intr_handler(void *param)
 
 	/* Clear other received doorbells. */
 	(*hw->ntb_ops->db_clear)(dev, db_bits);
-
-	/* Let the vendor process any hardware-specific events. */
-	if (hw->ntb_ops->handle_hw_event != NULL)
-		(*hw->ntb_ops->handle_hw_event)(dev);
 }
 
 static void
diff --git a/drivers/raw/ntb/ntb.h b/drivers/raw/ntb/ntb.h
index f867f0323d..f9f5bceede 100644
--- a/drivers/raw/ntb/ntb.h
+++ b/drivers/raw/ntb/ntb.h
@@ -105,8 +105,6 @@ enum ntb_spad_idx {
  * @link_cleanup: Tear down the local scratchpad/translation state so the
  * peer can no longer reach local memory.
  * @mem_align: Base-address alignment required for a memory window memzone of a given length.
- * @handle_hw_event: Optional. Process vendor-specific hardware events from
- * the common interrupt handler. May be NULL.
  */
 struct ntb_dev_ops {
 	int (*ntb_dev_init)(const struct rte_rawdev *dev);
@@ -129,7 +127,6 @@ struct ntb_dev_ops {
 	int (*read_peer_config)(const struct rte_rawdev *dev);
 	void (*link_cleanup)(const struct rte_rawdev *dev);
 	uint64_t (*mem_align)(const struct rte_rawdev *dev, uint32_t mw_id, uint64_t mw_len);
-	void (*handle_hw_event)(const struct rte_rawdev *dev);
 };
 
 struct ntb_desc {
diff --git a/drivers/raw/ntb/ntb_hw_amd.c b/drivers/raw/ntb/ntb_hw_amd.c
index 9b274bc6b9..abb923b384 100644
--- a/drivers/raw/ntb/ntb_hw_amd.c
+++ b/drivers/raw/ntb/ntb_hw_amd.c
@@ -441,7 +441,7 @@ static int
 amd_ntb_vector_bind(const struct rte_rawdev *dev __rte_unused, uint8_t intr __rte_unused,
 		uint8_t msix __rte_unused)
 {
-	/* Each doorbell/event maps to its MSI-X vector by default. */
+	/* Each doorbell maps to its MSI-X vector by default. */
 	return 0;
 }
 
@@ -565,45 +565,6 @@ amd_ntb_link_cleanup(const struct rte_rawdev *dev)
 		amd_ntb_mw_set_trans(dev, i, 0, 0);
 }
 
-/* Handle link/power-management events and acknowledge the SMU. Invoked from
- * the common interrupt handler when no inter-device doorbell is pending.
- */
-static void
-amd_ntb_handle_hw_event(const struct rte_rawdev *dev)
-{
-	struct ntb_hw *ntb = dev->dev_private;
-	uint32_t event, ack;
-
-	event = rte_read32((char *)ntb->hw_addr + AMD_INTSTAT_OFFSET);
-	event &= AMD_EVENT_INTMASK;
-	if (event == 0)
-		return;
-
-	switch (event) {
-	case AMD_PEER_FLUSH_EVENT:
-		NTB_LOG(INFO, "Peer flush event.");
-		break;
-	case AMD_PEER_D0_EVENT:
-		ack = rte_read32((char *)ntb->hw_addr + AMD_PMESTAT_OFFSET);
-		if (ack & 0x1)
-			NTB_LOG(INFO, "D0 wakeup completed for NTB.");
-		/* fall through to ack the SMU */
-		/* Falls through. */
-	case AMD_PEER_RESET_EVENT:
-	case AMD_LINK_DOWN_EVENT:
-	case AMD_PEER_D3_EVENT:
-	case AMD_PEER_PMETO_EVENT:
-	case AMD_LINK_UP_EVENT:
-		ack = rte_read32((char *)ntb->hw_addr + AMD_SMUACK_OFFSET);
-		ack |= event;
-		rte_write32(ack, (char *)ntb->hw_addr + AMD_SMUACK_OFFSET);
-		break;
-	default:
-		NTB_LOG(ERR, "Unknown interrupt event 0x%" PRIx32, event);
-		break;
-	}
-}
-
 static uint64_t
 amd_ntb_get_mem_align(const struct rte_rawdev *dev __rte_unused, uint32_t mw_id __rte_unused,
 		uint64_t mw_len)
@@ -630,5 +591,4 @@ const struct ntb_dev_ops amd_ntb_ops = {
 	.read_peer_config	= amd_ntb_read_peer_config,
 	.link_cleanup		= amd_ntb_link_cleanup,
 	.mem_align		= amd_ntb_get_mem_align,
-	.handle_hw_event	= amd_ntb_handle_hw_event,
 };
diff --git a/drivers/raw/ntb/ntb_hw_amd.h b/drivers/raw/ntb/ntb_hw_amd.h
index b03aed7d08..8fffa24348 100644
--- a/drivers/raw/ntb/ntb_hw_amd.h
+++ b/drivers/raw/ntb/ntb_hw_amd.h
@@ -16,7 +16,6 @@
 #define AMD_MW_COUNT			2
 #define AMD_DB_COUNT			16
 #define AMD_SPAD_COUNT			16
-#define AMD_MSIX_VECTOR_COUNT		24
 
 /* Peer register window: peer register = primary offset + 0x400. */
 #define AMD_PEER_OFFSET			0x400
@@ -37,10 +36,6 @@
 #define AMD_DBREQ_OFFSET		0x454	/* Doorbell request. */
 #define AMD_DBMASK_OFFSET		0x45C	/* Doorbell mask. */
 #define AMD_DBSTAT_OFFSET		0x460	/* Doorbell status. */
-#define AMD_INTMASK_OFFSET		0x470	/* Interrupt mask. */
-#define AMD_INTSTAT_OFFSET		0x474	/* Interrupt status. */
-#define AMD_PMESTAT_OFFSET		0x480	/* PME status. */
-#define AMD_SMUACK_OFFSET		0x4A0	/* SMU control (PSMU_ACK). */
 
 /* Link Status Register (0x408) bits, spec Table 5. */
 #define AMD_SIDE_MASK			(1 << 0) /* 0: primary, 1: secondary. */
@@ -50,22 +45,6 @@
 #define AMD_SMM_REG_CTL			(1 << 20)
 #define AMD_PMM_REG_CTL			(1 << 21)
 
-/* Interrupt Status/Mask event bits, spec Table 7. */
-#define AMD_PEER_FLUSH_EVENT		(1 << 0)
-#define AMD_PEER_RESET_EVENT		(1 << 1)
-#define AMD_PEER_D3_EVENT		(1 << 2)
-#define AMD_PEER_PMETO_EVENT		(1 << 3)
-#define AMD_PEER_D0_EVENT		(1 << 4)
-#define AMD_LINK_UP_EVENT		(1 << 5)
-#define AMD_LINK_DOWN_EVENT		(1 << 6)
-#define AMD_EVENT_INTMASK		(AMD_PEER_FLUSH_EVENT | \
-					 AMD_PEER_RESET_EVENT | \
-					 AMD_PEER_D3_EVENT | \
-					 AMD_PEER_PMETO_EVENT | \
-					 AMD_PEER_D0_EVENT | \
-					 AMD_LINK_UP_EVENT | \
-					 AMD_LINK_DOWN_EVENT)
-
 /* PCIe link status decoding (link speed/width). */
 #define AMD_LNK_STA_SPEED_MASK		0x000f
 #define AMD_LNK_STA_WIDTH_MASK		0x03f0
-- 
2.34.1


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

* [PATCH v2 08/15] raw/ntb: fix Rx of incomplete packets
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (21 preceding siblings ...)
  2026-11-06  5:50 ` [PATCH v2 07/15] raw/ntb: remove AMD hardware event handling Raghavendra Ningoji
@ 2026-11-06  5:50 ` Raghavendra Ningoji
  2026-11-06  5:50 ` [PATCH v2 09/15] raw/ntb: fix double free of Rx mbufs on stop Raghavendra Ningoji
                   ` (6 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-06  5:50 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson, stable

When a packet had no EOP descriptor among the ones walked, or when a
refill mbuf could not be allocated in the middle of a packet, the Rx
burst stopped with the packet partially consumed: the ring indexes had
moved, but the mbuf chain was neither returned nor freed, and the
refilled descriptors were not published to the peer if no packet had
been completed before.

The EOP guard also bounded the walk on the ring size rather than on
the descriptors actually published by the peer.

Only take a packet once all of its descriptors have been published,
and allocate its refill mbufs before consuming it, so that the ring
indexes are only advanced for complete packets.

Fixes: 11b5c7daf019 ("raw/ntb: add enqueue and dequeue functions")
Fixes: 5ce50c234ad1 ("raw/ntb: generalize framework for multiple vendors")
Cc: stable@dpdk.org

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb.c | 39 +++++++++++++++++++++------------------
 1 file changed, 21 insertions(+), 18 deletions(-)

diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index bface8d497..eb562052d8 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -650,13 +650,14 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
 	struct ntb_rx_queue *rxq = hw->rx_queues[(size_t)context];
 	struct ntb_rx_entry *sw_ring = rxq->sw_ring;
 	struct ntb_desc rx_desc[NTB_MAX_DESC_SIZE];
-	struct rte_mbuf *first, *rxm_t;
+	struct rte_mbuf *new_mbufs[NTB_MAX_DESC_SIZE];
+	struct rte_mbuf *first = NULL, *rxm_t;
 	struct rte_mbuf *prev = NULL;
 	volatile struct ntb_used *rx_item;
 	uint16_t nb_mbufs = 0;
 	uint16_t nb_rx = 0;
 	uint64_t bytes = 0;
-	uint16_t off, last_avail, used_cnt, used_nb;
+	uint16_t off, last_avail, used_cnt, used_nb, nb_segs;
 	int i;
 
 	if (unlikely(dev->started == 0 || hw->peer_dev_up == 0)) {
@@ -673,13 +674,24 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
 	used_nb = (used_cnt - rxq->last_used) & (rxq->nb_rx_desc - 1);
 	count = RTE_MIN(count, used_nb);
 	for (nb_rx = 0; nb_rx < count; nb_rx++) {
-		i = 0;
-		while (true) {
-			if (unlikely(nb_mbufs >= rxq->nb_rx_desc)) {
-				NTB_LOG(ERR, "Malformed rx stream (no EOP); "
-					"aborting to avoid desc overflow.");
+		/* Only take a packet once the peer has published all of it. */
+		for (nb_segs = 1; ; nb_segs++) {
+			if (nb_segs > used_nb)
 				goto end_of_rx;
-			}
+			rx_item = rxq->rx_used_ring + ((rxq->last_used + nb_segs - 1) &
+						       (rxq->nb_rx_desc - 1));
+			if (rx_item->flags & NTB_FLAG_EOP)
+				break;
+		}
+
+		/* Get the refill mbufs first so a packet is never partially consumed. */
+		if (unlikely(rte_mbuf_raw_alloc_bulk(rxq->mpool, new_mbufs, nb_segs))) {
+			NTB_LOG(ERR, "recv alloc mbuf failed.");
+			goto end_of_rx;
+		}
+		used_nb -= nb_segs;
+
+		for (i = 0; i < nb_segs; i++) {
 			rx_item = rxq->rx_used_ring + rxq->last_used;
 			rxm_t = sw_ring[rxq->last_used].mbuf;
 			rxm_t->data_len = rx_item->len;
@@ -701,15 +713,9 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
 			rxq->last_used = (rxq->last_used + 1) &
 					 (rxq->nb_rx_desc - 1);
 
-			/* alloc new mbuf */
-			rxm_t = rte_mbuf_raw_alloc(rxq->mpool);
-			if (unlikely(rxm_t == NULL)) {
-				NTB_LOG(ERR, "recv alloc mbuf failed.");
-				goto end_of_rx;
-			}
+			rxm_t = new_mbufs[i];
 			rxm_t->port = rxq->port_id;
 			sw_ring[rxq->last_avail].mbuf = rxm_t;
-			i++;
 
 			/* fill new desc */
 			rx_desc[nb_mbufs].addr =
@@ -718,9 +724,6 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
 						  RTE_PKTMBUF_HEADROOM;
 			rxq->last_avail = (rxq->last_avail + 1) &
 					  (rxq->nb_rx_desc - 1);
-
-			if (rx_item->flags & NTB_FLAG_EOP)
-				break;
 		}
 		/* update stats */
 		bytes += first->pkt_len;
-- 
2.34.1


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

* [PATCH v2 09/15] raw/ntb: fix double free of Rx mbufs on stop
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (22 preceding siblings ...)
  2026-11-06  5:50 ` [PATCH v2 08/15] raw/ntb: fix Rx of incomplete packets Raghavendra Ningoji
@ 2026-11-06  5:50 ` Raghavendra Ningoji
  2026-11-06  5:50 ` [PATCH v2 10/15] examples/ntb: fix raw/ntb library linking Raghavendra Ningoji
                   ` (5 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-06  5:50 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson, stable

Once an Rx mbuf is handed to the application, its software ring entry
still references it until the slot is refilled. On device stop, all
referenced mbufs are freed, including the one now owned by the
application.

Clear the ring entry when the mbuf is taken.

Fixes: 11b5c7daf019 ("raw/ntb: add enqueue and dequeue functions")
Cc: stable@dpdk.org

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index eb562052d8..5b3abcb008 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -694,6 +694,7 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
 		for (i = 0; i < nb_segs; i++) {
 			rx_item = rxq->rx_used_ring + rxq->last_used;
 			rxm_t = sw_ring[rxq->last_used].mbuf;
+			sw_ring[rxq->last_used].mbuf = NULL;
 			rxm_t->data_len = rx_item->len;
 			rxm_t->data_off = RTE_PKTMBUF_HEADROOM;
 			rxm_t->port = rxq->port_id;
-- 
2.34.1


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

* [PATCH v2 10/15] examples/ntb: fix raw/ntb library linking
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (23 preceding siblings ...)
  2026-11-06  5:50 ` [PATCH v2 09/15] raw/ntb: fix double free of Rx mbufs on stop Raghavendra Ningoji
@ 2026-11-06  5:50 ` Raghavendra Ningoji
  2026-11-06  5:50 ` [PATCH v2 11/15] doc: add NTB device info change to ABI section Raghavendra Ningoji
                   ` (4 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-06  5:50 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson

The raw/ntb driver library was added to the linker flags of both the
shared and static targets. For static linking, it is already part of
the libdpdk pkg-config output, so only add it to the shared target,
as done in other examples.

Fixes: 5ce50c234ad1 ("raw/ntb: generalize framework for multiple vendors")

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 examples/ntb/Makefile | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/examples/ntb/Makefile b/examples/ntb/Makefile
index 6c0307c697..a074251646 100644
--- a/examples/ntb/Makefile
+++ b/examples/ntb/Makefile
@@ -23,11 +23,12 @@ static: build/$(APP)-static
 	ln -sf $(APP)-static build/$(APP)
 
 CFLAGS += -D_FILE_OFFSET_BITS=64
-LDFLAGS += -pthread -lrte_raw_ntb
+LDFLAGS += -pthread
 
 PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null)
 CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) -I build/
 LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk)
+LDFLAGS_SHARED += -lrte_raw_ntb
 LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk)
 
 build/commands.h: commands.list Makefile
-- 
2.34.1


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

* [PATCH v2 11/15] doc: add NTB device info change to ABI section
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (24 preceding siblings ...)
  2026-11-06  5:50 ` [PATCH v2 10/15] examples/ntb: fix raw/ntb library linking Raghavendra Ningoji
@ 2026-11-06  5:50 ` Raghavendra Ningoji
  2026-11-06  5:50 ` [PATCH v2 12/15] doc: add IOVA requirement for NTB Raghavendra Ningoji
                   ` (3 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-06  5:50 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson

Removing the mw_size_align field changed the layout of the installed
struct ntb_dev_info. Mention it in the ABI changes as well.

Fixes: 5ce50c234ad1 ("raw/ntb: generalize framework for multiple vendors")

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 doc/guides/rel_notes/release_26_11.rst | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index 6c76c60139..23980d5364 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -689,6 +689,8 @@ ABI Changes
 * cryptodev: The struct ``rte_crypto_rsa_op_param``
   was updated to include ``pss_salt``.
 
+* raw/ntb: The ``mw_size_align`` field was removed from ``struct ntb_dev_info``.
+
 
 Known Issues
 ------------
-- 
2.34.1


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

* [PATCH v2 12/15] doc: add IOVA requirement for NTB
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (25 preceding siblings ...)
  2026-11-06  5:50 ` [PATCH v2 11/15] doc: add NTB device info change to ABI section Raghavendra Ningoji
@ 2026-11-06  5:50 ` Raghavendra Ningoji
  2026-11-06  5:50 ` [PATCH v2 13/15] raw/ntb: remove unused AMD register definitions Raghavendra Ningoji
                   ` (2 subsequent siblings)
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-06  5:50 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson

The memory window memzone is reserved with the alignment required by
the NTB hardware, but this alignment applies to the virtual address.
With IOVA as PA and a memzone larger than the hugepage size, the IOVA
may not be aligned and the device configuration fails.

Document that IOVA as VA mode or large enough hugepages are needed.

Fixes: 5ce50c234ad1 ("raw/ntb: generalize framework for multiple vendors")

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 doc/guides/rawdevs/ntb.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/doc/guides/rawdevs/ntb.rst b/doc/guides/rawdevs/ntb.rst
index c4ad2f05c4..8332c27de9 100644
--- a/doc/guides/rawdevs/ntb.rst
+++ b/doc/guides/rawdevs/ntb.rst
@@ -66,6 +66,10 @@ Different NTB hardware imposes different alignment constraints,
 so applications should not assume any particular value:
 reserve each memory window memzone with the alignment returned by ``rte_pmd_ntb_get_mem_align()``
 for that window and length. The ``ntb_fwd`` example shows this usage.
+The memzone alignment applies to its virtual address.
+With IOVA as PA, the IOVA of a memzone larger than the hugepage size
+is not guaranteed to be aligned, and the device configuration fails:
+use IOVA as VA mode, or hugepages at least as large as the memory window.
 
 Device Setup
 ------------
-- 
2.34.1


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

* [PATCH v2 13/15] raw/ntb: remove unused AMD register definitions
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (26 preceding siblings ...)
  2026-11-06  5:50 ` [PATCH v2 12/15] doc: add IOVA requirement for NTB Raghavendra Ningoji
@ 2026-11-06  5:50 ` Raghavendra Ningoji
  2026-11-06  5:50 ` [PATCH v2 14/15] raw/ntb: fix peer device status access Raghavendra Ningoji
  2026-11-06  5:50 ` [PATCH v2 15/15] raw/ntb: fix queue setup checks Raghavendra Ningoji
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-06  5:50 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson

The scratchpad mutex and doorbell flush mode registers are not used
by the driver.

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb_hw_amd.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/raw/ntb/ntb_hw_amd.h b/drivers/raw/ntb/ntb_hw_amd.h
index 8fffa24348..eec2041ad2 100644
--- a/drivers/raw/ntb/ntb_hw_amd.h
+++ b/drivers/raw/ntb/ntb_hw_amd.h
@@ -25,14 +25,12 @@
 
 /* Primary-side MMIO register offsets (BAR0), spec Table 1. */
 #define AMD_CNTL_OFFSET			0x200	/* Link Control. */
-#define AMD_SPADMUTEX_OFFSET		0x20C	/* Scratchpad mutex. */
 #define AMD_SPAD_OFFSET			0x210	/* Scratchpad registers. */
 #define AMD_SIDEINFO_OFFSET		0x408	/* Link Status (PSIDE_INFO). */
 #define AMD_BAR23_LIMIT_OFFSET		0x418	/* MW BAR23 size. */
 #define AMD_BAR45_LIMIT_OFFSET		0x420	/* MW BAR45 size. */
 #define AMD_BAR23_XLAT_OFFSET		0x438	/* MW BAR23 translation. */
 #define AMD_BAR45_XLAT_OFFSET		0x440	/* MW BAR45 translation. */
-#define AMD_DBFM_OFFSET			0x450	/* Doorbell flush mode. */
 #define AMD_DBREQ_OFFSET		0x454	/* Doorbell request. */
 #define AMD_DBMASK_OFFSET		0x45C	/* Doorbell mask. */
 #define AMD_DBSTAT_OFFSET		0x460	/* Doorbell status. */
-- 
2.34.1


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

* [PATCH v2 14/15] raw/ntb: fix peer device status access
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (27 preceding siblings ...)
  2026-11-06  5:50 ` [PATCH v2 13/15] raw/ntb: remove unused AMD register definitions Raghavendra Ningoji
@ 2026-11-06  5:50 ` Raghavendra Ningoji
  2026-11-06  5:50 ` [PATCH v2 15/15] raw/ntb: fix queue setup checks Raghavendra Ningoji
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-06  5:50 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson, stable

The peer device status is written by the interrupt thread when the
peer doorbells are handled, and read by the control and data paths;
in particular, device stop polls it while waiting for the peer to
acknowledge. Plain accesses do not guarantee that this update is seen,
the stop loop only works because the delay call is opaque to the
compiler.

Use atomic accesses with release/acquire ordering.

Fixes: 62012a76811e ("raw/ntb: add handshake process")
Cc: stable@dpdk.org

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb.c | 28 +++++++++++++++++-----------
 drivers/raw/ntb/ntb.h |  5 ++++-
 2 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index 5b3abcb008..86405ad57a 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -48,6 +48,12 @@ static struct rte_rawdev_xstats_name ntb_xstats_names[] = {
 };
 #define NTB_XSTATS_NUM RTE_DIM(ntb_xstats_names)
 
+static inline bool
+ntb_peer_dev_is_up(struct ntb_hw *hw)
+{
+	return rte_atomic_load_explicit(&hw->peer_dev_up, rte_memory_order_acquire) != 0;
+}
+
 static void
 ntb_dev_intr_handler(void *param)
 {
@@ -69,14 +75,14 @@ ntb_dev_intr_handler(void *param)
 		 * Peer dev is already up. All mw settings are already done.
 		 * Skip them.
 		 */
-		if (hw->peer_dev_up)
+		if (ntb_peer_dev_is_up(hw))
 			return;
 
 		/* Check that the peer memory-window layout matches local. */
 		if ((*hw->ntb_ops->peer_mw_validate)(dev) < 0)
 			return;
 
-		hw->peer_dev_up = 1;
+		rte_atomic_store_explicit(&hw->peer_dev_up, 1, rte_memory_order_release);
 
 		/**
 		 * Handshake with peer. Scratchpad and translation programming
@@ -104,7 +110,7 @@ ntb_dev_intr_handler(void *param)
 		/* Peer device will be down, So clean local side too. */
 		(*hw->ntb_ops->link_cleanup)(dev);
 
-		hw->peer_dev_up = 0;
+		rte_atomic_store_explicit(&hw->peer_dev_up, 0, rte_memory_order_release);
 		/* Response peer's dev_stop request. */
 		(*hw->ntb_ops->peer_db_set)(dev, 2);
 		return;
@@ -114,7 +120,7 @@ ntb_dev_intr_handler(void *param)
 		NTB_LOG(INFO, "DB2: Peer device agrees dev to be down.");
 		/* Clear received doorbell. */
 		(*hw->ntb_ops->db_clear)(dev, (1 << 2));
-		hw->peer_dev_up = 0;
+		rte_atomic_store_explicit(&hw->peer_dev_up, 0, rte_memory_order_release);
 		return;
 	}
 
@@ -549,7 +555,7 @@ ntb_enqueue_bufs(struct rte_rawdev *dev,
 	void *buf_addr;
 	int i;
 
-	if (unlikely(dev->started == 0 || hw->peer_dev_up == 0)) {
+	if (unlikely(dev->started == 0 || !ntb_peer_dev_is_up(hw))) {
 		NTB_LOG(DEBUG, "Link is not up.");
 		return nb_tx;
 	}
@@ -660,7 +666,7 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
 	uint16_t off, last_avail, used_cnt, used_nb, nb_segs;
 	int i;
 
-	if (unlikely(dev->started == 0 || hw->peer_dev_up == 0)) {
+	if (unlikely(dev->started == 0 || !ntb_peer_dev_is_up(hw))) {
 		NTB_LOG(DEBUG, "Link is not up");
 		return nb_rx;
 	}
@@ -853,7 +859,7 @@ ntb_dev_start(struct rte_rawdev *dev)
 	uint32_t i;
 	int ret;
 
-	if (!hw->link_status || !hw->peer_dev_up)
+	if (!hw->link_status || !ntb_peer_dev_is_up(hw))
 		return -EINVAL;
 
 	/* Set total stats. */
@@ -907,7 +913,7 @@ ntb_dev_stop(struct rte_rawdev *dev)
 	uint32_t time_out;
 	int status, i;
 
-	if (!hw->peer_dev_up)
+	if (!ntb_peer_dev_is_up(hw))
 		goto clean;
 
 	(*hw->ntb_ops->link_cleanup)(dev);
@@ -926,7 +932,7 @@ ntb_dev_stop(struct rte_rawdev *dev)
 	time_out = 1000000;
 
 	/* Wait for cleanup work down before db mask clear. */
-	while (hw->peer_dev_up && time_out) {
+	while (ntb_peer_dev_is_up(hw) && time_out) {
 		time_out -= 10;
 		rte_delay_us(10);
 	}
@@ -1061,7 +1067,7 @@ ntb_attr_get(struct rte_rawdev *dev, const char *attr_name,
 
 	if (!strncmp(attr_name, NTB_LINK_STATUS_NAME, NTB_ATTR_NAME_LEN)) {
 		/* hw->link_status only indicates hw link status. */
-		*attr_value = hw->link_status && hw->peer_dev_up;
+		*attr_value = hw->link_status && ntb_peer_dev_is_up(hw);
 		NTB_LOG(DEBUG, "Attribute (%s) Value (%" PRIu64 ")",
 			attr_name, *attr_value);
 		return 0;
@@ -1325,7 +1331,7 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
 	int ret, i;
 
 	hw->pci_dev = pci_dev;
-	hw->peer_dev_up = 0;
+	rte_atomic_store_explicit(&hw->peer_dev_up, 0, rte_memory_order_release);
 	hw->link_status = NTB_LINK_DOWN;
 	hw->link_speed = NTB_SPEED_NONE;
 	hw->link_width = NTB_WIDTH_NONE;
diff --git a/drivers/raw/ntb/ntb.h b/drivers/raw/ntb/ntb.h
index f9f5bceede..6dce038e0b 100644
--- a/drivers/raw/ntb/ntb.h
+++ b/drivers/raw/ntb/ntb.h
@@ -7,6 +7,8 @@
 
 #include <stdbool.h>
 
+#include <rte_stdatomic.h>
+
 extern int ntb_logtype;
 #define RTE_LOGTYPE_NTB ntb_logtype
 
@@ -223,7 +225,8 @@ struct ntb_hw {
 	struct rte_intr_handle **db_intr_handles;
 	uint16_t nb_db_intr_handles;
 
-	uint8_t peer_dev_up;
+	/* Written by the interrupt thread, read by control and data paths. */
+	RTE_ATOMIC(uint8_t) peer_dev_up;
 	uint64_t mw_size[NTB_MAX_MW];
 	/* remote mem base addr */
 	uint64_t *peer_mw_base;
-- 
2.34.1


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

* [PATCH v2 15/15] raw/ntb: fix queue setup checks
  2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
                   ` (28 preceding siblings ...)
  2026-11-06  5:50 ` [PATCH v2 14/15] raw/ntb: fix peer device status access Raghavendra Ningoji
@ 2026-11-06  5:50 ` Raghavendra Ningoji
  29 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-06  5:50 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson, stable

The number of descriptors given at queue setup was not checked, while
the ring indexes wrap with a mask, requiring a power of 2, and the
burst functions use on-stack arrays of NTB_MAX_DESC_SIZE entries.

The Rx queue structure was also leaked when no mempool was given, and
the Tx queue structure and its ring when the Tx free threshold was
invalid.

Check the configuration before allocating the queue.

Fixes: c39d1e082a4b ("raw/ntb: setup queues")
Cc: stable@dpdk.org

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb.c | 51 +++++++++++++++++++++++++++++++------------
 1 file changed, 37 insertions(+), 14 deletions(-)

diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index 86405ad57a..8b1c332fbb 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -246,6 +246,20 @@ ntb_rxq_release(struct ntb_rx_queue *rxq)
 	rte_free(rxq);
 }
 
+/* The ring indexes wrap with a mask and the bursts use on-stack arrays. */
+static int
+ntb_queue_nb_desc_check(uint16_t nb_desc)
+{
+	if (nb_desc < NTB_MIN_DESC_SIZE || nb_desc > NTB_MAX_DESC_SIZE ||
+	    !rte_is_power_of_2(nb_desc)) {
+		NTB_LOG(ERR, "Number of descriptors %u must be a power of 2 within [%u, %u].",
+			nb_desc, NTB_MIN_DESC_SIZE, NTB_MAX_DESC_SIZE);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int
 ntb_rxq_setup(struct rte_rawdev *dev,
 	      uint16_t qp_id,
@@ -259,6 +273,14 @@ ntb_rxq_setup(struct rte_rawdev *dev,
 	if (conf_size != sizeof(*rxq_conf))
 		return -EINVAL;
 
+	if (rxq_conf->rx_mp == NULL) {
+		NTB_LOG(ERR, "Invalid null mempool pointer.");
+		return -EINVAL;
+	}
+
+	if (ntb_queue_nb_desc_check(rxq_conf->nb_desc) < 0)
+		return -EINVAL;
+
 	/* Allocate the rx queue data structure */
 	rxq = rte_zmalloc_socket("ntb rx queue",
 				 sizeof(struct ntb_rx_queue),
@@ -270,10 +292,6 @@ ntb_rxq_setup(struct rte_rawdev *dev,
 		return -ENOMEM;
 	}
 
-	if (rxq_conf->rx_mp == NULL) {
-		NTB_LOG(ERR, "Invalid null mempool pointer.");
-		return -EINVAL;
-	}
 	rxq->nb_rx_desc = rxq_conf->nb_desc;
 	rxq->mpool = rxq_conf->rx_mp;
 	rxq->port_id = dev->dev_id;
@@ -340,11 +358,24 @@ ntb_txq_setup(struct rte_rawdev *dev,
 	struct ntb_queue_conf *txq_conf = queue_conf;
 	struct ntb_hw *hw = dev->dev_private;
 	struct ntb_tx_queue *txq;
-	uint16_t i, prev;
+	uint16_t i, prev, tx_free_thresh;
 
 	if (conf_size != sizeof(*txq_conf))
 		return -EINVAL;
 
+	if (ntb_queue_nb_desc_check(txq_conf->nb_desc) < 0)
+		return -EINVAL;
+
+	tx_free_thresh = txq_conf->tx_free_thresh ?
+			 txq_conf->tx_free_thresh :
+			 NTB_DFLT_TX_FREE_THRESH;
+	if (tx_free_thresh >= txq_conf->nb_desc - 3) {
+		NTB_LOG(ERR, "tx_free_thresh must be less than nb_desc - 3. "
+			"(tx_free_thresh=%u qp_id=%u)", tx_free_thresh,
+			qp_id);
+		return -EINVAL;
+	}
+
 	/* Allocate the TX queue data structure. */
 	txq = rte_zmalloc_socket("ntb tx queue",
 				  sizeof(struct ntb_tx_queue),
@@ -383,15 +414,7 @@ ntb_txq_setup(struct rte_rawdev *dev,
 		prev = i;
 	}
 
-	txq->tx_free_thresh = txq_conf->tx_free_thresh ?
-			      txq_conf->tx_free_thresh :
-			      NTB_DFLT_TX_FREE_THRESH;
-	if (txq->tx_free_thresh >= txq->nb_tx_desc - 3) {
-		NTB_LOG(ERR, "tx_free_thresh must be less than nb_desc - 3. "
-			"(tx_free_thresh=%u qp_id=%u)", txq->tx_free_thresh,
-			qp_id);
-		return -EINVAL;
-	}
+	txq->tx_free_thresh = tx_free_thresh;
 
 	hw->tx_queues[qp_id] = txq;
 
-- 
2.34.1


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

* Re: [PATCH 00/13] raw/ntb: post-merge fixes
  2026-11-04 12:24 ` [PATCH 00/13] raw/ntb: post-merge fixes Stephen Hemminger
@ 2026-11-06  5:54   ` Raghavendra Ningoji
  0 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-06  5:54 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: dev, David Marchand, Jingjing Wu, Selwin Sebastian,
	Bhagyada Modali, bruce.richardson

Hi Stephen,

Thanks for the review. All the points are addressed in v2:

- mw_size is now embedded in struct ntb_hw, as suggested (patch 4).
- The doorbell interrupt handle array uses calloc() (patch 5).
- peer_dev_up uses atomic accesses (new patch 14).
- Queue setup checks are added, before any allocation, for both Rx and
  Tx (new patch 15).

Thanks,
Raghavendra

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

* Re: [PATCH v2 00/15] raw/ntb: post-merge fixes
  2026-11-06  5:50 ` [PATCH v2 00/15] " Raghavendra Ningoji
@ 2026-11-06 12:50   ` Stephen Hemminger
  2026-11-11  7:09     ` Raghavendra Ningoji
  2026-11-11  7:06   ` [PATCH v3 00/16] " Raghavendra Ningoji
  1 sibling, 1 reply; 52+ messages in thread
From: Stephen Hemminger @ 2026-11-06 12:50 UTC (permalink / raw)
  To: Raghavendra Ningoji
  Cc: dev, david.marchand, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson

On Fri, 6 Nov 2026 11:20:30 +0530
Raghavendra Ningoji <raghavendra.ningoji@amd.com> wrote:

> This series addresses the post-merge review of the AMD NTB support
> by Stephen. Some of the issues also exist in the Intel code and in
> released versions; those patches are tagged for stable.
> 
> - Patches 1-4 fix the type confusion in rte_pmd_ntb_get_mem_align(),
>   the unbounded peer memory window count, the off-by-one in the
>   address remapping and the memory window leaks.
> 
> - Patch 5 fixes the doorbell interrupts with vfio-pci: only MSI-X
>   vector 0 (DB0) was serviced, so the DB1/DB2 exchange of dev_stop
>   never completed and the stop waited for its 1s timeout.
> 
> - Patch 7 removes the AMD hardware event handling, which could not run
>   as wired, and documents that hardware events are not handled.
> 
> - Patches 8-9 fix the Rx path: a partially consumed packet was leaked
>   and desynchronized the ring, and an mbuf owned by the application
>   could be freed again on device stop.
> 
> - Patches 14-15 fix the peer device status accesses between the
>   interrupt thread and the stop/data paths, and the missing checks at
>   queue setup.
> 
> - The other patches are documentation and cleanup.
> 
> The peer memory window size check suggested for the AMD handshake is
> not added: all the AMD scratchpads are in use, and the window limit
> register programmed with the local memzone length already bounds what
> the peer can reach.
> 
> Tested with vfio-pci on two AMD EPYC Embedded hosts: handshake,
> file transfer, and stop/quit with DB1/DB2 exchange.
> 
> ---
> Changes since v1:
> - Patch 4: embed the memory window size array in struct ntb_hw instead
>   of freeing it on close, as the device stays attached after close and
>   mw_size could then be dereferenced as NULL.
> - Patch 5: allocate the doorbell interrupt handle array with calloc(),
>   as it only holds process-private pointers.
> - Added patch 14 for the peer device status atomic accesses.
> - Added patch 15 for the queue setup checks, also covering the Tx side
>   (unchecked nb_desc, and queue leak on invalid tx_free_thresh).
> 
> Raghavendra Ningoji (15):
>   raw/ntb: fix device check in memory alignment query
>   raw/ntb: fix peer memory window count check
>   raw/ntb: fix memory window bound in address remapping
>   raw/ntb: fix memory leaks
>   raw/ntb: fix doorbell interrupts with VFIO MSI-X
>   raw/ntb: fix AMD processor names
>   raw/ntb: remove AMD hardware event handling
>   raw/ntb: fix Rx of incomplete packets
>   raw/ntb: fix double free of Rx mbufs on stop
>   examples/ntb: fix raw/ntb library linking
>   doc: add NTB device info change to ABI section
>   doc: add IOVA requirement for NTB
>   raw/ntb: remove unused AMD register definitions
>   raw/ntb: fix peer device status access
>   raw/ntb: fix queue setup checks
> 
>  doc/guides/rawdevs/ntb.rst             |  12 +-
>  doc/guides/rel_notes/release_26_11.rst |   6 +-
>  drivers/raw/ntb/ntb.c                  | 212 +++++++++++++++++++------
>  drivers/raw/ntb/ntb.h                  |  17 +-
>  drivers/raw/ntb/ntb_hw_amd.c           |  60 ++-----
>  drivers/raw/ntb/ntb_hw_amd.h           |  25 +--
>  drivers/raw/ntb/ntb_hw_intel.c         |  17 +-
>  examples/ntb/Makefile                  |   3 +-
>  8 files changed, 210 insertions(+), 142 deletions(-)
> 

This version gets clean review from manual AI run.
It did see one pre-existing bug though.

Subject: Re: [PATCH v2 00/15] raw/ntb: post-merge fixes

v2 applies to main (26.11-rc2) and builds at every commit with
-Dwerror=true, and with -Denable_stdatomic=true at the tip.
The v1 comments on 04/15 and 05/15 are addressed; 14/15 and 15/15
cover the pre-existing items.

Patch 15/15 raw/ntb: fix queue setup checks

Info (pre-existing, not introduced by this patch): ntb_queue_setup()
still leaks on two paths the commit message does not cover.

ntb_txq_setup() runs first and installs the queue:

	hw->tx_queues[qp_id] = txq;

so when ntb_rxq_setup() then fails (rx_mp NULL, or allocation
failure), the Tx queue is left installed. Any second setup of the
same queue id (retry after that failure, or reconfiguration)
overwrites hw->tx_queues[qp_id] and hw->rx_queues[qp_id] without
freeing the previous queues.

Validate the shared conf before touching either queue, and release
what is already there:

	if (queue_id >= hw->queue_pairs)
		return -EINVAL;

	if (conf->rx_mp == NULL)
		return -EINVAL;

	if (hw->tx_queues[queue_id] != NULL ||
	    hw->rx_queues[queue_id] != NULL)
		ntb_queue_release(dev, queue_id);

	ret = ntb_txq_setup(dev, queue_id, queue_conf, conf_size);
	if (ret < 0)
		return ret;

	ret = ntb_rxq_setup(dev, queue_id, queue_conf, conf_size);
	if (ret < 0)
		ntb_queue_release(dev, queue_id);
	return ret;

(ntb_txq_release()/ntb_rxq_release() log an error on NULL, so a
NULL check on each would be needed for the last release.) Fine as a
follow-up.


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

* [PATCH v3 00/16] raw/ntb: post-merge fixes
  2026-11-06  5:50 ` [PATCH v2 00/15] " Raghavendra Ningoji
  2026-11-06 12:50   ` Stephen Hemminger
@ 2026-11-11  7:06   ` Raghavendra Ningoji
  2026-11-11  7:06     ` [PATCH v3 01/16] raw/ntb: fix device check in memory alignment query Raghavendra Ningoji
                       ` (16 more replies)
  1 sibling, 17 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-11  7:06 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson

This series addresses the post-merge review of the AMD NTB support
by Stephen. Some of the issues also exist in the Intel code and in
released versions; those patches are tagged for stable.

- Patches 1-4 fix the type confusion in rte_pmd_ntb_get_mem_align(),
  the unbounded peer memory window count, the off-by-one in the
  address remapping and the memory window leaks.

- Patch 5 fixes the doorbell interrupts with vfio-pci: only MSI-X
  vector 0 (DB0) was serviced, so the DB1/DB2 exchange of dev_stop
  never completed and the stop waited for its 1s timeout.

- Patch 7 removes the AMD hardware event handling, which could not run
  as wired, and documents that hardware events are not handled.

- Patches 8-9 fix the Rx path: a partially consumed packet was leaked
  and desynchronized the ring, and an mbuf owned by the application
  could be freed again on device stop.

- Patches 14-16 fix the peer device status accesses between the
  interrupt thread and the stop/data paths, and the missing checks and
  leaks at queue setup.

- The other patches are documentation and cleanup.

The peer memory window size check suggested for the AMD handshake is
not added: all the AMD scratchpads are in use, and the window limit
register programmed with the local memzone length already bounds what
the peer can reach.

Tested with vfio-pci on two AMD EPYC Embedded hosts: handshake,
file transfer, and stop/quit with DB1/DB2 exchange.

---
Changes since v2:
- Resent with proper threading: in v2, all the patches replied to the
  v1 cover letter, so patchwork did not group them as a series and the
  CI could not apply them. No change in patches 1-15, apart from the
  rebase on current main.
- Added patch 16 for the queue setup leaks reported by Stephen on v2.

Changes since v1:
- Patch 4: embed the memory window size array in struct ntb_hw instead
  of freeing it on close, as the device stays attached after close and
  mw_size could then be dereferenced as NULL.
- Patch 5: allocate the doorbell interrupt handle array with calloc(),
  as it only holds process-private pointers.
- Added patch 14 for the peer device status atomic accesses.
- Added patch 15 for the queue setup checks, also covering the Tx side
  (unchecked nb_desc, and queue leak on invalid tx_free_thresh).

Raghavendra Ningoji (16):
  raw/ntb: fix device check in memory alignment query
  raw/ntb: fix peer memory window count check
  raw/ntb: fix memory window bound in address remapping
  raw/ntb: fix memory leaks
  raw/ntb: fix doorbell interrupts with VFIO MSI-X
  raw/ntb: fix AMD processor names
  raw/ntb: remove AMD hardware event handling
  raw/ntb: fix Rx of incomplete packets
  raw/ntb: fix double free of Rx mbufs on stop
  examples/ntb: fix raw/ntb library linking
  doc: add NTB device info change to ABI section
  doc: add IOVA requirement for NTB
  raw/ntb: remove unused AMD register definitions
  raw/ntb: fix peer device status access
  raw/ntb: fix queue setup checks
  raw/ntb: fix queue leaks on setup

 doc/guides/rawdevs/ntb.rst             |  12 +-
 doc/guides/rel_notes/release_26_11.rst |   6 +-
 drivers/raw/ntb/ntb.c                  | 266 ++++++++++++++++++-------
 drivers/raw/ntb/ntb.h                  |  17 +-
 drivers/raw/ntb/ntb_hw_amd.c           |  60 +-----
 drivers/raw/ntb/ntb_hw_amd.h           |  25 +--
 drivers/raw/ntb/ntb_hw_intel.c         |  17 +-
 examples/ntb/Makefile                  |   3 +-
 8 files changed, 242 insertions(+), 164 deletions(-)

-- 
2.34.1


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

* [PATCH v3 01/16] raw/ntb: fix device check in memory alignment query
  2026-11-11  7:06   ` [PATCH v3 00/16] " Raghavendra Ningoji
@ 2026-11-11  7:06     ` Raghavendra Ningoji
  2026-11-11  7:06     ` [PATCH v3 02/16] raw/ntb: fix peer memory window count check Raghavendra Ningoji
                       ` (15 subsequent siblings)
  16 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-11  7:06 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson

rte_pmd_ntb_get_mem_align() only checked the device index range and
the presence of private data before casting it to struct ntb_hw.
Passing the id of a detached slot or of a rawdev from another driver
would then call through a garbage ops pointer.

Check that the device is attached and is driven by this PMD.

Also return 0 for an out of range memory window index, as documented,
instead of a cache line size.

Fixes: 5ce50c234ad1 ("raw/ntb: generalize framework for multiple vendors")

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index fe10782ecf..e42af0b9c5 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -33,6 +33,8 @@ static const struct rte_pci_id pci_id_ntb_map[] = {
 	{ .vendor_id = 0, /* sentinel */ },
 };
 
+static const struct rte_rawdev_ops ntb_ops;
+
 /* Align with enum ntb_xstats_idx */
 static struct rte_rawdev_xstats_name ntb_xstats_names[] = {
 	{"Tx-packets"},
@@ -722,15 +724,15 @@ rte_pmd_ntb_get_mem_align(uint16_t dev_id, uint32_t mw_id, uint64_t mw_len)
 	struct rte_rawdev *dev;
 	struct ntb_hw *hw;
 
-	if (dev_id >= RTE_RAWDEV_MAX_DEVS)
+	if (dev_id >= RTE_RAWDEV_MAX_DEVS || !rte_rawdev_pmd_is_valid_dev(dev_id))
 		return 0;
 	dev = rte_rawdev_pmd_get_dev(dev_id);
-	if (dev->dev_private == NULL)
+	if (dev->dev_ops != &ntb_ops)
 		return 0;
 
 	hw = dev->dev_private;
 	if (mw_id >= hw->mw_cnt)
-		return RTE_CACHE_LINE_SIZE;
+		return 0;
 
 	return (*hw->ntb_ops->mem_align)(dev, mw_id, mw_len);
 }
-- 
2.34.1


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

* [PATCH v3 02/16] raw/ntb: fix peer memory window count check
  2026-11-11  7:06   ` [PATCH v3 00/16] " Raghavendra Ningoji
  2026-11-11  7:06     ` [PATCH v3 01/16] raw/ntb: fix device check in memory alignment query Raghavendra Ningoji
@ 2026-11-11  7:06     ` Raghavendra Ningoji
  2026-11-11  7:06     ` [PATCH v3 03/16] raw/ntb: fix memory window bound in address remapping Raghavendra Ningoji
                       ` (14 subsequent siblings)
  16 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-11  7:06 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson, stable

The number of memory windows used by the peer is read from a
scratchpad register written by the peer, and is then used as the loop
bound to fill peer_mw_base[], which is allocated with mw_cnt entries.
A peer advertising more windows (bug, version mismatch, or a stale
scratchpad) makes the driver write past the end of this array.
On Intel, the 32-bit register value was also silently truncated into
the 8-bit peer_used_mws field.

Reject a peer configuration using more windows than the local device
has.

Fixes: c39d1e082a4b ("raw/ntb: setup queues")
Fixes: d6dc5a7f8b06 ("raw/ntb: support AMD NTB")
Cc: stable@dpdk.org

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb_hw_amd.c   | 10 ++++++++--
 drivers/raw/ntb/ntb_hw_intel.c |  7 ++++++-
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/raw/ntb/ntb_hw_amd.c b/drivers/raw/ntb/ntb_hw_amd.c
index ab78675218..dba5b03671 100644
--- a/drivers/raw/ntb/ntb_hw_amd.c
+++ b/drivers/raw/ntb/ntb_hw_amd.c
@@ -502,7 +502,7 @@ static int
 amd_ntb_read_peer_config(const struct rte_rawdev *dev)
 {
 	struct ntb_hw *ntb = dev->dev_private;
-	uint32_t info, peer_qps, peer_qsz, lo, hi;
+	uint32_t info, peer_qps, peer_qsz, peer_used_mws, lo, hi;
 	int i;
 
 	info = amd_ntb_spad_read(dev, AMD_SPAD_CNT_INFO, 0);
@@ -520,7 +520,13 @@ amd_ntb_read_peer_config(const struct rte_rawdev *dev)
 		return -EINVAL;
 	}
 
-	ntb->peer_used_mws = (info >> 16) & 0xff;
+	peer_used_mws = (info >> 16) & 0xff;
+	if (peer_used_mws > ntb->mw_cnt) {
+		NTB_LOG(ERR, "Peer used mws %u > mw cnt %u.", peer_used_mws, ntb->mw_cnt);
+		return -EINVAL;
+	}
+	ntb->peer_used_mws = peer_used_mws;
+
 	for (i = 0; i < ntb->peer_used_mws; i++) {
 		lo = amd_ntb_spad_read(dev, AMD_SPAD_MW0_BA_L + 2 * i, 0);
 		hi = amd_ntb_spad_read(dev, AMD_SPAD_MW0_BA_H + 2 * i, 0);
diff --git a/drivers/raw/ntb/ntb_hw_intel.c b/drivers/raw/ntb/ntb_hw_intel.c
index 1b784055ca..78fce9ffac 100644
--- a/drivers/raw/ntb/ntb_hw_intel.c
+++ b/drivers/raw/ntb/ntb_hw_intel.c
@@ -724,7 +724,12 @@ intel_ntb_read_peer_config(const struct rte_rawdev *dev)
 		return -EINVAL;
 	}
 
-	hw->peer_used_mws = intel_ntb_spad_read(dev, SPAD_USED_MWS, 0);
+	peer_val = intel_ntb_spad_read(dev, SPAD_USED_MWS, 0);
+	if (peer_val > hw->mw_cnt) {
+		NTB_LOG(ERR, "Peer used mws %u > mw cnt %u.", peer_val, hw->mw_cnt);
+		return -EINVAL;
+	}
+	hw->peer_used_mws = peer_val;
 
 	for (i = 0; i < hw->peer_used_mws; i++) {
 		peer_base_h = intel_ntb_spad_read(dev, SPAD_MW0_BA_H + 2 * i, 0);
-- 
2.34.1


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

* [PATCH v3 03/16] raw/ntb: fix memory window bound in address remapping
  2026-11-11  7:06   ` [PATCH v3 00/16] " Raghavendra Ningoji
  2026-11-11  7:06     ` [PATCH v3 01/16] raw/ntb: fix device check in memory alignment query Raghavendra Ningoji
  2026-11-11  7:06     ` [PATCH v3 02/16] raw/ntb: fix peer memory window count check Raghavendra Ningoji
@ 2026-11-11  7:06     ` Raghavendra Ningoji
  2026-11-11  7:06     ` [PATCH v3 04/16] raw/ntb: fix memory leaks Raghavendra Ningoji
                       ` (13 subsequent siblings)
  16 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-11  7:06 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson, stable

When translating a peer address into the local mapping of a memory
window, the end of the window was included in the accepted range,
so an address one byte past the window was mapped.

Exclude the end of the window.

Fixes: 11b5c7daf019 ("raw/ntb: add enqueue and dequeue functions")
Fixes: d6dc5a7f8b06 ("raw/ntb: support AMD NTB")
Cc: stable@dpdk.org

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb_hw_amd.c   | 2 +-
 drivers/raw/ntb/ntb_hw_intel.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/raw/ntb/ntb_hw_amd.c b/drivers/raw/ntb/ntb_hw_amd.c
index dba5b03671..64075501c2 100644
--- a/drivers/raw/ntb/ntb_hw_amd.c
+++ b/drivers/raw/ntb/ntb_hw_amd.c
@@ -166,7 +166,7 @@ amd_ntb_ioremap(const struct rte_rawdev *dev, uint64_t addr)
 
 	for (i = 0; i < ntb->peer_used_mws; i++) {
 		if (addr >= ntb->peer_mw_base[i] &&
-				addr <= ntb->peer_mw_base[i] + ntb->mw_size[i]) {
+				addr < ntb->peer_mw_base[i] + ntb->mw_size[i]) {
 			base = amd_ntb_get_peer_mw_addr(dev, i);
 			mapped = (void *)(size_t)(addr - ntb->peer_mw_base[i] + (size_t)base);
 			break;
diff --git a/drivers/raw/ntb/ntb_hw_intel.c b/drivers/raw/ntb/ntb_hw_intel.c
index 78fce9ffac..47d5d39339 100644
--- a/drivers/raw/ntb/ntb_hw_intel.c
+++ b/drivers/raw/ntb/ntb_hw_intel.c
@@ -312,7 +312,7 @@ intel_ntb_ioremap(const struct rte_rawdev *dev, uint64_t addr)
 
 	for (i = 0; i < hw->peer_used_mws; i++) {
 		if (addr >= hw->peer_mw_base[i] &&
-		    addr <= hw->peer_mw_base[i] + hw->mw_size[i]) {
+		    addr < hw->peer_mw_base[i] + hw->mw_size[i]) {
 			base = intel_ntb_get_peer_mw_addr(dev, i);
 			mapped = (void *)(size_t)(addr - hw->peer_mw_base[i] +
 				 (size_t)base);
-- 
2.34.1


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

* [PATCH v3 04/16] raw/ntb: fix memory leaks
  2026-11-11  7:06   ` [PATCH v3 00/16] " Raghavendra Ningoji
                       ` (2 preceding siblings ...)
  2026-11-11  7:06     ` [PATCH v3 03/16] raw/ntb: fix memory window bound in address remapping Raghavendra Ningoji
@ 2026-11-11  7:06     ` Raghavendra Ningoji
  2026-11-11  7:06     ` [PATCH v3 05/16] raw/ntb: fix doorbell interrupts with VFIO MSI-X Raghavendra Ningoji
                       ` (12 subsequent siblings)
  16 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-11  7:06 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson, stable

The memory window size array allocated by the vendor init at probe
time was never freed.
The peer memory window base array allocated at each device start was
only freed if the start failed, so it leaked on every stop/start cycle.

As the number of memory windows is fixed for all supported devices,
embed the memory window size array in the device private data instead
of allocating it: it lives as long as the device and remains valid for
the info get after close.
Free the peer memory window base array when stopping the device.

Fixes: c39d1e082a4b ("raw/ntb: setup queues")
Fixes: d6dc5a7f8b06 ("raw/ntb: support AMD NTB")
Cc: stable@dpdk.org

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb.c          | 6 ++++++
 drivers/raw/ntb/ntb.h          | 5 ++++-
 drivers/raw/ntb/ntb_hw_amd.c   | 6 +-----
 drivers/raw/ntb/ntb_hw_intel.c | 8 +-------
 4 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index e42af0b9c5..5985604cce 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -820,6 +820,8 @@ ntb_dev_start(struct rte_rawdev *dev)
 
 err_up:
 	rte_free(hw->peer_mw_base);
+	hw->peer_mw_base = NULL;
+	hw->peer_used_mws = 0;
 err_q_init:
 	for (i = 0; i < hw->queue_pairs; i++) {
 		ntb_rxq_release_mbufs(hw->rx_queues[i]);
@@ -872,6 +874,10 @@ ntb_dev_stop(struct rte_rawdev *dev)
 		ntb_txq_release_mbufs(hw->tx_queues[i]);
 	}
 
+	rte_free(hw->peer_mw_base);
+	hw->peer_mw_base = NULL;
+	hw->peer_used_mws = 0;
+
 	dev->started = 0;
 }
 
diff --git a/drivers/raw/ntb/ntb.h b/drivers/raw/ntb/ntb.h
index 0181bec5c9..31bf0f3260 100644
--- a/drivers/raw/ntb/ntb.h
+++ b/drivers/raw/ntb/ntb.h
@@ -17,6 +17,9 @@ extern int ntb_logtype;
 #define NTB_SPAD_USER               "spad_user_"
 #define NTB_SPAD_USER_LEN           (sizeof(NTB_SPAD_USER) - 1)
 #define NTB_SPAD_USER_MAX_NUM       4
+
+/* Maximum number of memory windows of supported devices. */
+#define NTB_MAX_MW                  2
 #define NTB_ATTR_NAME_LEN           30
 
 #define NTB_DFLT_TX_FREE_THRESH     256
@@ -220,7 +223,7 @@ struct ntb_hw {
 	char *hw_addr;
 
 	uint8_t peer_dev_up;
-	uint64_t *mw_size;
+	uint64_t mw_size[NTB_MAX_MW];
 	/* remote mem base addr */
 	uint64_t *peer_mw_base;
 
diff --git a/drivers/raw/ntb/ntb_hw_amd.c b/drivers/raw/ntb/ntb_hw_amd.c
index 64075501c2..9b274bc6b9 100644
--- a/drivers/raw/ntb/ntb_hw_amd.c
+++ b/drivers/raw/ntb/ntb_hw_amd.c
@@ -53,6 +53,7 @@ amd_ntb_dev_init(const struct rte_rawdev *dev)
 	NTB_LOG(INFO, "Device topology: %s (sideinfo 0x%" PRIx32 ")",
 		ntb->topo == NTB_TOPO_SEC ? "secondary" : "primary", sideinfo);
 
+	RTE_BUILD_BUG_ON(AMD_MW_COUNT > NTB_MAX_MW);
 	ntb->mw_cnt = AMD_MW_COUNT;
 	ntb->db_cnt = AMD_DB_COUNT;
 	/* The 16-register scratchpad bank is split into two halves, so only
@@ -60,11 +61,6 @@ amd_ntb_dev_init(const struct rte_rawdev *dev)
 	 */
 	ntb->spad_cnt = AMD_SPAD_PER_SIDE;
 
-	ntb->mw_size = rte_zmalloc("ntb_mw_size", ntb->mw_cnt * sizeof(uint64_t), 0);
-	if (ntb->mw_size == NULL) {
-		NTB_LOG(ERR, "Cannot allocate memory for mw size.");
-		return -ENOMEM;
-	}
 	for (i = 0; i < ntb->mw_cnt; i++) {
 		bar = amd_ntb_bar[i];
 		ntb->mw_size[i] = ntb->pci_dev->mem_resource[bar].len;
diff --git a/drivers/raw/ntb/ntb_hw_intel.c b/drivers/raw/ntb/ntb_hw_intel.c
index 47d5d39339..ad8e330199 100644
--- a/drivers/raw/ntb/ntb_hw_intel.c
+++ b/drivers/raw/ntb/ntb_hw_intel.c
@@ -194,17 +194,11 @@ intel_ntb_dev_init(const struct rte_rawdev *dev)
 	if (ret)
 		return ret;
 
+	RTE_BUILD_BUG_ON(XEON_MW_COUNT > NTB_MAX_MW);
 	hw->mw_cnt = XEON_MW_COUNT;
 	hw->db_cnt = XEON_DB_COUNT;
 	hw->spad_cnt = XEON_SPAD_COUNT;
 
-	hw->mw_size = rte_zmalloc("ntb_mw_size",
-				  hw->mw_cnt * sizeof(uint64_t), 0);
-	if (hw->mw_size == NULL) {
-		NTB_LOG(ERR, "Cannot allocate memory for mw size.");
-		return -ENOMEM;
-	}
-
 	for (i = 0; i < hw->mw_cnt; i++) {
 		bar = intel_ntb_bar[i];
 		hw->mw_size[i] = hw->pci_dev->mem_resource[bar].len;
-- 
2.34.1


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

* [PATCH v3 05/16] raw/ntb: fix doorbell interrupts with VFIO MSI-X
  2026-11-11  7:06   ` [PATCH v3 00/16] " Raghavendra Ningoji
                       ` (3 preceding siblings ...)
  2026-11-11  7:06     ` [PATCH v3 04/16] raw/ntb: fix memory leaks Raghavendra Ningoji
@ 2026-11-11  7:06     ` Raghavendra Ningoji
  2026-11-11  7:06     ` [PATCH v3 06/16] raw/ntb: fix AMD processor names Raghavendra Ningoji
                       ` (11 subsequent siblings)
  16 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-11  7:06 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson, stable

With VFIO MSI-X, each doorbell raises its own vector. Vector 0 is
signalled on the PCI device interrupt handle while the others are
signalled on the eventfds created by rte_intr_efd_enable(), but the
interrupt handler was only registered on the device interrupt handle.

As a result, doorbells other than DB0 were only noticed when DB0 fired
at the same time. In particular, the DB1 rung by the peer in its
dev_stop was never handled, the peer never got the DB2 answer and had
to wait for the 1s timeout.

Register the interrupt handler on each doorbell eventfd as well.

Fixes: 62012a76811e ("raw/ntb: add handshake process")
Cc: stable@dpdk.org

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb.c | 77 ++++++++++++++++++++++++++++++++++++++++++-
 drivers/raw/ntb/ntb.h |  4 +++
 2 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index 5985604cce..bde17c3c86 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -3,6 +3,7 @@
  */
 #include <stdint.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <errno.h>
 
@@ -11,6 +12,7 @@
 #include <rte_lcore.h>
 #include <rte_cycles.h>
 #include <rte_eal.h>
+#include <rte_errno.h>
 #include <rte_log.h>
 #include <rte_pci.h>
 #include <rte_mbuf.h>
@@ -124,6 +126,73 @@ ntb_dev_intr_handler(void *param)
 		(*hw->ntb_ops->handle_hw_event)(dev);
 }
 
+static void
+ntb_db_intr_unregister(struct rte_rawdev *dev)
+{
+	struct ntb_hw *hw = dev->dev_private;
+	struct rte_intr_handle *handle;
+	uint16_t i;
+
+	for (i = 0; i < hw->nb_db_intr_handles; i++) {
+		handle = hw->db_intr_handles[i];
+		rte_intr_callback_unregister_sync(handle,
+						  ntb_dev_intr_handler, dev);
+		/* The eventfd is owned by the PCI device interrupt handle. */
+		rte_intr_fd_set(handle, -1);
+		rte_intr_instance_free(handle);
+	}
+	free(hw->db_intr_handles);
+	hw->db_intr_handles = NULL;
+	hw->nb_db_intr_handles = 0;
+}
+
+/*
+ * With MSI-X, only vector 0 is serviced through the PCI device interrupt
+ * handle. Each other doorbell raises its own vector, signalled on the
+ * eventfds created by rte_intr_efd_enable(): register the handler on them.
+ */
+static int
+ntb_db_intr_register(struct rte_rawdev *dev,
+		     struct rte_intr_handle *intr_handle)
+{
+	struct ntb_hw *hw = dev->dev_private;
+	int nb_efd = rte_intr_nb_efd_get(intr_handle);
+	struct rte_intr_handle *handle;
+	int i, ret;
+
+	hw->db_intr_handles = calloc(nb_efd, sizeof(*hw->db_intr_handles));
+	if (hw->db_intr_handles == NULL)
+		return -ENOMEM;
+
+	for (i = 0; i < nb_efd; i++) {
+		handle = rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_PRIVATE);
+		if (handle == NULL) {
+			ret = -ENOMEM;
+			goto err;
+		}
+		hw->db_intr_handles[hw->nb_db_intr_handles++] = handle;
+
+		if (rte_intr_type_set(handle, RTE_INTR_HANDLE_VFIO_MSIX) ||
+		    rte_intr_fd_set(handle,
+				    rte_intr_efds_index_get(intr_handle, i))) {
+			ret = -rte_errno;
+			goto err;
+		}
+
+		ret = rte_intr_callback_register(handle,
+						 ntb_dev_intr_handler, dev);
+		if (ret)
+			goto err;
+	}
+
+	return 0;
+
+err:
+	NTB_LOG(ERR, "Failed to register doorbell interrupt %d.", i + 1);
+	ntb_db_intr_unregister(dev);
+	return ret;
+}
+
 static int
 ntb_queue_conf_get(struct rte_rawdev *dev,
 		   uint16_t queue_id,
@@ -902,6 +971,8 @@ ntb_dev_close(struct rte_rawdev *dev)
 	    !rte_intr_max_intr_get(intr_handle))
 		return 0;
 
+	ntb_db_intr_unregister(dev);
+
 	/* Clean datapath event and vec mapping */
 	rte_intr_efd_disable(intr_handle);
 	rte_intr_vec_list_free(intr_handle);
@@ -1305,7 +1376,11 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
 	 * by default for intel gen3. They are mapped to msix vec 1-32,
 	 * and hardware intr is mapped to 0. Map all to 0 for uio.
 	 */
-	if (!rte_intr_cap_multiple(intr_handle)) {
+	if (rte_intr_cap_multiple(intr_handle)) {
+		ret = ntb_db_intr_register(dev, intr_handle);
+		if (ret)
+			return ret;
+	} else {
 		for (i = 0; i < hw->db_cnt; i++) {
 			ret = (*hw->ntb_ops->vector_bind)(dev, i, 0);
 			if (ret)
diff --git a/drivers/raw/ntb/ntb.h b/drivers/raw/ntb/ntb.h
index 31bf0f3260..f867f0323d 100644
--- a/drivers/raw/ntb/ntb.h
+++ b/drivers/raw/ntb/ntb.h
@@ -222,6 +222,10 @@ struct ntb_hw {
 	struct rte_pci_device *pci_dev;
 	char *hw_addr;
 
+	/* Interrupt handles for the MSI-X doorbell vectors besides vector 0. */
+	struct rte_intr_handle **db_intr_handles;
+	uint16_t nb_db_intr_handles;
+
 	uint8_t peer_dev_up;
 	uint64_t mw_size[NTB_MAX_MW];
 	/* remote mem base addr */
-- 
2.34.1


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

* [PATCH v3 06/16] raw/ntb: fix AMD processor names
  2026-11-11  7:06   ` [PATCH v3 00/16] " Raghavendra Ningoji
                       ` (4 preceding siblings ...)
  2026-11-11  7:06     ` [PATCH v3 05/16] raw/ntb: fix doorbell interrupts with VFIO MSI-X Raghavendra Ningoji
@ 2026-11-11  7:06     ` Raghavendra Ningoji
  2026-11-11  7:06     ` [PATCH v3 07/16] raw/ntb: remove AMD hardware event handling Raghavendra Ningoji
                       ` (10 subsequent siblings)
  16 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-11  7:06 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson

Refer to the AMD processors integrating the NTB endpoints by their
EPYC Embedded 9004/9005/8004 series numbers rather than code names.

Fixes: d6dc5a7f8b06 ("raw/ntb: support AMD NTB")

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 doc/guides/rawdevs/ntb.rst             | 4 ++--
 doc/guides/rel_notes/release_26_11.rst | 4 ++--
 drivers/raw/ntb/ntb_hw_amd.h           | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/doc/guides/rawdevs/ntb.rst b/doc/guides/rawdevs/ntb.rst
index 99474745d6..37328cd9e6 100644
--- a/doc/guides/rawdevs/ntb.rst
+++ b/doc/guides/rawdevs/ntb.rst
@@ -41,7 +41,7 @@ AMD EPYC Embedded NTB
 ---------------------
 
 The driver also supports the NTB endpoints integrated in AMD EPYC Embedded
-"Turin", "Genoa" and "Siena" processors.
+9004/9005/8004 processors.
 These use a primary/secondary topology rather than the Intel back-to-back topology:
 one endpoint is enumerated as the primary (device ID ``0x14c0``) and
 the other as the secondary (device ID ``0x14c3``).
@@ -179,7 +179,7 @@ Limitation
 
 This PMD is supported on:
 
-- AMD EPYC Embedded "Turin", "Genoa" and "Siena" processors.
+- AMD EPYC Embedded 9004/9005/8004 processors.
 - 4th Generation Intel® Xeon® Scalable Processors.
 - 3rd Generation Intel® Xeon® Scalable Processors.
 - 2nd Generation Intel® Xeon® Scalable Processors.
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index 79994bb93a..06133409e1 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -311,8 +311,8 @@ New Features
 
 * **Added AMD NTB support to the NTB rawdev driver.**
 
-  Added support for the NTB endpoints integrated in AMD EPYC Embedded "Turin", "Genoa"
-  and "Siena" processors to the ``raw/ntb`` driver.
+  Added support for the NTB endpoints integrated in AMD EPYC Embedded
+  9004/9005/8004 processors to the ``raw/ntb`` driver.
   The NTB rawdev framework was generalized to support multiple vendors,
   with AMD-specific hardware access, a primary/secondary topology
   and a packed scratchpad handshake.
diff --git a/drivers/raw/ntb/ntb_hw_amd.h b/drivers/raw/ntb/ntb_hw_amd.h
index 48f0db1ad4..b03aed7d08 100644
--- a/drivers/raw/ntb/ntb_hw_amd.h
+++ b/drivers/raw/ntb/ntb_hw_amd.h
@@ -7,7 +7,7 @@
 
 #include <stdint.h>
 
-/* NTB vendor and device IDs (EPYC Embedded Turin/Genoa/Siena). */
+/* NTB vendor and device IDs (EPYC Embedded 9004/9005/8004). */
 #define NTB_AMD_VENDOR_ID		0x1022
 #define NTB_AMD_DEV_ID_PRI		0x14c0	/* Primary NTB endpoint. */
 #define NTB_AMD_DEV_ID_SEC		0x14c3	/* Secondary NTB endpoint. */
-- 
2.34.1


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

* [PATCH v3 07/16] raw/ntb: remove AMD hardware event handling
  2026-11-11  7:06   ` [PATCH v3 00/16] " Raghavendra Ningoji
                       ` (5 preceding siblings ...)
  2026-11-11  7:06     ` [PATCH v3 06/16] raw/ntb: fix AMD processor names Raghavendra Ningoji
@ 2026-11-11  7:06     ` Raghavendra Ningoji
  2026-11-11  7:06     ` [PATCH v3 08/16] raw/ntb: fix Rx of incomplete packets Raghavendra Ningoji
                       ` (9 subsequent siblings)
  16 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-11  7:06 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson

The AMD hardware event handler could never run: the event interrupts
were never unmasked, their MSI-X vectors were never enabled and the
handler was only reached when no known doorbell was pending.
It also mishandled several simultaneous events and never cleared
the interrupt status.

Remove it, together with the now unused vendor operation and
register definitions, and document that hardware events are not
handled.

Fixes: d6dc5a7f8b06 ("raw/ntb: support AMD NTB")

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 doc/guides/rawdevs/ntb.rst   |  4 ++++
 drivers/raw/ntb/ntb.c        |  4 ----
 drivers/raw/ntb/ntb.h        |  3 ---
 drivers/raw/ntb/ntb_hw_amd.c | 42 +-----------------------------------
 drivers/raw/ntb/ntb_hw_amd.h | 21 ------------------
 5 files changed, 5 insertions(+), 69 deletions(-)

diff --git a/doc/guides/rawdevs/ntb.rst b/doc/guides/rawdevs/ntb.rst
index 37328cd9e6..c4ad2f05c4 100644
--- a/doc/guides/rawdevs/ntb.rst
+++ b/doc/guides/rawdevs/ntb.rst
@@ -53,6 +53,10 @@ The AMD NTB hardware exposes two memory windows (BAR23 and BAR45),
 The scratchpad bank is split into two disjoint 8-register sets, one owned by each side,
 so the driver uses a packed handshake layout that fits within 8 registers.
 
+The AMD NTB hardware events (link up/down, peer reset, power state changes)
+are not handled: a peer going away is only detected through the doorbell
+handshake done when the peer device is stopped.
+
 The AMD NTB uses an outbound translation window:
 a write to a memory window offset is forwarded to ``(base | offset)`` in the peer's memory
 rather than ``(base + offset)``.
diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index bde17c3c86..bface8d497 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -120,10 +120,6 @@ ntb_dev_intr_handler(void *param)
 
 	/* Clear other received doorbells. */
 	(*hw->ntb_ops->db_clear)(dev, db_bits);
-
-	/* Let the vendor process any hardware-specific events. */
-	if (hw->ntb_ops->handle_hw_event != NULL)
-		(*hw->ntb_ops->handle_hw_event)(dev);
 }
 
 static void
diff --git a/drivers/raw/ntb/ntb.h b/drivers/raw/ntb/ntb.h
index f867f0323d..f9f5bceede 100644
--- a/drivers/raw/ntb/ntb.h
+++ b/drivers/raw/ntb/ntb.h
@@ -105,8 +105,6 @@ enum ntb_spad_idx {
  * @link_cleanup: Tear down the local scratchpad/translation state so the
  * peer can no longer reach local memory.
  * @mem_align: Base-address alignment required for a memory window memzone of a given length.
- * @handle_hw_event: Optional. Process vendor-specific hardware events from
- * the common interrupt handler. May be NULL.
  */
 struct ntb_dev_ops {
 	int (*ntb_dev_init)(const struct rte_rawdev *dev);
@@ -129,7 +127,6 @@ struct ntb_dev_ops {
 	int (*read_peer_config)(const struct rte_rawdev *dev);
 	void (*link_cleanup)(const struct rte_rawdev *dev);
 	uint64_t (*mem_align)(const struct rte_rawdev *dev, uint32_t mw_id, uint64_t mw_len);
-	void (*handle_hw_event)(const struct rte_rawdev *dev);
 };
 
 struct ntb_desc {
diff --git a/drivers/raw/ntb/ntb_hw_amd.c b/drivers/raw/ntb/ntb_hw_amd.c
index 9b274bc6b9..abb923b384 100644
--- a/drivers/raw/ntb/ntb_hw_amd.c
+++ b/drivers/raw/ntb/ntb_hw_amd.c
@@ -441,7 +441,7 @@ static int
 amd_ntb_vector_bind(const struct rte_rawdev *dev __rte_unused, uint8_t intr __rte_unused,
 		uint8_t msix __rte_unused)
 {
-	/* Each doorbell/event maps to its MSI-X vector by default. */
+	/* Each doorbell maps to its MSI-X vector by default. */
 	return 0;
 }
 
@@ -565,45 +565,6 @@ amd_ntb_link_cleanup(const struct rte_rawdev *dev)
 		amd_ntb_mw_set_trans(dev, i, 0, 0);
 }
 
-/* Handle link/power-management events and acknowledge the SMU. Invoked from
- * the common interrupt handler when no inter-device doorbell is pending.
- */
-static void
-amd_ntb_handle_hw_event(const struct rte_rawdev *dev)
-{
-	struct ntb_hw *ntb = dev->dev_private;
-	uint32_t event, ack;
-
-	event = rte_read32((char *)ntb->hw_addr + AMD_INTSTAT_OFFSET);
-	event &= AMD_EVENT_INTMASK;
-	if (event == 0)
-		return;
-
-	switch (event) {
-	case AMD_PEER_FLUSH_EVENT:
-		NTB_LOG(INFO, "Peer flush event.");
-		break;
-	case AMD_PEER_D0_EVENT:
-		ack = rte_read32((char *)ntb->hw_addr + AMD_PMESTAT_OFFSET);
-		if (ack & 0x1)
-			NTB_LOG(INFO, "D0 wakeup completed for NTB.");
-		/* fall through to ack the SMU */
-		/* Falls through. */
-	case AMD_PEER_RESET_EVENT:
-	case AMD_LINK_DOWN_EVENT:
-	case AMD_PEER_D3_EVENT:
-	case AMD_PEER_PMETO_EVENT:
-	case AMD_LINK_UP_EVENT:
-		ack = rte_read32((char *)ntb->hw_addr + AMD_SMUACK_OFFSET);
-		ack |= event;
-		rte_write32(ack, (char *)ntb->hw_addr + AMD_SMUACK_OFFSET);
-		break;
-	default:
-		NTB_LOG(ERR, "Unknown interrupt event 0x%" PRIx32, event);
-		break;
-	}
-}
-
 static uint64_t
 amd_ntb_get_mem_align(const struct rte_rawdev *dev __rte_unused, uint32_t mw_id __rte_unused,
 		uint64_t mw_len)
@@ -630,5 +591,4 @@ const struct ntb_dev_ops amd_ntb_ops = {
 	.read_peer_config	= amd_ntb_read_peer_config,
 	.link_cleanup		= amd_ntb_link_cleanup,
 	.mem_align		= amd_ntb_get_mem_align,
-	.handle_hw_event	= amd_ntb_handle_hw_event,
 };
diff --git a/drivers/raw/ntb/ntb_hw_amd.h b/drivers/raw/ntb/ntb_hw_amd.h
index b03aed7d08..8fffa24348 100644
--- a/drivers/raw/ntb/ntb_hw_amd.h
+++ b/drivers/raw/ntb/ntb_hw_amd.h
@@ -16,7 +16,6 @@
 #define AMD_MW_COUNT			2
 #define AMD_DB_COUNT			16
 #define AMD_SPAD_COUNT			16
-#define AMD_MSIX_VECTOR_COUNT		24
 
 /* Peer register window: peer register = primary offset + 0x400. */
 #define AMD_PEER_OFFSET			0x400
@@ -37,10 +36,6 @@
 #define AMD_DBREQ_OFFSET		0x454	/* Doorbell request. */
 #define AMD_DBMASK_OFFSET		0x45C	/* Doorbell mask. */
 #define AMD_DBSTAT_OFFSET		0x460	/* Doorbell status. */
-#define AMD_INTMASK_OFFSET		0x470	/* Interrupt mask. */
-#define AMD_INTSTAT_OFFSET		0x474	/* Interrupt status. */
-#define AMD_PMESTAT_OFFSET		0x480	/* PME status. */
-#define AMD_SMUACK_OFFSET		0x4A0	/* SMU control (PSMU_ACK). */
 
 /* Link Status Register (0x408) bits, spec Table 5. */
 #define AMD_SIDE_MASK			(1 << 0) /* 0: primary, 1: secondary. */
@@ -50,22 +45,6 @@
 #define AMD_SMM_REG_CTL			(1 << 20)
 #define AMD_PMM_REG_CTL			(1 << 21)
 
-/* Interrupt Status/Mask event bits, spec Table 7. */
-#define AMD_PEER_FLUSH_EVENT		(1 << 0)
-#define AMD_PEER_RESET_EVENT		(1 << 1)
-#define AMD_PEER_D3_EVENT		(1 << 2)
-#define AMD_PEER_PMETO_EVENT		(1 << 3)
-#define AMD_PEER_D0_EVENT		(1 << 4)
-#define AMD_LINK_UP_EVENT		(1 << 5)
-#define AMD_LINK_DOWN_EVENT		(1 << 6)
-#define AMD_EVENT_INTMASK		(AMD_PEER_FLUSH_EVENT | \
-					 AMD_PEER_RESET_EVENT | \
-					 AMD_PEER_D3_EVENT | \
-					 AMD_PEER_PMETO_EVENT | \
-					 AMD_PEER_D0_EVENT | \
-					 AMD_LINK_UP_EVENT | \
-					 AMD_LINK_DOWN_EVENT)
-
 /* PCIe link status decoding (link speed/width). */
 #define AMD_LNK_STA_SPEED_MASK		0x000f
 #define AMD_LNK_STA_WIDTH_MASK		0x03f0
-- 
2.34.1


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

* [PATCH v3 08/16] raw/ntb: fix Rx of incomplete packets
  2026-11-11  7:06   ` [PATCH v3 00/16] " Raghavendra Ningoji
                       ` (6 preceding siblings ...)
  2026-11-11  7:06     ` [PATCH v3 07/16] raw/ntb: remove AMD hardware event handling Raghavendra Ningoji
@ 2026-11-11  7:06     ` Raghavendra Ningoji
  2026-11-11  7:06     ` [PATCH v3 09/16] raw/ntb: fix double free of Rx mbufs on stop Raghavendra Ningoji
                       ` (8 subsequent siblings)
  16 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-11  7:06 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson, stable

When a packet had no EOP descriptor among the ones walked, or when a
refill mbuf could not be allocated in the middle of a packet, the Rx
burst stopped with the packet partially consumed: the ring indexes had
moved, but the mbuf chain was neither returned nor freed, and the
refilled descriptors were not published to the peer if no packet had
been completed before.

The EOP guard also bounded the walk on the ring size rather than on
the descriptors actually published by the peer.

Only take a packet once all of its descriptors have been published,
and allocate its refill mbufs before consuming it, so that the ring
indexes are only advanced for complete packets.

Fixes: 11b5c7daf019 ("raw/ntb: add enqueue and dequeue functions")
Fixes: 5ce50c234ad1 ("raw/ntb: generalize framework for multiple vendors")
Cc: stable@dpdk.org

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb.c | 39 +++++++++++++++++++++------------------
 1 file changed, 21 insertions(+), 18 deletions(-)

diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index bface8d497..eb562052d8 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -650,13 +650,14 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
 	struct ntb_rx_queue *rxq = hw->rx_queues[(size_t)context];
 	struct ntb_rx_entry *sw_ring = rxq->sw_ring;
 	struct ntb_desc rx_desc[NTB_MAX_DESC_SIZE];
-	struct rte_mbuf *first, *rxm_t;
+	struct rte_mbuf *new_mbufs[NTB_MAX_DESC_SIZE];
+	struct rte_mbuf *first = NULL, *rxm_t;
 	struct rte_mbuf *prev = NULL;
 	volatile struct ntb_used *rx_item;
 	uint16_t nb_mbufs = 0;
 	uint16_t nb_rx = 0;
 	uint64_t bytes = 0;
-	uint16_t off, last_avail, used_cnt, used_nb;
+	uint16_t off, last_avail, used_cnt, used_nb, nb_segs;
 	int i;
 
 	if (unlikely(dev->started == 0 || hw->peer_dev_up == 0)) {
@@ -673,13 +674,24 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
 	used_nb = (used_cnt - rxq->last_used) & (rxq->nb_rx_desc - 1);
 	count = RTE_MIN(count, used_nb);
 	for (nb_rx = 0; nb_rx < count; nb_rx++) {
-		i = 0;
-		while (true) {
-			if (unlikely(nb_mbufs >= rxq->nb_rx_desc)) {
-				NTB_LOG(ERR, "Malformed rx stream (no EOP); "
-					"aborting to avoid desc overflow.");
+		/* Only take a packet once the peer has published all of it. */
+		for (nb_segs = 1; ; nb_segs++) {
+			if (nb_segs > used_nb)
 				goto end_of_rx;
-			}
+			rx_item = rxq->rx_used_ring + ((rxq->last_used + nb_segs - 1) &
+						       (rxq->nb_rx_desc - 1));
+			if (rx_item->flags & NTB_FLAG_EOP)
+				break;
+		}
+
+		/* Get the refill mbufs first so a packet is never partially consumed. */
+		if (unlikely(rte_mbuf_raw_alloc_bulk(rxq->mpool, new_mbufs, nb_segs))) {
+			NTB_LOG(ERR, "recv alloc mbuf failed.");
+			goto end_of_rx;
+		}
+		used_nb -= nb_segs;
+
+		for (i = 0; i < nb_segs; i++) {
 			rx_item = rxq->rx_used_ring + rxq->last_used;
 			rxm_t = sw_ring[rxq->last_used].mbuf;
 			rxm_t->data_len = rx_item->len;
@@ -701,15 +713,9 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
 			rxq->last_used = (rxq->last_used + 1) &
 					 (rxq->nb_rx_desc - 1);
 
-			/* alloc new mbuf */
-			rxm_t = rte_mbuf_raw_alloc(rxq->mpool);
-			if (unlikely(rxm_t == NULL)) {
-				NTB_LOG(ERR, "recv alloc mbuf failed.");
-				goto end_of_rx;
-			}
+			rxm_t = new_mbufs[i];
 			rxm_t->port = rxq->port_id;
 			sw_ring[rxq->last_avail].mbuf = rxm_t;
-			i++;
 
 			/* fill new desc */
 			rx_desc[nb_mbufs].addr =
@@ -718,9 +724,6 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
 						  RTE_PKTMBUF_HEADROOM;
 			rxq->last_avail = (rxq->last_avail + 1) &
 					  (rxq->nb_rx_desc - 1);
-
-			if (rx_item->flags & NTB_FLAG_EOP)
-				break;
 		}
 		/* update stats */
 		bytes += first->pkt_len;
-- 
2.34.1


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

* [PATCH v3 09/16] raw/ntb: fix double free of Rx mbufs on stop
  2026-11-11  7:06   ` [PATCH v3 00/16] " Raghavendra Ningoji
                       ` (7 preceding siblings ...)
  2026-11-11  7:06     ` [PATCH v3 08/16] raw/ntb: fix Rx of incomplete packets Raghavendra Ningoji
@ 2026-11-11  7:06     ` Raghavendra Ningoji
  2026-11-11  7:06     ` [PATCH v3 10/16] examples/ntb: fix raw/ntb library linking Raghavendra Ningoji
                       ` (7 subsequent siblings)
  16 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-11  7:06 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson, stable

Once an Rx mbuf is handed to the application, its software ring entry
still references it until the slot is refilled. On device stop, all
referenced mbufs are freed, including the one now owned by the
application.

Clear the ring entry when the mbuf is taken.

Fixes: 11b5c7daf019 ("raw/ntb: add enqueue and dequeue functions")
Cc: stable@dpdk.org

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index eb562052d8..5b3abcb008 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -694,6 +694,7 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
 		for (i = 0; i < nb_segs; i++) {
 			rx_item = rxq->rx_used_ring + rxq->last_used;
 			rxm_t = sw_ring[rxq->last_used].mbuf;
+			sw_ring[rxq->last_used].mbuf = NULL;
 			rxm_t->data_len = rx_item->len;
 			rxm_t->data_off = RTE_PKTMBUF_HEADROOM;
 			rxm_t->port = rxq->port_id;
-- 
2.34.1


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

* [PATCH v3 10/16] examples/ntb: fix raw/ntb library linking
  2026-11-11  7:06   ` [PATCH v3 00/16] " Raghavendra Ningoji
                       ` (8 preceding siblings ...)
  2026-11-11  7:06     ` [PATCH v3 09/16] raw/ntb: fix double free of Rx mbufs on stop Raghavendra Ningoji
@ 2026-11-11  7:06     ` Raghavendra Ningoji
  2026-11-11  7:06     ` [PATCH v3 11/16] doc: add NTB device info change to ABI section Raghavendra Ningoji
                       ` (6 subsequent siblings)
  16 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-11  7:06 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson

The raw/ntb driver library was added to the linker flags of both the
shared and static targets. For static linking, it is already part of
the libdpdk pkg-config output, so only add it to the shared target,
as done in other examples.

Fixes: 5ce50c234ad1 ("raw/ntb: generalize framework for multiple vendors")

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 examples/ntb/Makefile | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/examples/ntb/Makefile b/examples/ntb/Makefile
index 6c0307c697..a074251646 100644
--- a/examples/ntb/Makefile
+++ b/examples/ntb/Makefile
@@ -23,11 +23,12 @@ static: build/$(APP)-static
 	ln -sf $(APP)-static build/$(APP)
 
 CFLAGS += -D_FILE_OFFSET_BITS=64
-LDFLAGS += -pthread -lrte_raw_ntb
+LDFLAGS += -pthread
 
 PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null)
 CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) -I build/
 LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk)
+LDFLAGS_SHARED += -lrte_raw_ntb
 LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk)
 
 build/commands.h: commands.list Makefile
-- 
2.34.1


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

* [PATCH v3 11/16] doc: add NTB device info change to ABI section
  2026-11-11  7:06   ` [PATCH v3 00/16] " Raghavendra Ningoji
                       ` (9 preceding siblings ...)
  2026-11-11  7:06     ` [PATCH v3 10/16] examples/ntb: fix raw/ntb library linking Raghavendra Ningoji
@ 2026-11-11  7:06     ` Raghavendra Ningoji
  2026-11-11  7:06     ` [PATCH v3 12/16] doc: add IOVA requirement for NTB Raghavendra Ningoji
                       ` (5 subsequent siblings)
  16 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-11  7:06 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson

Removing the mw_size_align field changed the layout of the installed
struct ntb_dev_info. Mention it in the ABI changes as well.

Fixes: 5ce50c234ad1 ("raw/ntb: generalize framework for multiple vendors")

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 doc/guides/rel_notes/release_26_11.rst | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index 06133409e1..3d1c8d52fb 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -694,6 +694,8 @@ ABI Changes
 * cryptodev: The struct ``rte_crypto_rsa_op_param``
   was updated to include ``pss_salt``.
 
+* raw/ntb: The ``mw_size_align`` field was removed from ``struct ntb_dev_info``.
+
 
 Known Issues
 ------------
-- 
2.34.1


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

* [PATCH v3 12/16] doc: add IOVA requirement for NTB
  2026-11-11  7:06   ` [PATCH v3 00/16] " Raghavendra Ningoji
                       ` (10 preceding siblings ...)
  2026-11-11  7:06     ` [PATCH v3 11/16] doc: add NTB device info change to ABI section Raghavendra Ningoji
@ 2026-11-11  7:06     ` Raghavendra Ningoji
  2026-11-11  7:06     ` [PATCH v3 13/16] raw/ntb: remove unused AMD register definitions Raghavendra Ningoji
                       ` (4 subsequent siblings)
  16 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-11  7:06 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson

The memory window memzone is reserved with the alignment required by
the NTB hardware, but this alignment applies to the virtual address.
With IOVA as PA and a memzone larger than the hugepage size, the IOVA
may not be aligned and the device configuration fails.

Document that IOVA as VA mode or large enough hugepages are needed.

Fixes: 5ce50c234ad1 ("raw/ntb: generalize framework for multiple vendors")

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 doc/guides/rawdevs/ntb.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/doc/guides/rawdevs/ntb.rst b/doc/guides/rawdevs/ntb.rst
index c4ad2f05c4..8332c27de9 100644
--- a/doc/guides/rawdevs/ntb.rst
+++ b/doc/guides/rawdevs/ntb.rst
@@ -66,6 +66,10 @@ Different NTB hardware imposes different alignment constraints,
 so applications should not assume any particular value:
 reserve each memory window memzone with the alignment returned by ``rte_pmd_ntb_get_mem_align()``
 for that window and length. The ``ntb_fwd`` example shows this usage.
+The memzone alignment applies to its virtual address.
+With IOVA as PA, the IOVA of a memzone larger than the hugepage size
+is not guaranteed to be aligned, and the device configuration fails:
+use IOVA as VA mode, or hugepages at least as large as the memory window.
 
 Device Setup
 ------------
-- 
2.34.1


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

* [PATCH v3 13/16] raw/ntb: remove unused AMD register definitions
  2026-11-11  7:06   ` [PATCH v3 00/16] " Raghavendra Ningoji
                       ` (11 preceding siblings ...)
  2026-11-11  7:06     ` [PATCH v3 12/16] doc: add IOVA requirement for NTB Raghavendra Ningoji
@ 2026-11-11  7:06     ` Raghavendra Ningoji
  2026-11-11  7:06     ` [PATCH v3 14/16] raw/ntb: fix peer device status access Raghavendra Ningoji
                       ` (3 subsequent siblings)
  16 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-11  7:06 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson

The scratchpad mutex and doorbell flush mode registers are not used
by the driver.

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb_hw_amd.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/raw/ntb/ntb_hw_amd.h b/drivers/raw/ntb/ntb_hw_amd.h
index 8fffa24348..eec2041ad2 100644
--- a/drivers/raw/ntb/ntb_hw_amd.h
+++ b/drivers/raw/ntb/ntb_hw_amd.h
@@ -25,14 +25,12 @@
 
 /* Primary-side MMIO register offsets (BAR0), spec Table 1. */
 #define AMD_CNTL_OFFSET			0x200	/* Link Control. */
-#define AMD_SPADMUTEX_OFFSET		0x20C	/* Scratchpad mutex. */
 #define AMD_SPAD_OFFSET			0x210	/* Scratchpad registers. */
 #define AMD_SIDEINFO_OFFSET		0x408	/* Link Status (PSIDE_INFO). */
 #define AMD_BAR23_LIMIT_OFFSET		0x418	/* MW BAR23 size. */
 #define AMD_BAR45_LIMIT_OFFSET		0x420	/* MW BAR45 size. */
 #define AMD_BAR23_XLAT_OFFSET		0x438	/* MW BAR23 translation. */
 #define AMD_BAR45_XLAT_OFFSET		0x440	/* MW BAR45 translation. */
-#define AMD_DBFM_OFFSET			0x450	/* Doorbell flush mode. */
 #define AMD_DBREQ_OFFSET		0x454	/* Doorbell request. */
 #define AMD_DBMASK_OFFSET		0x45C	/* Doorbell mask. */
 #define AMD_DBSTAT_OFFSET		0x460	/* Doorbell status. */
-- 
2.34.1


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

* [PATCH v3 14/16] raw/ntb: fix peer device status access
  2026-11-11  7:06   ` [PATCH v3 00/16] " Raghavendra Ningoji
                       ` (12 preceding siblings ...)
  2026-11-11  7:06     ` [PATCH v3 13/16] raw/ntb: remove unused AMD register definitions Raghavendra Ningoji
@ 2026-11-11  7:06     ` Raghavendra Ningoji
  2026-11-11  7:06     ` [PATCH v3 15/16] raw/ntb: fix queue setup checks Raghavendra Ningoji
                       ` (2 subsequent siblings)
  16 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-11  7:06 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson, stable

The peer device status is written by the interrupt thread when the
peer doorbells are handled, and read by the control and data paths;
in particular, device stop polls it while waiting for the peer to
acknowledge. Plain accesses do not guarantee that this update is seen,
the stop loop only works because the delay call is opaque to the
compiler.

Use atomic accesses with release/acquire ordering.

Fixes: 62012a76811e ("raw/ntb: add handshake process")
Cc: stable@dpdk.org

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb.c | 28 +++++++++++++++++-----------
 drivers/raw/ntb/ntb.h |  5 ++++-
 2 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index 5b3abcb008..86405ad57a 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -48,6 +48,12 @@ static struct rte_rawdev_xstats_name ntb_xstats_names[] = {
 };
 #define NTB_XSTATS_NUM RTE_DIM(ntb_xstats_names)
 
+static inline bool
+ntb_peer_dev_is_up(struct ntb_hw *hw)
+{
+	return rte_atomic_load_explicit(&hw->peer_dev_up, rte_memory_order_acquire) != 0;
+}
+
 static void
 ntb_dev_intr_handler(void *param)
 {
@@ -69,14 +75,14 @@ ntb_dev_intr_handler(void *param)
 		 * Peer dev is already up. All mw settings are already done.
 		 * Skip them.
 		 */
-		if (hw->peer_dev_up)
+		if (ntb_peer_dev_is_up(hw))
 			return;
 
 		/* Check that the peer memory-window layout matches local. */
 		if ((*hw->ntb_ops->peer_mw_validate)(dev) < 0)
 			return;
 
-		hw->peer_dev_up = 1;
+		rte_atomic_store_explicit(&hw->peer_dev_up, 1, rte_memory_order_release);
 
 		/**
 		 * Handshake with peer. Scratchpad and translation programming
@@ -104,7 +110,7 @@ ntb_dev_intr_handler(void *param)
 		/* Peer device will be down, So clean local side too. */
 		(*hw->ntb_ops->link_cleanup)(dev);
 
-		hw->peer_dev_up = 0;
+		rte_atomic_store_explicit(&hw->peer_dev_up, 0, rte_memory_order_release);
 		/* Response peer's dev_stop request. */
 		(*hw->ntb_ops->peer_db_set)(dev, 2);
 		return;
@@ -114,7 +120,7 @@ ntb_dev_intr_handler(void *param)
 		NTB_LOG(INFO, "DB2: Peer device agrees dev to be down.");
 		/* Clear received doorbell. */
 		(*hw->ntb_ops->db_clear)(dev, (1 << 2));
-		hw->peer_dev_up = 0;
+		rte_atomic_store_explicit(&hw->peer_dev_up, 0, rte_memory_order_release);
 		return;
 	}
 
@@ -549,7 +555,7 @@ ntb_enqueue_bufs(struct rte_rawdev *dev,
 	void *buf_addr;
 	int i;
 
-	if (unlikely(dev->started == 0 || hw->peer_dev_up == 0)) {
+	if (unlikely(dev->started == 0 || !ntb_peer_dev_is_up(hw))) {
 		NTB_LOG(DEBUG, "Link is not up.");
 		return nb_tx;
 	}
@@ -660,7 +666,7 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
 	uint16_t off, last_avail, used_cnt, used_nb, nb_segs;
 	int i;
 
-	if (unlikely(dev->started == 0 || hw->peer_dev_up == 0)) {
+	if (unlikely(dev->started == 0 || !ntb_peer_dev_is_up(hw))) {
 		NTB_LOG(DEBUG, "Link is not up");
 		return nb_rx;
 	}
@@ -853,7 +859,7 @@ ntb_dev_start(struct rte_rawdev *dev)
 	uint32_t i;
 	int ret;
 
-	if (!hw->link_status || !hw->peer_dev_up)
+	if (!hw->link_status || !ntb_peer_dev_is_up(hw))
 		return -EINVAL;
 
 	/* Set total stats. */
@@ -907,7 +913,7 @@ ntb_dev_stop(struct rte_rawdev *dev)
 	uint32_t time_out;
 	int status, i;
 
-	if (!hw->peer_dev_up)
+	if (!ntb_peer_dev_is_up(hw))
 		goto clean;
 
 	(*hw->ntb_ops->link_cleanup)(dev);
@@ -926,7 +932,7 @@ ntb_dev_stop(struct rte_rawdev *dev)
 	time_out = 1000000;
 
 	/* Wait for cleanup work down before db mask clear. */
-	while (hw->peer_dev_up && time_out) {
+	while (ntb_peer_dev_is_up(hw) && time_out) {
 		time_out -= 10;
 		rte_delay_us(10);
 	}
@@ -1061,7 +1067,7 @@ ntb_attr_get(struct rte_rawdev *dev, const char *attr_name,
 
 	if (!strncmp(attr_name, NTB_LINK_STATUS_NAME, NTB_ATTR_NAME_LEN)) {
 		/* hw->link_status only indicates hw link status. */
-		*attr_value = hw->link_status && hw->peer_dev_up;
+		*attr_value = hw->link_status && ntb_peer_dev_is_up(hw);
 		NTB_LOG(DEBUG, "Attribute (%s) Value (%" PRIu64 ")",
 			attr_name, *attr_value);
 		return 0;
@@ -1325,7 +1331,7 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
 	int ret, i;
 
 	hw->pci_dev = pci_dev;
-	hw->peer_dev_up = 0;
+	rte_atomic_store_explicit(&hw->peer_dev_up, 0, rte_memory_order_release);
 	hw->link_status = NTB_LINK_DOWN;
 	hw->link_speed = NTB_SPEED_NONE;
 	hw->link_width = NTB_WIDTH_NONE;
diff --git a/drivers/raw/ntb/ntb.h b/drivers/raw/ntb/ntb.h
index f9f5bceede..6dce038e0b 100644
--- a/drivers/raw/ntb/ntb.h
+++ b/drivers/raw/ntb/ntb.h
@@ -7,6 +7,8 @@
 
 #include <stdbool.h>
 
+#include <rte_stdatomic.h>
+
 extern int ntb_logtype;
 #define RTE_LOGTYPE_NTB ntb_logtype
 
@@ -223,7 +225,8 @@ struct ntb_hw {
 	struct rte_intr_handle **db_intr_handles;
 	uint16_t nb_db_intr_handles;
 
-	uint8_t peer_dev_up;
+	/* Written by the interrupt thread, read by control and data paths. */
+	RTE_ATOMIC(uint8_t) peer_dev_up;
 	uint64_t mw_size[NTB_MAX_MW];
 	/* remote mem base addr */
 	uint64_t *peer_mw_base;
-- 
2.34.1


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

* [PATCH v3 15/16] raw/ntb: fix queue setup checks
  2026-11-11  7:06   ` [PATCH v3 00/16] " Raghavendra Ningoji
                       ` (13 preceding siblings ...)
  2026-11-11  7:06     ` [PATCH v3 14/16] raw/ntb: fix peer device status access Raghavendra Ningoji
@ 2026-11-11  7:06     ` Raghavendra Ningoji
  2026-11-11  7:06     ` [PATCH v3 16/16] raw/ntb: fix queue leaks on setup Raghavendra Ningoji
  2026-11-12 14:56     ` [PATCH v3 00/16] raw/ntb: post-merge fixes David Marchand
  16 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-11  7:06 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson, stable

The number of descriptors given at queue setup was not checked, while
the ring indexes wrap with a mask, requiring a power of 2, and the
burst functions use on-stack arrays of NTB_MAX_DESC_SIZE entries.

The Rx queue structure was also leaked when no mempool was given, and
the Tx queue structure and its ring when the Tx free threshold was
invalid.

Check the configuration before allocating the queue.

Fixes: c39d1e082a4b ("raw/ntb: setup queues")
Cc: stable@dpdk.org

Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb.c | 51 +++++++++++++++++++++++++++++++------------
 1 file changed, 37 insertions(+), 14 deletions(-)

diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index 86405ad57a..8b1c332fbb 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -246,6 +246,20 @@ ntb_rxq_release(struct ntb_rx_queue *rxq)
 	rte_free(rxq);
 }
 
+/* The ring indexes wrap with a mask and the bursts use on-stack arrays. */
+static int
+ntb_queue_nb_desc_check(uint16_t nb_desc)
+{
+	if (nb_desc < NTB_MIN_DESC_SIZE || nb_desc > NTB_MAX_DESC_SIZE ||
+	    !rte_is_power_of_2(nb_desc)) {
+		NTB_LOG(ERR, "Number of descriptors %u must be a power of 2 within [%u, %u].",
+			nb_desc, NTB_MIN_DESC_SIZE, NTB_MAX_DESC_SIZE);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int
 ntb_rxq_setup(struct rte_rawdev *dev,
 	      uint16_t qp_id,
@@ -259,6 +273,14 @@ ntb_rxq_setup(struct rte_rawdev *dev,
 	if (conf_size != sizeof(*rxq_conf))
 		return -EINVAL;
 
+	if (rxq_conf->rx_mp == NULL) {
+		NTB_LOG(ERR, "Invalid null mempool pointer.");
+		return -EINVAL;
+	}
+
+	if (ntb_queue_nb_desc_check(rxq_conf->nb_desc) < 0)
+		return -EINVAL;
+
 	/* Allocate the rx queue data structure */
 	rxq = rte_zmalloc_socket("ntb rx queue",
 				 sizeof(struct ntb_rx_queue),
@@ -270,10 +292,6 @@ ntb_rxq_setup(struct rte_rawdev *dev,
 		return -ENOMEM;
 	}
 
-	if (rxq_conf->rx_mp == NULL) {
-		NTB_LOG(ERR, "Invalid null mempool pointer.");
-		return -EINVAL;
-	}
 	rxq->nb_rx_desc = rxq_conf->nb_desc;
 	rxq->mpool = rxq_conf->rx_mp;
 	rxq->port_id = dev->dev_id;
@@ -340,11 +358,24 @@ ntb_txq_setup(struct rte_rawdev *dev,
 	struct ntb_queue_conf *txq_conf = queue_conf;
 	struct ntb_hw *hw = dev->dev_private;
 	struct ntb_tx_queue *txq;
-	uint16_t i, prev;
+	uint16_t i, prev, tx_free_thresh;
 
 	if (conf_size != sizeof(*txq_conf))
 		return -EINVAL;
 
+	if (ntb_queue_nb_desc_check(txq_conf->nb_desc) < 0)
+		return -EINVAL;
+
+	tx_free_thresh = txq_conf->tx_free_thresh ?
+			 txq_conf->tx_free_thresh :
+			 NTB_DFLT_TX_FREE_THRESH;
+	if (tx_free_thresh >= txq_conf->nb_desc - 3) {
+		NTB_LOG(ERR, "tx_free_thresh must be less than nb_desc - 3. "
+			"(tx_free_thresh=%u qp_id=%u)", tx_free_thresh,
+			qp_id);
+		return -EINVAL;
+	}
+
 	/* Allocate the TX queue data structure. */
 	txq = rte_zmalloc_socket("ntb tx queue",
 				  sizeof(struct ntb_tx_queue),
@@ -383,15 +414,7 @@ ntb_txq_setup(struct rte_rawdev *dev,
 		prev = i;
 	}
 
-	txq->tx_free_thresh = txq_conf->tx_free_thresh ?
-			      txq_conf->tx_free_thresh :
-			      NTB_DFLT_TX_FREE_THRESH;
-	if (txq->tx_free_thresh >= txq->nb_tx_desc - 3) {
-		NTB_LOG(ERR, "tx_free_thresh must be less than nb_desc - 3. "
-			"(tx_free_thresh=%u qp_id=%u)", txq->tx_free_thresh,
-			qp_id);
-		return -EINVAL;
-	}
+	txq->tx_free_thresh = tx_free_thresh;
 
 	hw->tx_queues[qp_id] = txq;
 
-- 
2.34.1


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

* [PATCH v3 16/16] raw/ntb: fix queue leaks on setup
  2026-11-11  7:06   ` [PATCH v3 00/16] " Raghavendra Ningoji
                       ` (14 preceding siblings ...)
  2026-11-11  7:06     ` [PATCH v3 15/16] raw/ntb: fix queue setup checks Raghavendra Ningoji
@ 2026-11-11  7:06     ` Raghavendra Ningoji
  2026-11-12 14:56     ` [PATCH v3 00/16] raw/ntb: post-merge fixes David Marchand
  16 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-11  7:06 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, stephen, jingjing.wu, bhagyada.modali,
	Selwin.Sebastian, bruce.richardson, stable

The Tx queue was set up first and left in place when the Rx queue
setup failed. A new setup of the same queue pair, either a retry after
such a failure or a reconfiguration, then overwrote the previous queue
pointers without freeing them.

Check the shared configuration before setting up any queue, release
the queues of a previous setup, and release the Tx queue if the Rx
queue setup fails. As the previous queues are released, refuse the
setup while the device is started.

Fixes: c39d1e082a4b ("raw/ntb: setup queues")
Cc: stable@dpdk.org

Suggested-by: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
---
 drivers/raw/ntb/ntb.c | 64 +++++++++++++++++++++++++------------------
 1 file changed, 37 insertions(+), 27 deletions(-)

diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index 8b1c332fbb..68137c4237 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -235,10 +235,8 @@ ntb_rxq_release_mbufs(struct ntb_rx_queue *q)
 static void
 ntb_rxq_release(struct ntb_rx_queue *rxq)
 {
-	if (!rxq) {
-		NTB_LOG(ERR, "Pointer to rxq is NULL");
+	if (!rxq)
 		return;
-	}
 
 	ntb_rxq_release_mbufs(rxq);
 
@@ -273,11 +271,6 @@ ntb_rxq_setup(struct rte_rawdev *dev,
 	if (conf_size != sizeof(*rxq_conf))
 		return -EINVAL;
 
-	if (rxq_conf->rx_mp == NULL) {
-		NTB_LOG(ERR, "Invalid null mempool pointer.");
-		return -EINVAL;
-	}
-
 	if (ntb_queue_nb_desc_check(rxq_conf->nb_desc) < 0)
 		return -EINVAL;
 
@@ -338,10 +331,8 @@ ntb_txq_release_mbufs(struct ntb_tx_queue *q)
 static void
 ntb_txq_release(struct ntb_tx_queue *txq)
 {
-	if (!txq) {
-		NTB_LOG(ERR, "Pointer to txq is NULL");
+	if (!txq)
 		return;
-	}
 
 	ntb_txq_release_mbufs(txq);
 
@@ -422,43 +413,62 @@ ntb_txq_setup(struct rte_rawdev *dev,
 }
 
 
+static int
+ntb_queue_release(struct rte_rawdev *dev, uint16_t queue_id)
+{
+	struct ntb_hw *hw = dev->dev_private;
+
+	if (queue_id >= hw->queue_pairs)
+		return -EINVAL;
+
+	ntb_txq_release(hw->tx_queues[queue_id]);
+	hw->tx_queues[queue_id] = NULL;
+	ntb_rxq_release(hw->rx_queues[queue_id]);
+	hw->rx_queues[queue_id] = NULL;
+
+	return 0;
+}
+
 static int
 ntb_queue_setup(struct rte_rawdev *dev,
 		uint16_t queue_id,
 		rte_rawdev_obj_t queue_conf,
 		size_t conf_size)
 {
+	struct ntb_queue_conf *conf = queue_conf;
 	struct ntb_hw *hw = dev->dev_private;
 	int ret;
 
 	if (queue_id >= hw->queue_pairs)
 		return -EINVAL;
 
+	if (conf == NULL || conf_size != sizeof(*conf))
+		return -EINVAL;
+
+	if (conf->rx_mp == NULL) {
+		NTB_LOG(ERR, "Invalid null mempool pointer.");
+		return -EINVAL;
+	}
+
+	if (dev->started) {
+		NTB_LOG(ERR, "Cannot setup queue %u of a started device.", queue_id);
+		return -EBUSY;
+	}
+
+	/* Release the queues of a previous setup. */
+	ntb_queue_release(dev, queue_id);
+
 	ret = ntb_txq_setup(dev, queue_id, queue_conf, conf_size);
 	if (ret < 0)
 		return ret;
 
 	ret = ntb_rxq_setup(dev, queue_id, queue_conf, conf_size);
+	if (ret < 0)
+		ntb_queue_release(dev, queue_id);
 
 	return ret;
 }
 
-static int
-ntb_queue_release(struct rte_rawdev *dev, uint16_t queue_id)
-{
-	struct ntb_hw *hw = dev->dev_private;
-
-	if (queue_id >= hw->queue_pairs)
-		return -EINVAL;
-
-	ntb_txq_release(hw->tx_queues[queue_id]);
-	hw->tx_queues[queue_id] = NULL;
-	ntb_rxq_release(hw->rx_queues[queue_id]);
-	hw->rx_queues[queue_id] = NULL;
-
-	return 0;
-}
-
 static uint16_t
 ntb_queue_count(struct rte_rawdev *dev)
 {
-- 
2.34.1


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

* Re: [PATCH v2 00/15] raw/ntb: post-merge fixes
  2026-11-06 12:50   ` Stephen Hemminger
@ 2026-11-11  7:09     ` Raghavendra Ningoji
  0 siblings, 0 replies; 52+ messages in thread
From: Raghavendra Ningoji @ 2026-11-11  7:09 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: dev, David Marchand, Jingjing Wu, Selwin Sebastian,
	Bhagyada Modali, bruce.richardson

On Fri, 6 Nov 2026 13:50:50 -0800
Stephen Hemminger <stephen@networkplumber.org> wrote:

> Info (pre-existing, not introduced by this patch): ntb_queue_setup()
> still leaks on two paths the commit message does not cover.
[...]
> (ntb_txq_release()/ntb_rxq_release() log an error on NULL, so a
> NULL check on each would be needed for the last release.) Fine as a
> follow-up.

Hi Stephen,

Thanks for the review. The follow-up is included in v3 as patch 16,
"raw/ntb: fix queue leaks on setup", as you suggested: the shared conf
is checked first, the previous queues are released before a new setup,
the Tx queue is released if the Rx setup fails, and the release helpers
ignore NULL queues. In addition, the setup returns -EBUSY when the
device is started, as releasing the queues under the data path would be
a use after free.

Hi David,

Sorry for the trouble with v2. The patches were generated without
threading, so each one replied to the v1 cover letter instead of the
v2 one. Patchwork then split the series and the CI could not apply it.

v3 is resent with proper threading, rebased on main. Patches 1-15 are
unchanged from v2, and patch 16 is the follow-up above. I will check
that the CI passes on v3. The v1 and v2 series in patchwork can be
marked as superseded.

Thanks,
Raghavendra

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

* Re: [PATCH v3 00/16] raw/ntb: post-merge fixes
  2026-11-11  7:06   ` [PATCH v3 00/16] " Raghavendra Ningoji
                       ` (15 preceding siblings ...)
  2026-11-11  7:06     ` [PATCH v3 16/16] raw/ntb: fix queue leaks on setup Raghavendra Ningoji
@ 2026-11-12 14:56     ` David Marchand
  16 siblings, 0 replies; 52+ messages in thread
From: David Marchand @ 2026-11-12 14:56 UTC (permalink / raw)
  To: Raghavendra Ningoji
  Cc: dev, stephen, jingjing.wu, bhagyada.modali, Selwin.Sebastian,
	bruce.richardson

On Wed, 11 Nov 2026 at 08:11, Raghavendra Ningoji
<raghavendra.ningoji@amd.com> wrote:
>
> This series addresses the post-merge review of the AMD NTB support
> by Stephen. Some of the issues also exist in the Intel code and in
> released versions; those patches are tagged for stable.
>
> - Patches 1-4 fix the type confusion in rte_pmd_ntb_get_mem_align(),
>   the unbounded peer memory window count, the off-by-one in the
>   address remapping and the memory window leaks.
>
> - Patch 5 fixes the doorbell interrupts with vfio-pci: only MSI-X
>   vector 0 (DB0) was serviced, so the DB1/DB2 exchange of dev_stop
>   never completed and the stop waited for its 1s timeout.
>
> - Patch 7 removes the AMD hardware event handling, which could not run
>   as wired, and documents that hardware events are not handled.
>
> - Patches 8-9 fix the Rx path: a partially consumed packet was leaked
>   and desynchronized the ring, and an mbuf owned by the application
>   could be freed again on device stop.
>
> - Patches 14-16 fix the peer device status accesses between the
>   interrupt thread and the stop/data paths, and the missing checks and
>   leaks at queue setup.
>
> - The other patches are documentation and cleanup.
>
> The peer memory window size check suggested for the AMD handshake is
> not added: all the AMD scratchpads are in use, and the window limit
> register programmed with the local memzone length already bounds what
> the peer can reach.
>
> Tested with vfio-pci on two AMD EPYC Embedded hosts: handshake,
> file transfer, and stop/quit with DB1/DB2 exchange.
>
> ---
> Changes since v2:
> - Resent with proper threading: in v2, all the patches replied to the
>   v1 cover letter, so patchwork did not group them as a series and the
>   CI could not apply them. No change in patches 1-15, apart from the
>   rebase on current main.
> - Added patch 16 for the queue setup leaks reported by Stephen on v2.

There was again a hiccup with the CI on the v3, probably something
wrong in your mailing setup.

I had a look at the changes, and nothing looks out of place.
I ran my compilation checks, some GHA checks, all passed.


Thanks for the fixes.
Series applied.


-- 
David Marchand


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

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

Thread overview: 52+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-04 11:19 [PATCH 00/13] raw/ntb: post-merge fixes Raghavendra Ningoji
2026-11-04 11:19 ` [PATCH 01/13] raw/ntb: fix device check in memory alignment query Raghavendra Ningoji
2026-11-04 11:19 ` [PATCH 02/13] raw/ntb: fix peer memory window count check Raghavendra Ningoji
2026-11-04 11:19 ` [PATCH 03/13] raw/ntb: fix memory window bound in address remapping Raghavendra Ningoji
2026-11-04 11:19 ` [PATCH 04/13] raw/ntb: fix memory leaks Raghavendra Ningoji
2026-11-04 11:19 ` [PATCH 05/13] raw/ntb: fix doorbell interrupts with VFIO MSI-X Raghavendra Ningoji
2026-11-04 11:19 ` [PATCH 06/13] raw/ntb: fix AMD processor names Raghavendra Ningoji
2026-11-04 11:19 ` [PATCH 07/13] raw/ntb: remove AMD hardware event handling Raghavendra Ningoji
2026-11-04 11:19 ` [PATCH 08/13] raw/ntb: fix Rx of incomplete packets Raghavendra Ningoji
2026-11-04 11:19 ` [PATCH 09/13] raw/ntb: fix double free of Rx mbufs on stop Raghavendra Ningoji
2026-11-04 11:19 ` [PATCH 10/13] examples/ntb: fix raw/ntb library linking Raghavendra Ningoji
2026-11-04 11:19 ` [PATCH 11/13] doc: add NTB device info change to ABI section Raghavendra Ningoji
2026-11-04 11:20 ` [PATCH 12/13] doc: add IOVA requirement for NTB Raghavendra Ningoji
2026-11-04 11:20 ` [PATCH 13/13] raw/ntb: remove unused AMD register definitions Raghavendra Ningoji
2026-11-04 12:24 ` [PATCH 00/13] raw/ntb: post-merge fixes Stephen Hemminger
2026-11-06  5:54   ` Raghavendra Ningoji
2026-11-06  5:50 ` [PATCH v2 00/15] " Raghavendra Ningoji
2026-11-06 12:50   ` Stephen Hemminger
2026-11-11  7:09     ` Raghavendra Ningoji
2026-11-11  7:06   ` [PATCH v3 00/16] " Raghavendra Ningoji
2026-11-11  7:06     ` [PATCH v3 01/16] raw/ntb: fix device check in memory alignment query Raghavendra Ningoji
2026-11-11  7:06     ` [PATCH v3 02/16] raw/ntb: fix peer memory window count check Raghavendra Ningoji
2026-11-11  7:06     ` [PATCH v3 03/16] raw/ntb: fix memory window bound in address remapping Raghavendra Ningoji
2026-11-11  7:06     ` [PATCH v3 04/16] raw/ntb: fix memory leaks Raghavendra Ningoji
2026-11-11  7:06     ` [PATCH v3 05/16] raw/ntb: fix doorbell interrupts with VFIO MSI-X Raghavendra Ningoji
2026-11-11  7:06     ` [PATCH v3 06/16] raw/ntb: fix AMD processor names Raghavendra Ningoji
2026-11-11  7:06     ` [PATCH v3 07/16] raw/ntb: remove AMD hardware event handling Raghavendra Ningoji
2026-11-11  7:06     ` [PATCH v3 08/16] raw/ntb: fix Rx of incomplete packets Raghavendra Ningoji
2026-11-11  7:06     ` [PATCH v3 09/16] raw/ntb: fix double free of Rx mbufs on stop Raghavendra Ningoji
2026-11-11  7:06     ` [PATCH v3 10/16] examples/ntb: fix raw/ntb library linking Raghavendra Ningoji
2026-11-11  7:06     ` [PATCH v3 11/16] doc: add NTB device info change to ABI section Raghavendra Ningoji
2026-11-11  7:06     ` [PATCH v3 12/16] doc: add IOVA requirement for NTB Raghavendra Ningoji
2026-11-11  7:06     ` [PATCH v3 13/16] raw/ntb: remove unused AMD register definitions Raghavendra Ningoji
2026-11-11  7:06     ` [PATCH v3 14/16] raw/ntb: fix peer device status access Raghavendra Ningoji
2026-11-11  7:06     ` [PATCH v3 15/16] raw/ntb: fix queue setup checks Raghavendra Ningoji
2026-11-11  7:06     ` [PATCH v3 16/16] raw/ntb: fix queue leaks on setup Raghavendra Ningoji
2026-11-12 14:56     ` [PATCH v3 00/16] raw/ntb: post-merge fixes David Marchand
2026-11-06  5:50 ` [PATCH v2 01/15] raw/ntb: fix device check in memory alignment query Raghavendra Ningoji
2026-11-06  5:50 ` [PATCH v2 02/15] raw/ntb: fix peer memory window count check Raghavendra Ningoji
2026-11-06  5:50 ` [PATCH v2 03/15] raw/ntb: fix memory window bound in address remapping Raghavendra Ningoji
2026-11-06  5:50 ` [PATCH v2 04/15] raw/ntb: fix memory leaks Raghavendra Ningoji
2026-11-06  5:50 ` [PATCH v2 05/15] raw/ntb: fix doorbell interrupts with VFIO MSI-X Raghavendra Ningoji
2026-11-06  5:50 ` [PATCH v2 06/15] raw/ntb: fix AMD processor names Raghavendra Ningoji
2026-11-06  5:50 ` [PATCH v2 07/15] raw/ntb: remove AMD hardware event handling Raghavendra Ningoji
2026-11-06  5:50 ` [PATCH v2 08/15] raw/ntb: fix Rx of incomplete packets Raghavendra Ningoji
2026-11-06  5:50 ` [PATCH v2 09/15] raw/ntb: fix double free of Rx mbufs on stop Raghavendra Ningoji
2026-11-06  5:50 ` [PATCH v2 10/15] examples/ntb: fix raw/ntb library linking Raghavendra Ningoji
2026-11-06  5:50 ` [PATCH v2 11/15] doc: add NTB device info change to ABI section Raghavendra Ningoji
2026-11-06  5:50 ` [PATCH v2 12/15] doc: add IOVA requirement for NTB Raghavendra Ningoji
2026-11-06  5:50 ` [PATCH v2 13/15] raw/ntb: remove unused AMD register definitions Raghavendra Ningoji
2026-11-06  5:50 ` [PATCH v2 14/15] raw/ntb: fix peer device status access Raghavendra Ningoji
2026-11-06  5:50 ` [PATCH v2 15/15] raw/ntb: fix queue setup checks Raghavendra Ningoji

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.