DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 4/4] app/testpmd: report reason when queue setup command fails
From: Stephen Hemminger @ 2026-07-02 16:10 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Aman Singh
In-Reply-To: <20260702161244.363233-1-stephen@networkplumber.org>

The interactive "port <id> rxq|txq <id> setup" command printed a
bare failure message. rte_eth_rx/tx_queue_setup() can fail with
-EBUSY without logging anything, for example when the port is
started and the PMD does not support runtime queue setup, leaving
the user with no clue:

  testpmd> port 0 rxq 0 setup
  Failed to setup RX queue

Print the error string:

  Failed to setup RX queue: Device or resource busy

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 app/test-pmd/cmdline.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index bb62778a26..e0dcdc1193 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -3092,7 +3092,8 @@ cmd_setup_rxtx_queue_parsed(
 				     &port->rxq[res->qid].conf,
 				     mp);
 		if (ret)
-			fprintf(stderr, "Failed to setup RX queue\n");
+			fprintf(stderr, "Failed to setup RX queue: %s\n",
+				rte_strerror(-ret));
 	} else {
 		socket_id = txring_numa[res->portid];
 		if (!numa_support || socket_id == NUMA_NO_CONFIG)
@@ -3109,7 +3110,8 @@ cmd_setup_rxtx_queue_parsed(
 					     socket_id,
 					     &port->txq[res->qid].conf);
 		if (ret)
-			fprintf(stderr, "Failed to setup TX queue\n");
+			fprintf(stderr, "Failed to setup TX queue: %s\n",
+				rte_strerror(-ret));
 	}
 }
 
-- 
2.53.0


^ permalink raw reply related

* [PATCH 3/4] app/testpmd: display any socket ID as text
From: Stephen Hemminger @ 2026-07-02 16:10 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Aman Singh
In-Reply-To: <20260702161244.363233-1-stephen@networkplumber.org>

When NUMA support is disabled the port socket id is SOCKET_ID_ANY,
which was displayed as 4294967295 in "show port info", the
"Configuring Port" message, the mbuf pool creation log and the
pool lookup error message. Print "any" instead.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 app/test-pmd/cmdline.c |  6 ++++--
 app/test-pmd/config.c  | 18 ++++++++++++------
 app/test-pmd/testpmd.c | 28 ++++++++++++++++++----------
 app/test-pmd/testpmd.h | 11 +++++++++++
 4 files changed, 45 insertions(+), 18 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 3c39e27aa8..bb62778a26 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -3078,9 +3078,11 @@ cmd_setup_rxtx_queue_parsed(
 
 		mp = mbuf_pool_find_first(socket_id);
 		if (mp == NULL) {
+			char buf[16];
+
 			fprintf(stderr,
-				"Failed to setup RX queue: No mempool allocation on the socket %d\n",
-				rxring_numa[res->portid]);
+				"Failed to setup RX queue: No mempool allocation on the socket %s\n",
+				socket_id_str(socket_id, buf, sizeof(buf)));
 			return;
 		}
 		ret = rx_queue_setup(res->portid,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 9d457ca88e..166caa10b0 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -808,6 +808,7 @@ port_infos_display(portid_t port_id)
 	static const char *info_border = "*********************";
 	uint16_t mtu;
 	char name[RTE_ETH_NAME_MAX_LEN];
+	char buf[16];
 	int ret;
 	char fw_version[ETHDEV_FWVERS_LEN];
 	uint32_t lanes;
@@ -841,7 +842,8 @@ port_infos_display(portid_t port_id)
 
 	if (rte_dev_devargs(dev_info.device) && rte_dev_devargs(dev_info.device)->args)
 		printf("\nDevargs: %s", rte_dev_devargs(dev_info.device)->args);
-	printf("\nConnect to socket: %u", port->socket_id);
+	printf("\nConnect to socket: %s",
+	       socket_id_str(port->socket_id, buf, sizeof(buf)));
 
 	if (port_numa[port_id] != NUMA_NO_CONFIG) {
 		mp = mbuf_pool_find(port_numa[port_id], 0);
@@ -849,7 +851,8 @@ port_infos_display(portid_t port_id)
 			printf("\nmemory allocation on the socket: %d",
 							port_numa[port_id]);
 	} else
-		printf("\nmemory allocation on the socket: %u",port->socket_id);
+		printf("\nmemory allocation on the socket: %s",
+		       socket_id_str(port->socket_id, buf, sizeof(buf)));
 
 	printf("\nLink status: %s\n", (link.link_status) ? ("up") : ("down"));
 	printf("Link speed: %s\n", rte_eth_link_speed_to_str(link.link_speed));
@@ -5642,6 +5645,7 @@ pkt_fwd_config_display(struct fwd_config *cfg)
 	struct fwd_stream *fs;
 	lcoreid_t  lc_id;
 	streamid_t sm_id;
+	char buf[16];
 
 	printf("%s%s%s packet forwarding%s - ports=%d - cores=%d - streams=%d - "
 		"NUMA support %s, MP allocation mode: %s\n",
@@ -5664,12 +5668,14 @@ pkt_fwd_config_display(struct fwd_config *cfg)
 		       fwd_lcores[lc_id]->stream_nb);
 		for (sm_id = 0; sm_id < fwd_lcores[lc_id]->stream_nb; sm_id++) {
 			fs = fwd_streams[fwd_lcores[lc_id]->stream_idx + sm_id];
-			printf("\n  RX P=%d/Q=%d (socket %u) -> TX "
-			       "P=%d/Q=%d (socket %u) ",
+			printf("\n  RX P=%d/Q=%d (socket %s) -> ",
 			       fs->rx_port, fs->rx_queue,
-			       ports[fs->rx_port].socket_id,
+			       socket_id_str(ports[fs->rx_port].socket_id,
+					     buf, sizeof(buf)));
+			printf("TX P=%d/Q=%d (socket %s) ",
 			       fs->tx_port, fs->tx_queue,
-			       ports[fs->tx_port].socket_id);
+			       socket_id_str(ports[fs->tx_port].socket_id,
+					     buf, sizeof(buf)));
 			print_ethaddr("peer=",
 				      &peer_eth_addrs[fs->peer_addr]);
 		}
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 04f0e15bee..69e631d386 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -1263,6 +1263,7 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
 		 unsigned int socket_id, uint16_t size_idx)
 {
 	char pool_name[RTE_MEMPOOL_NAMESIZE];
+	char sock_str[16];
 	struct rte_mempool *rte_mp = NULL;
 #ifndef RTE_EXEC_ENV_WINDOWS
 	uint32_t mb_size;
@@ -1274,14 +1275,17 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
 		rte_mp = rte_mempool_lookup(pool_name);
 		if (rte_mp == NULL)
 			rte_exit(EXIT_FAILURE,
-				"Get mbuf pool for socket %u failed: %s\n",
-				socket_id, rte_strerror(rte_errno));
+				"Get mbuf pool for socket %s failed: %s\n",
+				socket_id_str(socket_id, sock_str,
+					      sizeof(sock_str)),
+				rte_strerror(rte_errno));
 		return rte_mp;
 	}
 
 	TESTPMD_LOG(INFO,
-		"create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
-		pool_name, nb_mbuf, mbuf_seg_size, socket_id);
+		"create a new mbuf pool <%s>: n=%u, size=%u, socket=%s\n",
+		pool_name, nb_mbuf, mbuf_seg_size,
+		socket_id_str(socket_id, sock_str, sizeof(sock_str)));
 
 	switch (mp_alloc_type) {
 	case MP_ALLOC_NATIVE:
@@ -1366,8 +1370,9 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
 #endif
 	if (rte_mp == NULL) {
 		rte_exit(EXIT_FAILURE,
-			"Creation of mbuf pool for socket %u failed: %s\n",
-			socket_id, rte_strerror(rte_errno));
+			"Creation of mbuf pool for socket %s failed: %s\n",
+			socket_id_str(socket_id, sock_str, sizeof(sock_str)),
+			rte_strerror(rte_errno));
 	} else if (verbose_level > 0) {
 		rte_mempool_dump(stdout, rte_mp);
 	}
@@ -2973,6 +2978,7 @@ int
 start_port(portid_t pid)
 {
 	int diag;
+	char buf[16];
 	portid_t pi;
 	portid_t p_pi = RTE_MAX_ETHPORTS;
 	portid_t pl[RTE_MAX_ETHPORTS];
@@ -3027,8 +3033,9 @@ start_port(portid_t pid)
 				}
 			}
 			configure_rxtx_dump_callbacks(0);
-			printf("Configuring Port %d (socket %u)\n", pi,
-					port->socket_id);
+			printf("Configuring Port %d (socket %s)\n", pi,
+					socket_id_str(port->socket_id,
+						buf, sizeof(buf)));
 			if (nb_hairpinq > 0 &&
 			    rte_eth_dev_hairpin_capability_get(pi, &cap)) {
 				fprintf(stderr,
@@ -3156,8 +3163,9 @@ start_port(portid_t pid)
 							(port->socket_id);
 					if (mp == NULL) {
 						fprintf(stderr,
-							"Failed to setup RX queue: No mempool allocation on the socket %d\n",
-							port->socket_id);
+							"Failed to setup RX queue: No mempool allocation on the socket %s\n",
+							socket_id_str(port->socket_id,
+								buf, sizeof(buf)));
 						return -1;
 					}
 					diag = rx_queue_setup(pi, qi,
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 3d4b36d668..1732fa1c19 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -873,6 +873,17 @@ current_fwd_lcore(void)
 void
 parse_fwd_portlist(const char *port);
 
+/* Format a socket id for display, SOCKET_ID_ANY as "any". */
+static inline const char *
+socket_id_str(unsigned int socket_id, char *buf, size_t size)
+{
+	if (socket_id == (unsigned int)SOCKET_ID_ANY)
+		snprintf(buf, size, "any");
+	else
+		snprintf(buf, size, "%u", socket_id);
+	return buf;
+}
+
 /* Mbuf Pools */
 static inline void
 mbuf_poolname_build(unsigned int sock_id, char *mp_name,
-- 
2.53.0


^ permalink raw reply related

* [PATCH 2/4] app/testpmd: consolidate port socket ID computation
From: Stephen Hemminger @ 2026-07-02 16:10 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Aman Singh
In-Reply-To: <20260702161244.363233-1-stephen@networkplumber.org>

The socket id of a port was computed in three places with
diverging copies of the same policy:

- init_config() and init_fwd_streams() duplicated the full policy
  (--port-numa-config, device socket id, first available socket,
  --socket-num);
- setup_attached_port() used only the device socket id and ignored
  --port-numa-config, --no-numa and --socket-num, so a hot-attached
  port could be keyed to a socket where no mbuf pool exists.

Move the policy into a single helper, port_socket_id(), and use it
in all three places.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 app/test-pmd/testpmd.c | 69 +++++++++++++++++-------------------------
 1 file changed, 28 insertions(+), 41 deletions(-)

diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index b5dca03047..04f0e15bee 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -1740,6 +1740,31 @@ uma_socket_id(void)
 	       (unsigned int)SOCKET_ID_ANY : socket_num;
 }
 
+/*
+ * Socket id to use for a port: the socket its mbuf pools are created
+ * on and where its queue resources are placed.
+ */
+static unsigned int
+port_socket_id(portid_t pid)
+{
+	unsigned int socket_id;
+
+	if (!numa_support)
+		return uma_socket_id();
+
+	socket_id = port_numa[pid];
+	if (socket_id == NUMA_NO_CONFIG) {
+		socket_id = rte_eth_dev_socket_id(pid);
+		/*
+		 * If socket_id is invalid,
+		 * set to the first available socket.
+		 */
+		if (check_socket_id(socket_id) < 0)
+			socket_id = socket_ids[0];
+	}
+	return socket_id;
+}
+
 static void
 init_config(void)
 {
@@ -1774,25 +1799,8 @@ init_config(void)
 	}
 
 	RTE_ETH_FOREACH_DEV(pid) {
-		uint32_t socket_id;
-
-		if (numa_support) {
-			socket_id = port_numa[pid];
-			if (port_numa[pid] == NUMA_NO_CONFIG) {
-				socket_id = rte_eth_dev_socket_id(pid);
-
-				/*
-				 * if socket_id is invalid,
-				 * set to the first available socket.
-				 */
-				if (check_socket_id(socket_id) < 0)
-					socket_id = socket_ids[0];
-			}
-		} else {
-			socket_id = uma_socket_id();
-		}
 		/* Apply default TxRx configuration for all ports */
-		init_config_port_offloads(pid, socket_id);
+		init_config_port_offloads(pid, port_socket_id(pid));
 	}
 	/*
 	 * Create pools of mbuf.
@@ -1916,23 +1924,7 @@ init_fwd_streams(void)
 				nb_txq, port->dev_info.max_tx_queues);
 			return -1;
 		}
-		if (numa_support) {
-			if (port_numa[pid] != NUMA_NO_CONFIG)
-				port->socket_id = port_numa[pid];
-			else {
-				port->socket_id = rte_eth_dev_socket_id(pid);
-
-				/*
-				 * if socket_id is invalid,
-				 * set to the first available socket.
-				 */
-				if (check_socket_id(port->socket_id) < 0)
-					port->socket_id = socket_ids[0];
-			}
-		}
-		else {
-			port->socket_id = uma_socket_id();
-		}
+		port->socket_id = port_socket_id(pid);
 	}
 
 	q = RTE_MAX(nb_rxq, nb_txq);
@@ -3604,14 +3596,9 @@ attach_port(char *identifier)
 static void
 setup_attached_port(portid_t pi)
 {
-	unsigned int socket_id;
 	int ret;
 
-	socket_id = (unsigned)rte_eth_dev_socket_id(pi);
-	/* if socket_id is invalid, set to the first available socket. */
-	if (check_socket_id(socket_id) < 0)
-		socket_id = socket_ids[0];
-	reconfig(pi, socket_id);
+	reconfig(pi, port_socket_id(pi));
 	ret = rte_eth_promiscuous_enable(pi);
 	if (ret != 0)
 		fprintf(stderr,
-- 
2.53.0


^ permalink raw reply related

* [PATCH 1/4] app/testpmd: fix port socket ID with NUMA disabled
From: Stephen Hemminger @ 2026-07-02 16:10 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, stable, Maayan Kashani, Aman Singh
In-Reply-To: <20260702161244.363233-1-stephen@networkplumber.org>

When NUMA support is disabled, mbuf pools are created on
SOCKET_ID_ANY but port->socket_id is still set to 0 (or
--socket-num). Pool lookup is by name, and the name embeds the
socket id the pool was created with, so every lookup that does not
go through the one workaround in start_port() misses:

- the per-lcore pool assignment in init_config() leaves
  fwd_lcores[]->mbp NULL, so "testpmd --no-numa
  --forward-mode=txonly" crashes with a NULL dereference in
  pkt_burst_transmit();
- the per-segment and multi-mempool lookups in rx_queue_setup()
  fall back to the first pool, so buffer split fails when a later
  segment needs a larger mbuf
  (e.g. --mbuf-size=314,978 --rxpkts=186,978);
- the interactive "port <id> rxq|txq <id> setup" command cannot
  find a pool.

The --socket-num option is also ignored for pool allocation since
the offending commit.

Fix this at the source instead of adding another workaround at a
lookup site: make port->socket_id hold the same socket id the
pools are created and named with. Add uma_socket_id() returning
the pool socket key used when NUMA support is disabled
(--socket-num if given, otherwise SOCKET_ID_ANY) and use it for
pool creation, port->socket_id and the per-lcore pool fallback.
The workaround in start_port() is then unnecessary.

Passing SOCKET_ID_ANY to rte_eth_rx/tx_queue_setup() is allowed by
the ethdev API and matches the cross-NUMA intent of the offending
commit.

Fixes: 835fd4893a31 ("app/testpmd: support cross-NUMA allocations")
Cc: stable@dpdk.org

Reported-by: Maayan Kashani <mkashani@nvidia.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 app/test-pmd/testpmd.c | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index fcd8a90967..b5dca03047 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -1729,6 +1729,17 @@ init_config_port_offloads(portid_t pid, uint32_t socket_id)
 	}
 }
 
+/*
+ * Socket id that mbuf pools are created (and named) with when NUMA
+ * support is disabled: --socket-num if given, otherwise SOCKET_ID_ANY.
+ */
+static unsigned int
+uma_socket_id(void)
+{
+	return socket_num == UMA_NO_CONFIG ?
+	       (unsigned int)SOCKET_ID_ANY : socket_num;
+}
+
 static void
 init_config(void)
 {
@@ -1778,8 +1789,7 @@ init_config(void)
 					socket_id = socket_ids[0];
 			}
 		} else {
-			socket_id = (socket_num == UMA_NO_CONFIG) ?
-				    0 : socket_num;
+			socket_id = uma_socket_id();
 		}
 		/* Apply default TxRx configuration for all ports */
 		init_config_port_offloads(pid, socket_id);
@@ -1823,7 +1833,7 @@ init_config(void)
 			mempools[i] = mbuf_pool_create
 					(mbuf_data_size[i],
 					 nb_mbuf_per_pool,
-					 SOCKET_ID_ANY, i);
+					 uma_socket_id(), i);
 		}
 	}
 
@@ -1841,7 +1851,8 @@ init_config(void)
 			rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]));
 
 		if (mbp == NULL)
-			mbp = mbuf_pool_find_first(0);
+			mbp = mbuf_pool_find_first(numa_support ?
+				0 : uma_socket_id());
 		fwd_lcores[lc_id]->mbp = mbp;
 #ifdef RTE_LIB_GSO
 		/* initialize GSO context */
@@ -1920,10 +1931,7 @@ init_fwd_streams(void)
 			}
 		}
 		else {
-			if (socket_num == UMA_NO_CONFIG)
-				port->socket_id = 0;
-			else
-				port->socket_id = socket_num;
+			port->socket_id = uma_socket_id();
 		}
 	}
 
@@ -3153,8 +3161,7 @@ start_port(portid_t pid)
 				} else {
 					struct rte_mempool *mp =
 						mbuf_pool_find_first
-							((numa_support ? port->socket_id :
-							(unsigned int)SOCKET_ID_ANY));
+							(port->socket_id);
 					if (mp == NULL) {
 						fprintf(stderr,
 							"Failed to setup RX queue: No mempool allocation on the socket %d\n",
-- 
2.53.0


^ permalink raw reply related

* [PATCH 0/4] app/testpmd: fix socket id handling with NUMA disabled
From: Stephen Hemminger @ 2026-07-02 16:10 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger
In-Reply-To: <20260702130729.26577-1-mkashani@nvidia.com>

Alternative to the patch "app/testpmd: fix multi-pool Rx setup with --no-NUMA"
from Maayan Kashani, fixing the problem at the source
rather than remapping inside mbuf_pool_find().

Since commit 835fd4893a31 ("app/testpmd: support cross-NUMA allocations"),
mbuf pools are created (and named) on SOCKET_ID_ANY
when NUMA support is disabled, but port->socket_id still holds 0/--socket-num.
Every name-based pool lookup that does not go through the single workaround in
start_port() misses. The reported multi-pool Rx failure is one instance; plain
"testpmd --no-numa --forward-mode=txonly" also crashes with a NULL
mempool dereference, and --socket-num no longer affects pool allocation.

Patch 1 restores the invariant that port->socket_id equals the
socket id the pools are created and named with, and removes the
start_port() workaround. It should go to stable (the regression
shipped in 25.07 and 25.11); it cherry-picks onto 25.11 with
trivial context conflicts and was build- and run-tested there.

Patch 2 consolidates the three diverging copies of the port socket
id policy into one helper; this also fixes hot-attached ports
ignoring --port-numa-config, --no-numa and --socket-num.

Patch 3 prints SOCKET_ID_ANY as "any" instead of 4294967295.

Patch 4 adds the error string to the interactive queue setup
command failure message; rte_eth_rx/tx_queue_setup() can return
-EBUSY silently when the port is started and the PMD lacks
runtime queue setup support.

Stephen Hemminger (4):
  app/testpmd: fix port socket ID with NUMA disabled
  app/testpmd: consolidate port socket ID computation
  app/testpmd: display any socket ID as text
  app/testpmd: report reason when queue setup command fails

 app/test-pmd/cmdline.c |  12 +++--
 app/test-pmd/config.c  |  18 ++++---
 app/test-pmd/testpmd.c | 120 +++++++++++++++++++++--------------------
 app/test-pmd/testpmd.h |  11 ++++
 4 files changed, 92 insertions(+), 69 deletions(-)

-- 
2.53.0


^ permalink raw reply

* [PATCH] app/testpmd: fix multi-pool Rx setup with --no-NUMA
From: Maayan Kashani @ 2026-07-02 13:07 UTC (permalink / raw)
  To: dev; +Cc: mkashani, rasland, stable, Aman Singh, Thomas Monjalon,
	Gregory Etelson

When NUMA is disabled, mbuf pools are allocated on SOCKET_ID_ANY,
but rx_queue_setup() looked them up using port->socket_id. Per-segment
pool lookup failed and all segments fell back to the first pool,
causing Rx queue setup to fail when a later segment needed a larger
mbuf (e.g. --mbuf-size=314,978 --rxpkts=186,978).

Check numa_support inside mbuf_pool_find() and drop the duplicate
NUMA socket remapping from start_port().

Fixes: 0be0ad196b52 ("app/testpmd: support selective Rx")
Cc: stable@dpdk.org

Signed-off-by: Maayan Kashani <mkashani@nvidia.com>
---
 app/test-pmd/testpmd.c | 3 +--
 app/test-pmd/testpmd.h | 3 +++
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index fcd8a909670..9a85657840a 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -3153,8 +3153,7 @@ start_port(portid_t pid)
 				} else {
 					struct rte_mempool *mp =
 						mbuf_pool_find_first
-							((numa_support ? port->socket_id :
-							(unsigned int)SOCKET_ID_ANY));
+							(port->socket_id);
 					if (mp == NULL) {
 						fprintf(stderr,
 							"Failed to setup RX queue: No mempool allocation on the socket %d\n",
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 3d4b36d6683..c1f3650f484 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -891,6 +891,9 @@ mbuf_pool_find(unsigned int sock_id, uint16_t idx)
 {
 	char pool_name[RTE_MEMPOOL_NAMESIZE];
 
+	if (!numa_support)
+		sock_id = (unsigned int)SOCKET_ID_ANY;
+
 	mbuf_poolname_build(sock_id, pool_name, sizeof(pool_name), idx);
 	return rte_mempool_lookup((const char *)pool_name);
 }
-- 
2.21.0


^ permalink raw reply related

* Re: [PATCH 0/2] fix dmadev incomplete ABI validation
From: fengchengwen @ 2026-07-02 12:50 UTC (permalink / raw)
  To: David Marchand; +Cc: datshan, thomas, dev, Stephen Hemminger, Bruce Richardson
In-Reply-To: <CAJFAV8ytRF4jjsM=Euoij3=76BgRCCZPk-7MX7iCWv4zetz6yg@mail.gmail.com>

On 7/2/2026 2:52 PM, David Marchand wrote:
> On Thu, 2 Jul 2026 at 03:35, fengchengwen <fengchengwen@huawei.com> wrote:
>>
>> On 7/2/2026 1:01 AM, David Marchand wrote:
>>> On Wed, 1 Jul 2026 at 10:11, David Marchand <david.marchand@redhat.com> wrote:
>>>> On Tue, 30 Jun 2026 at 15:24, <datshan@qq.com> wrote:
>>>>>
>>>>> From: datshan <datshan@qq.com>
>>>>>
>>>>> Fix dmadev incomplete ABI validation.
>>>>>
>>>>> Chengwen Feng (2):
>>>>>   dmadev: fix incomplete configuration validation
>>>>>   test/dmadev: add config and vchan validation tests
>>>>>
>>>>>  app/test/test_dmadev_api.c | 186 ++++++++++++++++++++++++++++++++++---
>>>>>  lib/dmadev/rte_dmadev.c    | 156 +++++++++++++++++++++----------
>>>>>  2 files changed, 283 insertions(+), 59 deletions(-)
>>>>>
>>>>
>>>> This series is not versionned, but I guess this is a new revision.
>>>> Don't forget to flag your submissions with a version number in the future.
>>>> I marked the previous patches as superseded in patchwork.
>>>>
>>>> Also provide a high level summary of the differences between versions.
>>>>
>>>> All of those steps are listed in the contributing guide, I suggest
>>>> (re-)reading the whole guide, with a highlight on:
>>>> https://doc.dpdk.org/guides/contributing/patches.html#steps-to-getting-your-patch-merged
>>>>
>>>> Thanks, I'll try to find some time to review this week.
>>>
>>> Well, enforcing *now* that some fields are 0 is actually breaking ABI
>>> for existing applications.
>>> This change should be deferred to 26.11, and backporting to a LTS is
>>> not possible.
>>
>> OK
>> BTW: Should I submit another version in 26.11 cycle or do nothing?
> 
> I'll mark those patches as Deferred in patchwork.
> That's enough, I will apply them after 26.11-rc0.

Thanks

> 
> 


^ permalink raw reply

* Re: [PATCH v2 1/5] examples/l3fwd-power: fix uncore deinit for non-legacy
From: Macnamara, Chris @ 2026-07-02 11:06 UTC (permalink / raw)
  To: Huisong Li, anatoly.burakov, sivaprasad.tummala
  Cc: dev, thomas, stephen, fengchengwen, yangxingui, zhanjie9,
	john.mcnamara
In-Reply-To: <20260526081138.1434947-2-lihuisong@huawei.com>

> Uncore resources were not being deinitialized in non-legacy modes (such
> as pmd-mgmt), causing the uncore frequency not to return to its original
> value after the application exited.
>
> The root cause is that uncore initialization can be performed for all
> modes, whereas the deinitialization logic is incorrectly restricted
> to legacy mode only. So do the deinitialization of uncore on all app
> modes.
>
> Fixes: 10db2a5b8724 ("examples/l3fwd-power: add options for uncore frequency")
> Cc: stable@dpdk.org
>
> Signed-off-by: Huisong Li <lihuisong@huawei.com>
> ---
>   examples/l3fwd-power/main.c | 66 ++++++++++++++++++++-----------------
>   1 file changed, 35 insertions(+), 31 deletions(-)
>
> diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
> index 02ec17d799..1122aeb930 100644
> --- a/examples/l3fwd-power/main.c
> +++ b/examples/l3fwd-power/main.c
> @@ -2271,28 +2271,31 @@ init_power_library(void)
>   	unsigned int lcore_id;
>   	int ret = 0;
>   
> -	RTE_LCORE_FOREACH(lcore_id) {
> -		/* init power management library */
> -		ret = rte_power_init(lcore_id);
> -		if (ret) {
> -			RTE_LOG(ERR, L3FWD_POWER,
> -				"Library initialization failed on core %u\n",
> -				lcore_id);
> -			return ret;
> -		}
> -		/* we're not supporting the VM channel mode */
> -		env = rte_power_get_env();
> -		if (env != PM_ENV_ACPI_CPUFREQ &&
> -				env != PM_ENV_PSTATE_CPUFREQ &&
> -				env != PM_ENV_AMD_PSTATE_CPUFREQ &&
> -				env != PM_ENV_CPPC_CPUFREQ) {
> -			RTE_LOG(ERR, L3FWD_POWER,
> -				"Only ACPI and PSTATE mode are supported\n");
> -			return -1;
> +	/* only legacy mode relies on the initialization of cpufreq library */
> +	if (app_mode == APP_MODE_LEGACY) {
> +		RTE_LCORE_FOREACH(lcore_id) {
> +			/* init power management library */
> +			ret = rte_power_init(lcore_id);
> +			if (ret) {
> +				RTE_LOG(ERR, L3FWD_POWER,
> +					"Library initialization failed on core %u\n",
> +					lcore_id);
> +				return ret;
> +			}
> +			/* we're not supporting the VM channel mode */
> +			env = rte_power_get_env();
> +			if (env != PM_ENV_ACPI_CPUFREQ &&
> +					env != PM_ENV_PSTATE_CPUFREQ &&
> +					env != PM_ENV_AMD_PSTATE_CPUFREQ &&
> +					env != PM_ENV_CPPC_CPUFREQ) {
> +				RTE_LOG(ERR, L3FWD_POWER,
> +					"Only ACPI and PSTATE mode are supported\n");
> +				return -1;
> +			}
>   		}
>   	}
>   
> -	if (cpu_resume_latency != -1) {
> +	if (app_mode == APP_MODE_LEGACY && cpu_resume_latency != -1) {
>   		RTE_LCORE_FOREACH(lcore_id) {
>   			/* Back old CPU resume latency. */
>   			ret = rte_power_qos_get_cpu_resume_latency(lcore_id);
> @@ -2329,14 +2332,16 @@ deinit_power_library(void)
>   	unsigned int lcore_id, max_pkg, max_die, die, pkg;
>   	int ret = 0;
>   
> -	RTE_LCORE_FOREACH(lcore_id) {
> -		/* deinit power management library */
> -		ret = rte_power_exit(lcore_id);
> -		if (ret) {
> -			RTE_LOG(ERR, L3FWD_POWER,
> -				"Library deinitialization failed on core %u\n",
> -				lcore_id);
> -			return ret;
> +	if (app_mode == APP_MODE_LEGACY) {
> +		RTE_LCORE_FOREACH(lcore_id) {
> +			/* deinit power management library */
> +			ret = rte_power_exit(lcore_id);
> +			if (ret) {
> +				RTE_LOG(ERR, L3FWD_POWER,
> +					"Library deinitialization failed on core %u\n",
> +					lcore_id);
> +				return ret;
> +			}
>   		}
>   	}
>   
> @@ -2360,7 +2365,7 @@ deinit_power_library(void)
>   		}
>   	}
>   
> -	if (cpu_resume_latency != -1) {
> +	if (app_mode == APP_MODE_LEGACY && cpu_resume_latency != -1) {
>   		RTE_LCORE_FOREACH(lcore_id) {
>   			/* Restore the original value. */
>   			rte_power_qos_set_cpu_resume_latency(lcore_id,

Agree there is an issue with uncore deinit.

cpu_resume_latency & init_power_library: After this patch, 
cpu_resume_latency (for C-state PM QoS control) is gated behind 
APP_MODE_LEGACY even though it's orthogonal to the cpufreq library, so 
it's silently ignored in pmd-mgmt/interrupt modes. It’s used for C state 
management which applies in other modes such as interrupt mode.

Also init_power_library() now has both its blocks legacy-guarded 
internally, the newly-unconditional call by removing APP_MODE_LEGACY to 
it is a no-op in non-legacy modes. This leaves the two functions 
inconsistent: init_power_library() does nothing outside legacy mode, 
whereas deinit_power_library() still has real work to do in every mode 
because of the uncore cleanup.

Consider, keep the APP_MODE_LEGACY guard at the init call site as the 
init is truly legacy only or split the uncore teardown into its own 
deinit_uncore() so that deinit_power_library() stays strictly about 
cpufreq.


^ permalink raw reply

* [PATCH v2] app/flow-perf: add represented-port/port-representor actions
From: Hadi Sandid @ 2026-07-02  8:56 UTC (permalink / raw)
  To: wisamm; +Cc: dev, Hadi Sandid
In-Reply-To: <20260701150422.57359-1-hadisandid@gmail.com>

Add 'represented-port' and 'port-representor' action support,
and update documentation.

Signed-off-by: Hadi Sandid <hadisandid@gmail.com>
---
v2:
  - use per-lcore port-action configurations during concurrent flow creation
  - clarify port redirection actions and destination option handling

 .mailmap                         |  1 +
 app/test-flow-perf/actions_gen.c | 46 ++++++++++++++++++++++++++++----
 app/test-flow-perf/main.c        | 31 ++++++++++++++++-----
 doc/guides/tools/flow-perf.rst   | 42 ++++++++++++++++++++++++-----
 4 files changed, 102 insertions(+), 18 deletions(-)

diff --git a/.mailmap b/.mailmap
index c5bc728fae..c51b14fbda 100644
--- a/.mailmap
+++ b/.mailmap
@@ -557,6 +557,7 @@ Guruprasad Rao <guruprasadx.rao@intel.com>
 Guy Kaneti <guyk@marvell.com>
 Guy Tzalik <gtzalik@amazon.com>
 H. Peter Anvin <hpa@linux.intel.com>
+Hadi Sandid <hadisandid@gmail.com>
 Haggai Eran <haggaie@nvidia.com>
 Haifei Luo <haifeil@nvidia.com>
 Haifeng Gao <gaohaifeng.gao@huawei.com>
diff --git a/app/test-flow-perf/actions_gen.c b/app/test-flow-perf/actions_gen.c
index 9d102e3af4..2a1fca9d7a 100644
--- a/app/test-flow-perf/actions_gen.c
+++ b/app/test-flow-perf/actions_gen.c
@@ -178,13 +178,41 @@ add_port_id(struct rte_flow_action *actions,
 	uint8_t actions_counter,
 	struct additional_para para)
 {
-	static struct rte_flow_action_port_id port_id = {
-		.id = PORT_ID_DST,
-	};
+	static alignas(RTE_CACHE_LINE_SIZE)
+	    struct rte_flow_action_port_id port_ids[RTE_MAX_LCORE];
+	uint8_t ti = para.core_idx;
 
-	port_id.id = para.dst_port;
+	port_ids[ti].id = para.dst_port;
 	actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_PORT_ID;
-	actions[actions_counter].conf = &port_id;
+	actions[actions_counter].conf = &port_ids[ti];
+}
+
+static void
+add_represented_port(struct rte_flow_action *actions,
+	uint8_t actions_counter,
+	struct additional_para para)
+{
+	static alignas(RTE_CACHE_LINE_SIZE)
+	    struct rte_flow_action_ethdev represented_ports[RTE_MAX_LCORE];
+	uint8_t ti = para.core_idx;
+
+	represented_ports[ti].port_id = para.dst_port;
+	actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT;
+	actions[actions_counter].conf = &represented_ports[ti];
+}
+
+static void
+add_port_representor(struct rte_flow_action *actions,
+	uint8_t actions_counter,
+	struct additional_para para)
+{
+	static alignas(RTE_CACHE_LINE_SIZE)
+	    struct rte_flow_action_ethdev port_representors[RTE_MAX_LCORE];
+	uint8_t ti = para.core_idx;
+
+	port_representors[ti].port_id = para.dst_port;
+	actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR;
+	actions[actions_counter].conf = &port_representors[ti];
 }
 
 static void
@@ -1102,6 +1130,14 @@ fill_actions(struct rte_flow_action *actions, uint64_t *flow_actions,
 			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_PORT_ID),
 			.funct = add_port_id
 		},
+		{
+			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT),
+			.funct = add_represented_port,
+		},
+		{
+			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR),
+			.funct = add_port_representor,
+		},
 		{
 			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_DROP),
 			.funct = add_drop,
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index 6636d1517f..646caccfda 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -267,6 +267,18 @@ static const struct option_dict {
 		.map = &flow_actions[0],
 		.map_idx = &actions_idx
 	},
+	{
+		.str = "represented-port",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "port-representor",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
 	{
 		.str = "rss",
 		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_RSS),
@@ -542,6 +554,8 @@ usage(char *progname)
 
 	printf("To set flow actions:\n");
 	printf("  --port-id: add port-id action in flow actions\n");
+	printf("  --represented-port: add represented-port action in flow actions\n");
+	printf("  --port-representor: add port-representor action in flow actions\n");
 	printf("  --rss: add rss action in flow actions\n");
 	printf("  --queue: add queue action in flow actions\n");
 	printf("  --jump: add jump action in flow actions\n");
@@ -699,6 +713,8 @@ args_parse(int argc, char **argv)
 		{ "icmpv6",                     0, 0, 0 },
 		/* Actions */
 		{ "port-id",                    2, 0, 0 },
+		{ "represented-port",           2, 0, 0 },
+		{ "port-representor",           2, 0, 0 },
 		{ "rss",                        0, 0, 0 },
 		{ "queue",                      0, 0, 0 },
 		{ "jump",                       0, 0, 0 },
@@ -913,14 +929,17 @@ args_parse(int argc, char **argv)
 					rte_exit(EXIT_FAILURE, "Invalid hairpin config mask\n");
 				hairpin_conf_mask = hp_conf;
 			}
-			if (strcmp(lgopts[opt_idx].name,
-					"port-id") == 0) {
+			if (strcmp(lgopts[opt_idx].name, "port-id") == 0 ||
+			    strcmp(lgopts[opt_idx].name, "represented-port") == 0 ||
+			    strcmp(lgopts[opt_idx].name, "port-representor") == 0) {
 				uint16_t port_idx = 0;
 
-				token = strtok(optarg, ",");
-				while (token != NULL) {
-					dst_ports[port_idx++] = atoi(token);
-					token = strtok(NULL, ",");
+				if (optarg != NULL) {
+					token = strtok(optarg, ",");
+					while (token != NULL) {
+						dst_ports[port_idx++] = atoi(token);
+						token = strtok(NULL, ",");
+					}
 				}
 			}
 			if (strcmp(lgopts[opt_idx].name, "rxq") == 0) {
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index 657f06fec7..aecbb846e3 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -240,13 +240,41 @@ Items:
 Actions:
 
 *	``--port-id``
-	Add port redirection action to all flows actions.
-	Port redirection destination is defined in user_parameters.h
-	under PORT_ID_DST, default value = 1.
-
-       It can also has optional parameter like --port-id=N[,M] to
-       specify the destination port, the number of values should be
-       the same with number of set bits in portmask.
+	Add an action that redirects matching traffic to a DPDK port ID.
+	As this action is deprecated; prefer ``--represented-port`` or
+	``--port-representor`` for embedded-switch flows when supported by
+	the PMD.
+	Port redirection destination is defined in config.h under
+	PORT_ID_DST, default value = 1.
+
+       Without an argument, ``PORT_ID_DST`` is used for each source port.
+       With ``--port-id=N[,M]``, the values override the destination for
+       enabled source ports in ``--portmask`` order; provide one value for
+       each set bit in the port mask.
+
+*	``--represented-port``
+	At the embedded-switch level, add an action that redirects matching
+	traffic to the entity represented by the specified ethdev. Use this
+	action when the destination is the represented entity.
+	Port redirection destination is defined in config.h under
+	PORT_ID_DST, default value = 1.
+
+		Without an argument, ``PORT_ID_DST`` is used for each source port.
+		With ``--represented-port=N[,M]``, the values override the destination
+		for enabled source ports in ``--portmask`` order; provide one value
+		for each set bit in the port mask.
+
+*	``--port-representor``
+	At the embedded-switch level, add an action that redirects matching
+	traffic to the specified ethdev. Use this action when the destination
+	is the ethdev rather than the entity it represents.
+	Port redirection destination is defined in config.h under
+	PORT_ID_DST, default value = 1.
+
+		Without an argument, ``PORT_ID_DST`` is used for each source port.
+		With ``--port-representor=N[,M]``, the values override the destination
+		for enabled source ports in ``--portmask`` order; provide one value
+		for each set bit in the port mask.
 
 *	``--rss``
 	Add RSS action to all flows actions,
-- 
2.43.0


^ permalink raw reply related

* RE: [PATCH 1/2] bpf: default log level should be NOTICE
From: Marat Khalili @ 2026-07-02  8:40 UTC (permalink / raw)
  To: Stephen Hemminger, dev@dpdk.org; +Cc: Konstantin Ananyev
In-Reply-To: <20260701223453.104660-1-stephen@networkplumber.org>

> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Wednesday 1 July 2026 23:35
> To: dev@dpdk.org
> Cc: Stephen Hemminger <stephen@networkplumber.org>; Konstantin Ananyev <konstantin.ananyev@huawei.com>;
> Marat Khalili <marat.khalili@huawei.com>
> Subject: [PATCH 1/2] bpf: default log level should be NOTICE
> 
> BPF is used by other services now and the default log
> level should match other libraries.
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
>  lib/bpf/bpf.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/lib/bpf/bpf.c b/lib/bpf/bpf.c
> index 740c080591..695454a2d4 100644
> --- a/lib/bpf/bpf.c
> +++ b/lib/bpf/bpf.c
> @@ -78,4 +78,4 @@ __rte_bpf_jit(struct rte_bpf *bpf)
>  	return rc;
>  }
> 
> -RTE_LOG_REGISTER_DEFAULT(rte_bpf_logtype, INFO);
> +RTE_LOG_REGISTER_DEFAULT(rte_bpf_logtype, NOTICE);
> --
> 2.53.0

Acked-by: Marat Khalili <marat.khalili@huawei.com>

(I wonder if this default should have a name like LIB_DEFAULT.)

^ permalink raw reply

* RE: [PATCH 2/2] bpf: silence noisy message
From: Marat Khalili @ 2026-07-02  8:36 UTC (permalink / raw)
  To: Stephen Hemminger, dev@dpdk.org; +Cc: Konstantin Ananyev
In-Reply-To: <20260701223453.104660-2-stephen@networkplumber.org>



> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Wednesday 1 July 2026 23:35
> To: dev@dpdk.org
> Cc: Stephen Hemminger <stephen@networkplumber.org>; Konstantin Ananyev <konstantin.ananyev@huawei.com>;
> Marat Khalili <marat.khalili@huawei.com>
> Subject: [PATCH 2/2] bpf: silence noisy message
> 
> The recent loader change causes a log message every time BPF
> is used. For example, running dpdk-dumpcap cause:
>  BPF: rte_bpf_load_ex(): successfully creates ...
> 
> This is a debug message and should not normally be needed.
> 
> Fixes: 55192fe168b9 ("bpf: introduce extensible load API")

The commit message and Fixes tag are not 100% accurate, this message existed before:
https://github.com/DPDK/dpdk/blob/09e4f37ddd0f7d5cc7c696741f31f1582c73a716/lib/bpf/bpf_load_elf.c#L331-L333

(In fact I tried to eliminate it, but had to but back at the insistence of AI reviewer
and even broke the build in the process...)

So naturally I support downgrading this message. With the commit message corrected,

Acked-by: Marat Khalili <marat.khalili@huawei.com>

> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
>  lib/bpf/bpf_load.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/lib/bpf/bpf_load.c b/lib/bpf/bpf_load.c
> index 2fd0ee0720..36f6556fd5 100644
> --- a/lib/bpf/bpf_load.c
> +++ b/lib/bpf/bpf_load.c
> @@ -286,7 +286,7 @@ rte_bpf_load_ex(const struct rte_bpf_prm_ex *prm)
>  		return NULL;
>  	}
> 
> -	RTE_BPF_LOG_FUNC_LINE(INFO, "successfully creates %p(jit={.func=%p,.sz=%zu});",
> +	RTE_BPF_LOG_FUNC_LINE(DEBUG, "successfully creates %p(jit={.func=%p,.sz=%zu});",
>  		load.bpf, load.bpf->jit.raw, load.bpf->jit.sz);
>  	return load.bpf;
>  }
> --
> 2.53.0


^ permalink raw reply

* Re: [PATCH] net/iavf: fix QinQ handling when only inner VLAN capability is supported
From: Bruce Richardson @ 2026-07-02  8:20 UTC (permalink / raw)
  To: Anurag Mandal; +Cc: dev, vladimir.medvedkin, stable
In-Reply-To: <20260701230858.436510-1-anurag.mandal@intel.com>

On Wed, Jul 01, 2026 at 11:08:58PM +0000, Anurag Mandal wrote:
> While adding support for QinQ stripping and insertion
> operations, it was assumed that Single VLAN
> operations are always reported through outer VLAN
> capabilities by the hardware.
> However, it seems that Single VLAN operations can
> also be reported through only inner VLAN capabilities
> as well by the hardware.
> 
> This patches fixes the same for QinQ operations.
> 
> Fixes: 8599d7604e0a ("net/iavf: support QinQ strip")
> Fixes: 7ce1363b424f ("net/iavf: support QinQ insertion")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Anurag Mandal <anurag.mandal@intel.com>
> ---
Acked-by: Bruce Richardson <bruce.richardson@intel.com>

Applied to dpdk-next-net-intel.
Thanks,
/Bruce


^ permalink raw reply

* Re: [PATCH 0/2] fix dmadev incomplete ABI validation
From: David Marchand @ 2026-07-02  6:52 UTC (permalink / raw)
  To: fengchengwen; +Cc: datshan, thomas, dev, Stephen Hemminger, Bruce Richardson
In-Reply-To: <257fb8fd-2850-4b31-aa9f-c1ef42897e7b@huawei.com>

On Thu, 2 Jul 2026 at 03:35, fengchengwen <fengchengwen@huawei.com> wrote:
>
> On 7/2/2026 1:01 AM, David Marchand wrote:
> > On Wed, 1 Jul 2026 at 10:11, David Marchand <david.marchand@redhat.com> wrote:
> >> On Tue, 30 Jun 2026 at 15:24, <datshan@qq.com> wrote:
> >>>
> >>> From: datshan <datshan@qq.com>
> >>>
> >>> Fix dmadev incomplete ABI validation.
> >>>
> >>> Chengwen Feng (2):
> >>>   dmadev: fix incomplete configuration validation
> >>>   test/dmadev: add config and vchan validation tests
> >>>
> >>>  app/test/test_dmadev_api.c | 186 ++++++++++++++++++++++++++++++++++---
> >>>  lib/dmadev/rte_dmadev.c    | 156 +++++++++++++++++++++----------
> >>>  2 files changed, 283 insertions(+), 59 deletions(-)
> >>>
> >>
> >> This series is not versionned, but I guess this is a new revision.
> >> Don't forget to flag your submissions with a version number in the future.
> >> I marked the previous patches as superseded in patchwork.
> >>
> >> Also provide a high level summary of the differences between versions.
> >>
> >> All of those steps are listed in the contributing guide, I suggest
> >> (re-)reading the whole guide, with a highlight on:
> >> https://doc.dpdk.org/guides/contributing/patches.html#steps-to-getting-your-patch-merged
> >>
> >> Thanks, I'll try to find some time to review this week.
> >
> > Well, enforcing *now* that some fields are 0 is actually breaking ABI
> > for existing applications.
> > This change should be deferred to 26.11, and backporting to a LTS is
> > not possible.
>
> OK
> BTW: Should I submit another version in 26.11 cycle or do nothing?

I'll mark those patches as Deferred in patchwork.
That's enough, I will apply them after 26.11-rc0.


-- 
David Marchand


^ permalink raw reply

* Re: [PATCH v5 17/19] drivers: release DPAA bpid on driver destructor
From: Hemant Agrawal @ 2026-07-02  5:34 UTC (permalink / raw)
  To: Stephen Hemminger, Hemant Agrawal; +Cc: david.marchand, dev, Jun Yang
In-Reply-To: <20260626095901.5bef5e05@phoenix.local>


On 26-06-2026 22:29, Stephen Hemminger wrote:
> On Fri, 26 Jun 2026 12:26:53 +0530
> Hemant Agrawal <hemant.agrawal@nxp.com> wrote:
>
>> From: Jun Yang <jun.yang@nxp.com>
>>
>> Track allocated BPIDs in a static per-BPID flag table and register a
>> driver destructor that releases any BPIDs still marked as in use at
>> process exit. This prevents BPID leaks when an application exits without
>> calling rte_mempool_free(). Also tune the per-lcore mempool cache flush
>> threshold to match the hardware bulk release size (DPAA_MBUF_MAX_ACQ_REL)
>> so that buffers are returned to HW in optimal burst sizes.
>>
>> Signed-off-by: Jun Yang <jun.yang@nxp.com>
>> ---
> Build with ASAN fails with this patch.
> Simple fix is usually replacing all use of rte_memcpy with memcpy.
> Rte_memcpy on x86 confuses ASAN and it thinks certain sizes reference past
> end of buffer. I would just do a global replace of rte_memcpy with memcpy
> across all of drivers/bus/dpaa none of this is performance critical on old
> versions of Gcc which is the only reason rte_memcpy still exists.
>
> This needs to be fixed before merging.

for now, I have fixed the affected patch. replaced it with memcpy.




^ permalink raw reply

* [PATCH v6 19/19] net/dpaa: add ONIC port checks
From: Hemant Agrawal @ 2026-07-02  5:33 UTC (permalink / raw)
  To: stephen, david.marchand, dev; +Cc: Vanshika Shukla
In-Reply-To: <20260702053359.3243907-1-hemant.agrawal@nxp.com>

From: Vanshika Shukla <vanshika.shukla@nxp.com>

Add fman_onic MAC type handling to get_rx_port_type() so that ONIC
and offline-internal ports are mapped to OH_OFFLINE_PARSING, consistent
with how the VSP port configuration handles these types. Without this,
ONIC ports used an incorrect port type in flow configuration, leading
to failed FMC operations.

Signed-off-by: Vanshika Shukla <vanshika.shukla@nxp.com>
---
 drivers/net/dpaa/dpaa_ethdev.c |  26 ++++---
 drivers/net/dpaa/dpaa_ethdev.h |  11 ++-
 drivers/net/dpaa/dpaa_flow.c   | 129 +++++++++++++++++----------------
 drivers/net/dpaa/dpaa_flow.h   |   7 +-
 4 files changed, 93 insertions(+), 80 deletions(-)

diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 30dfaa95d6..f285b35cbc 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -490,7 +490,7 @@ static int dpaa_eth_dev_stop(struct rte_eth_dev *dev)
 	PMD_INIT_FUNC_TRACE();
 	dev->data->dev_started = 0;
 
-	if (!fif->is_shared_mac) {
+	if (!fif->is_shared_mac && fif->mac_type != fman_onic) {
 		fman_if_bmi_stats_disable(fif);
 		fman_if_disable_rx(fif);
 	}
@@ -590,7 +590,7 @@ static int dpaa_eth_dev_close(struct rte_eth_dev *dev)
 		}
 	}
 	if (fif->num_profiles) {
-		ret = dpaa_port_vsp_cleanup(dpaa_intf, fif);
+		ret = dpaa_port_vsp_cleanup(dpaa_intf);
 		if (ret) {
 			DPAA_PMD_WARN("%s: cleanup VSP failed(%d)",
 				dev->data->name, ret);
@@ -676,7 +676,7 @@ static int dpaa_eth_dev_close(struct rte_eth_dev *dev)
 		}
 	}
 	if (fif->num_profiles) {
-		ret = dpaa_port_vsp_cleanup(dpaa_intf, fif);
+		ret = dpaa_port_vsp_cleanup(dpaa_intf);
 		if (ret) {
 			DPAA_PMD_WARN("%s: cleanup VSP failed(%d)",
 				dev->data->name, ret);
@@ -1136,8 +1136,8 @@ static inline int dpaa_eth_rx_queue_bp_check(struct rte_eth_dev *dev,
 			vsp_id = 0;
 	}
 
-	if (dpaa_intf->vsp_bpid[vsp_id] &&
-		bpid != dpaa_intf->vsp_bpid[vsp_id]) {
+	if (dpaa_intf->vsp[vsp_id].vsp_bp[0] &&
+		bpid != dpaa_intf->vsp[vsp_id].vsp_bp[0]->bpid) {
 		DPAA_PMD_ERR("Various MPs are assigned to RXQs with same VSP");
 
 		return -1;
@@ -1234,9 +1234,9 @@ int dpaa_eth_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 		int8_t vsp_id = rxq->vsp_id;
 
 		if (vsp_id >= 0) {
-			ret = dpaa_port_vsp_update(dpaa_intf, fmc_q, vsp_id,
-					DPAA_MEMPOOL_TO_POOL_INFO(mp)->bpid,
-					fif, buffsz + RTE_PKTMBUF_HEADROOM);
+			dpaa_intf->vsp[vsp_id].vsp_bp[0] = DPAA_MEMPOOL_TO_POOL_INFO(mp);
+			dpaa_intf->vsp[vsp_id].bp_num = 1;
+			ret = dpaa_port_vsp_update(dpaa_intf, fmc_q, vsp_id, fif);
 			if (ret) {
 				DPAA_PMD_ERR("dpaa_port_vsp_update failed");
 				return ret;
@@ -1249,12 +1249,14 @@ int dpaa_eth_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 					     " to shared interface on DPDK.");
 				return -EINVAL;
 			}
-			dpaa_intf->vsp_bpid[fif->base_profile_id] =
-				DPAA_MEMPOOL_TO_POOL_INFO(mp)->bpid;
+			dpaa_intf->vsp[fif->base_profile_id].vsp_bp[0] =
+				DPAA_MEMPOOL_TO_POOL_INFO(mp);
+			dpaa_intf->vsp[fif->base_profile_id].bp_num = 1;
 		}
 	} else {
-		dpaa_intf->vsp_bpid[0] =
-			DPAA_MEMPOOL_TO_POOL_INFO(mp)->bpid;
+		dpaa_intf->vsp[0].vsp_bp[0] =
+			DPAA_MEMPOOL_TO_POOL_INFO(mp);
+		dpaa_intf->vsp[0].bp_num = 1;
 	}
 
 	dpaa_intf->valid = 1;
diff --git a/drivers/net/dpaa/dpaa_ethdev.h b/drivers/net/dpaa/dpaa_ethdev.h
index d342d98f23..d3e005b556 100644
--- a/drivers/net/dpaa/dpaa_ethdev.h
+++ b/drivers/net/dpaa/dpaa_ethdev.h
@@ -118,6 +118,13 @@ enum {
 
 #define FMC_FILE "/tmp/fmc.bin"
 
+struct dpaa_if_vsp {
+	struct dpaa_bp_info *vsp_bp[FMAN_PORT_MAX_EXT_POOLS_NUM];
+	uint8_t bp_num;
+	uint32_t max_size;
+	void *vsp_handle;
+};
+
 extern struct rte_mempool *dpaa_tx_sg_pool;
 
 /* PMD related logs */
@@ -164,8 +171,8 @@ struct dpaa_if {
 	 */
 	struct qman_fq *next_tx_conf_queue;
 
-	void *vsp_handle[DPAA_VSP_PROFILE_MAX_NUM];
-	uint32_t vsp_bpid[DPAA_VSP_PROFILE_MAX_NUM];
+	struct dpaa_if_vsp vsp[DPAA_VSP_PROFILE_MAX_NUM];
+	uint8_t base_vsp;
 };
 
 struct dpaa_if_stats {
diff --git a/drivers/net/dpaa/dpaa_flow.c b/drivers/net/dpaa/dpaa_flow.c
index 559850ced7..a10ca0cb56 100644
--- a/drivers/net/dpaa/dpaa_flow.c
+++ b/drivers/net/dpaa/dpaa_flow.c
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright 2017-2019,2021-2025 NXP
+ * Copyright 2017-2019,2021-2026 NXP
  */
 
 /* System headers */
@@ -8,6 +8,7 @@
 #include <unistd.h>
 #include <sys/types.h>
 
+#include <dpaa_mempool.h>
 #include <dpaa_ethdev.h>
 #include <dpaa_flow.h>
 #include <rte_dpaa_logs.h>
@@ -724,9 +725,6 @@ int dpaa_fm_deconfig(struct dpaa_if *dpaa_intf,
 
 	PMD_INIT_FUNC_TRACE();
 
-	if (!dpaa_intf->port_handle)
-		return 0;
-
 	/* FM PORT Disable */
 	ret = fm_port_disable(dpaa_intf->port_handle);
 	if (ret != E_OK) {
@@ -786,8 +784,10 @@ int dpaa_fm_config(struct rte_eth_dev *dev, uint64_t req_dist_set)
 	unsigned int i = 0;
 	PMD_INIT_FUNC_TRACE();
 
-	if (dpaa_fm_deconfig(dpaa_intf, fif))
-		DPAA_PMD_ERR("DPAA FM deconfig failed");
+	if (dpaa_intf->port_handle) {
+		if (dpaa_fm_deconfig(dpaa_intf, fif))
+			DPAA_PMD_ERR("DPAA FM deconfig failed");
+	}
 
 	if (!dev->data->nb_rx_queues)
 		return 0;
@@ -806,8 +806,7 @@ int dpaa_fm_config(struct rte_eth_dev *dev, uint64_t req_dist_set)
 
 	if (fif->num_profiles) {
 		for (i = 0; i < dev->data->nb_rx_queues; i++)
-			dpaa_intf->rx_queues[i].vsp_id =
-				fm_default_vsp_id(fif);
+			dpaa_intf->rx_queues[i].vsp_id = fm_default_vsp_id(fif);
 
 		i = 0;
 	}
@@ -939,27 +938,16 @@ int dpaa_fm_term(void)
 }
 
 static int dpaa_port_vsp_configure(struct dpaa_if *dpaa_intf,
-		uint8_t vsp_id, t_handle fman_handle,
-		struct fman_if *fif, u32 mbuf_data_room_size)
+		uint8_t vsp_id, t_handle fman_handle, struct fman_if *fif)
 {
+	struct dpaa_if_vsp *vsp;
 	t_fm_vsp_params vsp_params;
 	t_fm_buffer_prefix_content buf_prefix_cont;
-	uint8_t idx = mac_idx[fif->mac_idx];
+	uint8_t idx = mac_idx[fif->mac_idx], i;
 	int ret;
+	struct t_fm_ext_pools *pools;
 
-	if (vsp_id == fif->base_profile_id && fif->is_shared_mac) {
-		/* For shared interface, VSP of base
-		 * profile is default pool located in kernel.
-		 */
-		dpaa_intf->vsp_bpid[vsp_id] = 0;
-		return 0;
-	}
-
-	if (vsp_id >= DPAA_VSP_PROFILE_MAX_NUM) {
-		DPAA_PMD_ERR("VSP ID %d exceeds MAX number %d",
-			vsp_id, DPAA_VSP_PROFILE_MAX_NUM);
-		return -1;
-	}
+	vsp = &dpaa_intf->vsp[vsp_id];
 
 	memset(&vsp_params, 0, sizeof(vsp_params));
 	vsp_params.h_fm = fman_handle;
@@ -973,17 +961,21 @@ static int dpaa_port_vsp_configure(struct dpaa_if *dpaa_intf,
 	vsp_params.port_params.port_type = get_rx_port_type(fif);
 	if (vsp_params.port_params.port_type == e_FM_PORT_TYPE_DUMMY) {
 		DPAA_PMD_ERR("Mac type %d error", fif->mac_type);
-		return -1;
+		return -EINVAL;
 	}
 
-	vsp_params.ext_buf_pools.num_of_pools_used = 1;
-	vsp_params.ext_buf_pools.ext_buf_pool[0].id = dpaa_intf->vsp_bpid[vsp_id];
-	vsp_params.ext_buf_pools.ext_buf_pool[0].size = mbuf_data_room_size;
+	pools = &vsp_params.ext_buf_pools;
 
-	dpaa_intf->vsp_handle[vsp_id] = fm_vsp_config(&vsp_params);
-	if (!dpaa_intf->vsp_handle[vsp_id]) {
-		DPAA_PMD_ERR("fm_vsp_config error for profile %d", vsp_id);
-		return -EINVAL;
+	pools->num_of_pools_used = vsp->bp_num;
+	for (i = 0; i < vsp->bp_num; i++) {
+		pools->ext_buf_pool[i].id = vsp->vsp_bp[i]->bpid;
+		pools->ext_buf_pool[i].size = vsp->vsp_bp[i]->size;
+	}
+
+	vsp->vsp_handle = fm_vsp_config(&vsp_params);
+	if (!vsp->vsp_handle) {
+		DPAA_PMD_ERR("Configure VSP[%d] failed!", vsp_id);
+		return -EIO;
 	}
 
 	/* configure the application buffer (structure, size and
@@ -1001,19 +993,18 @@ static int dpaa_port_vsp_configure(struct dpaa_if *dpaa_intf,
 	buf_prefix_cont.manip_ext_space =
 		RTE_PKTMBUF_HEADROOM - DPAA_MBUF_HW_ANNOTATION;
 
-	ret = fm_vsp_config_buffer_prefix_content(dpaa_intf->vsp_handle[vsp_id],
-					       &buf_prefix_cont);
+	ret = fm_vsp_config_buffer_prefix_content(vsp->vsp_handle,
+			&buf_prefix_cont);
 	if (ret != E_OK) {
-		DPAA_PMD_ERR("fm_vsp_config_buffer_prefix_content error for profile %d err: %d",
-			     vsp_id, ret);
+		DPAA_PMD_ERR("Configure VSP[%d]'s buffer prefix failed(%d)!",
+			vsp_id, ret);
 		return ret;
 	}
 
 	/* initialize the FM VSP module */
-	ret = fm_vsp_init(dpaa_intf->vsp_handle[vsp_id]);
+	ret = fm_vsp_init(vsp->vsp_handle);
 	if (ret != E_OK) {
-		DPAA_PMD_ERR("fm_vsp_init error for profile %d err:%d",
-			 vsp_id, ret);
+		DPAA_PMD_ERR("Init VSP[%d] failed(%d)!", vsp_id, ret);
 		return ret;
 	}
 
@@ -1021,29 +1012,44 @@ static int dpaa_port_vsp_configure(struct dpaa_if *dpaa_intf,
 }
 
 int dpaa_port_vsp_update(struct dpaa_if *dpaa_intf,
-		bool fmc_mode, uint8_t vsp_id, uint32_t bpid,
-		struct fman_if *fif, u32 mbuf_data_room_size)
+		bool fmc_mode, uint8_t vsp_id, struct fman_if *fif)
 {
 	int ret = 0;
 	t_handle fman_handle;
+	struct dpaa_if_vsp *vsp;
 
-	if (!fif->num_profiles)
-		return 0;
+	if (!fif->num_profiles) {
+		DPAA_PMD_ERR("%s: No multiple VSPs specified!",
+			dpaa_intf->name);
+		return -EINVAL;
+	}
 
-	if (vsp_id >= fif->num_profiles)
-		return 0;
+	if (vsp_id >= (fif->base_profile_id + fif->num_profiles)) {
+		DPAA_PMD_ERR("%s: Invalid VSP ID(%d) >= base(%d) + num(%d)",
+			dpaa_intf->name, vsp_id, fif->base_profile_id,
+			fif->num_profiles);
+		return -EINVAL;
+	}
 
-	if (dpaa_intf->vsp_bpid[vsp_id] == bpid)
+	if (vsp_id == fif->base_profile_id && fif->is_shared_mac) {
+		/* For shared interface, VSP of base
+		 * profile is default pool located in kernel.
+		 */
+		dpaa_intf->vsp[vsp_id].bp_num = 0;
+		dpaa_intf->vsp[vsp_id].vsp_handle = NULL;
 		return 0;
+	}
+
+	vsp = &dpaa_intf->vsp[vsp_id];
 
-	if (dpaa_intf->vsp_handle[vsp_id]) {
-		ret = fm_vsp_free(dpaa_intf->vsp_handle[vsp_id]);
+	if (vsp->vsp_handle) {
+		ret = fm_vsp_free(vsp->vsp_handle);
 		if (ret != E_OK) {
-			DPAA_PMD_ERR("Error fm_vsp_free: err %d vsp_handle[%d]",
-				     ret, vsp_id);
+			DPAA_PMD_ERR("Free VSP[%d]'s handle failed(%d)",
+				vsp_id, ret);
 			return ret;
 		}
-		dpaa_intf->vsp_handle[vsp_id] = 0;
+		vsp->vsp_handle = NULL;
 	}
 
 	if (fmc_mode)
@@ -1051,24 +1057,23 @@ int dpaa_port_vsp_update(struct dpaa_if *dpaa_intf,
 	else
 		fman_handle = fm_info.fman_handle;
 
-	dpaa_intf->vsp_bpid[vsp_id] = bpid;
-
-	return dpaa_port_vsp_configure(dpaa_intf, vsp_id, fman_handle, fif,
-				       mbuf_data_room_size);
+	return dpaa_port_vsp_configure(dpaa_intf, vsp_id, fman_handle, fif);
 }
 
-int dpaa_port_vsp_cleanup(struct dpaa_if *dpaa_intf, struct fman_if *fif)
+int dpaa_port_vsp_cleanup(struct dpaa_if *dpaa_intf)
 {
-	int idx, ret;
+	int ret;
+	uint8_t idx;
 
-	for (idx = 0; idx < (uint8_t)fif->num_profiles; idx++) {
-		if (dpaa_intf->vsp_handle[idx]) {
-			ret = fm_vsp_free(dpaa_intf->vsp_handle[idx]);
+	for (idx = 0; idx < DPAA_VSP_PROFILE_MAX_NUM; idx++) {
+		if (dpaa_intf->vsp[idx].vsp_handle) {
+			ret = fm_vsp_free(dpaa_intf->vsp[idx].vsp_handle);
 			if (ret != E_OK) {
-				DPAA_PMD_ERR("Error fm_vsp_free: err %d"
-					     " vsp_handle[%d]", ret, idx);
+				DPAA_PMD_ERR("Free VSP[%d] failed(%d)",
+					idx, ret);
 				return ret;
 			}
+			dpaa_intf->vsp[idx].vsp_handle = NULL;
 		}
 	}
 
diff --git a/drivers/net/dpaa/dpaa_flow.h b/drivers/net/dpaa/dpaa_flow.h
index 4742b8dd0a..6a949d6dd4 100644
--- a/drivers/net/dpaa/dpaa_flow.h
+++ b/drivers/net/dpaa/dpaa_flow.h
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright 2017,2019,2022 NXP
+ * Copyright 2017,2019,2022,2026 NXP
  */
 
 #ifndef __DPAA_FLOW_H__
@@ -11,9 +11,8 @@ int dpaa_fm_config(struct rte_eth_dev *dev, uint64_t req_dist_set);
 int dpaa_fm_deconfig(struct dpaa_if *dpaa_intf, struct fman_if *fif);
 void dpaa_write_fm_config_to_file(void);
 int dpaa_port_vsp_update(struct dpaa_if *dpaa_intf,
-	bool fmc_mode, uint8_t vsp_id, uint32_t bpid, struct fman_if *fif,
-	u32 mbuf_data_room_size);
-int dpaa_port_vsp_cleanup(struct dpaa_if *dpaa_intf, struct fman_if *fif);
+	bool fmc_mode, uint8_t vsp_id, struct fman_if *fif);
+int dpaa_port_vsp_cleanup(struct dpaa_if *dpaa_intf);
 int dpaa_port_fmc_init(struct fman_if *fif,
 		       uint32_t *fqids, int8_t *vspids, int max_nb_rxq);
 
-- 
2.25.1


^ permalink raw reply related

* [PATCH v6 18/19] dma/dpaa: add SG data validation and ERR050757 fix
From: Hemant Agrawal @ 2026-07-02  5:33 UTC (permalink / raw)
  To: stephen, david.marchand, dev; +Cc: Gagandeep Singh
In-Reply-To: <20260702053359.3243907-1-hemant.agrawal@nxp.com>

From: Gagandeep Singh <g.singh@nxp.com>

Add scatter-gather (SG) support to the QDMA driver, enabled by default
via the s_sg_enable flag. Add optional data validation mode controlled
by the s_data_validation flag for debugging transfer correctness.

Add a workaround for hardware errata ERR050757: when
RTE_DMA_DPAA_ERRATA_ERR050757 is defined, configure the source frame
descriptor with stride settings (sss/ssd = FSL_QDMA_CMD_SS_ERR050757_LEN)
to force PCI read transactions to stay within the errata-safe length
limit, preventing data corruption on affected silicon.

Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
 drivers/dma/dpaa/dpaa_qdma.c | 79 +++++++++++++++++++++++++-----------
 1 file changed, 55 insertions(+), 24 deletions(-)

diff --git a/drivers/dma/dpaa/dpaa_qdma.c b/drivers/dma/dpaa/dpaa_qdma.c
index 3e1f60eab2..a631ee7368 100644
--- a/drivers/dma/dpaa/dpaa_qdma.c
+++ b/drivers/dma/dpaa/dpaa_qdma.c
@@ -9,9 +9,14 @@
 #include "dpaa_qdma.h"
 #include "dpaa_qdma_logs.h"
 
+static int s_data_validation;
+static int s_hw_err_check;
+static int s_sg_enable = 1;
 static uint32_t s_sg_max_entry_sz = 2000;
-static bool s_hw_err_check;
 
+#ifdef RTE_DMA_DPAA_ERRATA_ERR050757
+static int s_pci_read = 1;
+#endif
 #define DPAA_DMA_ERROR_CHECK "dpaa_dma_err_check"
 
 static inline void
@@ -112,7 +117,8 @@ dma_pool_alloc(char *nm, int size, int aligned, dma_addr_t *phy_addr)
 	if (!virt_addr)
 		return NULL;
 
-	*phy_addr = rte_mem_virt2iova(virt_addr);
+	if (phy_addr)
+		*phy_addr = rte_mem_virt2iova(virt_addr);
 
 	return virt_addr;
 }
@@ -392,6 +398,8 @@ fsl_qdma_data_validation(struct fsl_qdma_desc *desc[],
 	char err_msg[512];
 	int offset;
 
+	if (likely(!s_data_validation))
+		return;
 
 	offset = sprintf(err_msg, "Fatal TC%d/queue%d: ",
 		fsl_queue->block_id,
@@ -716,19 +724,21 @@ fsl_qdma_enqueue_desc_single(struct fsl_qdma_queue *fsl_queue,
 	ft = fsl_queue->ft[fsl_queue->ci];
 
 #ifdef RTE_DMA_DPAA_ERRATA_ERR050757
-	sdf = &ft->df.sdf;
-	sdf->srttype = FSL_QDMA_CMD_RWTTYPE;
+	if (s_pci_read) {
+		sdf = &ft->df.sdf;
+		sdf->srttype = FSL_QDMA_CMD_RWTTYPE;
 #ifdef RTE_DMA_DPAA_ERRATA_ERR050265
-	sdf->prefetch = 1;
+		sdf->prefetch = 1;
 #endif
-	if (len > FSL_QDMA_CMD_SS_ERR050757_LEN) {
-		sdf->ssen = 1;
-		sdf->sss = FSL_QDMA_CMD_SS_ERR050757_LEN;
-		sdf->ssd = FSL_QDMA_CMD_SS_ERR050757_LEN;
-	} else {
-		sdf->ssen = 0;
-		sdf->sss = 0;
-		sdf->ssd = 0;
+		if (len > FSL_QDMA_CMD_SS_ERR050757_LEN) {
+			sdf->ssen = 1;
+			sdf->sss = FSL_QDMA_CMD_SS_ERR050757_LEN;
+			sdf->ssd = FSL_QDMA_CMD_SS_ERR050757_LEN;
+		} else {
+			sdf->ssen = 0;
+			sdf->sss = 0;
+			sdf->ssd = 0;
+		}
 	}
 #endif
 	csgf_src = &ft->desc_sbuf;
@@ -832,19 +842,21 @@ fsl_qdma_enqueue_desc_sg(struct fsl_qdma_queue *fsl_queue)
 	csgf_src->length = total_len;
 	csgf_dest->length = total_len;
 #ifdef RTE_DMA_DPAA_ERRATA_ERR050757
-	sdf = &ft->df.sdf;
-	sdf->srttype = FSL_QDMA_CMD_RWTTYPE;
+	if (s_pci_read) {
+		sdf = &ft->df.sdf;
+		sdf->srttype = FSL_QDMA_CMD_RWTTYPE;
 #ifdef RTE_DMA_DPAA_ERRATA_ERR050265
-	sdf->prefetch = 1;
+		sdf->prefetch = 1;
 #endif
-	if (total_len > FSL_QDMA_CMD_SS_ERR050757_LEN) {
-		sdf->ssen = 1;
-		sdf->sss = FSL_QDMA_CMD_SS_ERR050757_LEN;
-		sdf->ssd = FSL_QDMA_CMD_SS_ERR050757_LEN;
-	} else {
-		sdf->ssen = 0;
-		sdf->sss = 0;
-		sdf->ssd = 0;
+		if (total_len > FSL_QDMA_CMD_SS_ERR050757_LEN) {
+			sdf->ssen = 1;
+			sdf->sss = FSL_QDMA_CMD_SS_ERR050757_LEN;
+			sdf->ssd = FSL_QDMA_CMD_SS_ERR050757_LEN;
+		} else {
+			sdf->ssen = 0;
+			sdf->sss = 0;
+			sdf->ssd = 0;
+		}
 	}
 #endif
 	ret = fsl_qdma_enqueue_desc_to_ring(fsl_queue, num);
@@ -883,6 +895,25 @@ fsl_qdma_enqueue_desc(struct fsl_qdma_queue *fsl_queue)
 			fsl_queue->pending_num = 0;
 		}
 		return ret;
+	} else if (!s_sg_enable) {
+		while (fsl_queue->pending_num > 0) {
+			ret = fsl_qdma_enqueue_desc_single(fsl_queue,
+				fsl_queue->pending_desc[start].dst,
+				fsl_queue->pending_desc[start].src,
+				fsl_queue->pending_desc[start].len);
+			if (!ret) {
+				start = (start + 1) &
+					(fsl_queue->pending_max - 1);
+				fsl_queue->pending_start = start;
+				fsl_queue->pending_num--;
+			} else {
+				DPAA_QDMA_ERR("Eq pending desc failed(%d)",
+					ret);
+				return -EIO;
+			}
+		}
+
+		return 0;
 	}
 
 	return fsl_qdma_enqueue_desc_sg(fsl_queue);
-- 
2.25.1


^ permalink raw reply related

* [PATCH v6 17/19] drivers: release DPAA bpid on driver destructor
From: Hemant Agrawal @ 2026-07-02  5:33 UTC (permalink / raw)
  To: stephen, david.marchand, dev; +Cc: Jun Yang
In-Reply-To: <20260702053359.3243907-1-hemant.agrawal@nxp.com>

From: Jun Yang <jun.yang@nxp.com>

Track allocated BPIDs in a static per-BPID flag table and register a
driver destructor that releases any BPIDs still marked as in use at
process exit. This prevents BPID leaks when an application exits without
calling rte_mempool_free(). Also tune the per-lcore mempool cache flush
threshold to match the hardware bulk release size (DPAA_MBUF_MAX_ACQ_REL)
so that buffers are returned to HW in optimal burst sizes.

Signed-off-by: Jun Yang <jun.yang@nxp.com>
---
 drivers/bus/dpaa/base/qbman/bman.c       |  8 +++
 drivers/bus/dpaa/dpaa_bus_base_symbols.c |  1 +
 drivers/bus/dpaa/include/fsl_bman.h      |  3 ++
 drivers/mempool/dpaa/dpaa_mempool.c      | 67 ++++++++++++++++++++++--
 drivers/mempool/dpaa/dpaa_mempool.h      |  3 +-
 5 files changed, 78 insertions(+), 4 deletions(-)

diff --git a/drivers/bus/dpaa/base/qbman/bman.c b/drivers/bus/dpaa/base/qbman/bman.c
index 225a8a9fd7..4286e6df6a 100644
--- a/drivers/bus/dpaa/base/qbman/bman.c
+++ b/drivers/bus/dpaa/base/qbman/bman.c
@@ -237,6 +237,14 @@ void bman_free_pool(struct bman_pool *pool)
 	kfree(pool);
 }
 
+void bman_free_bpid(u8 bpid, u32 flags)
+{
+	if (flags & BMAN_POOL_FLAG_THRESH)
+		bm_pool_set(bpid, zero_thresholds);
+	if (flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
+		bman_release_bpid(bpid);
+}
+
 const struct bman_pool_params *bman_get_params(const struct bman_pool *pool)
 {
 	return &pool->params;
diff --git a/drivers/bus/dpaa/dpaa_bus_base_symbols.c b/drivers/bus/dpaa/dpaa_bus_base_symbols.c
index 514ab7b1f1..8bd1a9bc6e 100644
--- a/drivers/bus/dpaa/dpaa_bus_base_symbols.c
+++ b/drivers/bus/dpaa/dpaa_bus_base_symbols.c
@@ -46,6 +46,7 @@ RTE_EXPORT_INTERNAL_SYMBOL(netcfg_acquire)
 RTE_EXPORT_INTERNAL_SYMBOL(netcfg_release)
 RTE_EXPORT_INTERNAL_SYMBOL(bman_new_pool)
 RTE_EXPORT_INTERNAL_SYMBOL(bman_free_pool)
+RTE_EXPORT_INTERNAL_SYMBOL(bman_free_bpid)
 RTE_EXPORT_INTERNAL_SYMBOL(bman_get_params)
 RTE_EXPORT_INTERNAL_SYMBOL(bman_release)
 RTE_EXPORT_INTERNAL_SYMBOL(bman_acquire)
diff --git a/drivers/bus/dpaa/include/fsl_bman.h b/drivers/bus/dpaa/include/fsl_bman.h
index 67a7a09618..6079eedff5 100644
--- a/drivers/bus/dpaa/include/fsl_bman.h
+++ b/drivers/bus/dpaa/include/fsl_bman.h
@@ -317,6 +317,9 @@ struct bman_pool *bman_new_pool(const struct bman_pool_params *params);
 __rte_internal
 void bman_free_pool(struct bman_pool *pool);
 
+__rte_internal
+void bman_free_bpid(u8 bpid, u32 flags);
+
 /**
  * bman_get_params - Returns a pool object's parameters.
  * @pool: the pool object
diff --git a/drivers/mempool/dpaa/dpaa_mempool.c b/drivers/mempool/dpaa/dpaa_mempool.c
index 3fdbcba646..210ea3bcf9 100644
--- a/drivers/mempool/dpaa/dpaa_mempool.c
+++ b/drivers/mempool/dpaa/dpaa_mempool.c
@@ -25,10 +25,22 @@
 #include <rte_eal.h>
 #include <rte_malloc.h>
 #include <rte_ring.h>
+#include <rte_common.h>
 
 #include <dpaa_mempool.h>
 #include <dpaax_iova_table.h>
 
+struct dpaa_bpid_flag {
+	uint32_t flags;
+	int used;
+};
+
+/** Be referenced in destructor to release bpid allocated.
+ * Destructor can't access bman_pool from eal mem,
+ * we release ID with flag directly.
+ */
+static struct dpaa_bpid_flag s_dpaa_bpid_allocated_flag[DPAA_MAX_BPOOLS];
+
 #define FMAN_ERRATA_BOUNDARY ((uint64_t)4096)
 #define FMAN_ERRATA_BOUNDARY_MASK (~(FMAN_ERRATA_BOUNDARY - 1))
 
@@ -58,6 +70,8 @@ dpaa_mbuf_create_pool(struct rte_mempool *mp)
 	struct bman_pool_params params = {
 		.flags = BMAN_POOL_FLAG_DYNAMIC_BPID
 	};
+	unsigned int lcore_id;
+	struct rte_mempool_cache *cache;
 
 	MEMPOOL_INIT_FUNC_TRACE();
 
@@ -115,7 +129,7 @@ dpaa_mbuf_create_pool(struct rte_mempool *mp)
 	rte_dpaa_bpid_info[bpid].ptov_off = 0;
 	rte_dpaa_bpid_info[bpid].flags = 0;
 
-	bp_info = rte_malloc(NULL,
+	bp_info = rte_zmalloc(NULL,
 			     sizeof(struct dpaa_bp_info),
 			     RTE_CACHE_LINE_SIZE);
 	if (!bp_info) {
@@ -127,6 +141,20 @@ dpaa_mbuf_create_pool(struct rte_mempool *mp)
 	rte_memcpy(bp_info, (void *)&rte_dpaa_bpid_info[bpid],
 		   sizeof(struct dpaa_bp_info));
 	mp->pool_data = (void *)bp_info;
+	s_dpaa_bpid_allocated_flag[bpid].flags = params.flags;
+	s_dpaa_bpid_allocated_flag[bpid].used = true;
+	/* Update per core mempool cache threshold to optimal value which is
+	 * number of buffers that can be released to HW buffer pool in
+	 * a single API call.
+	 */
+	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
+		cache = &mp->local_cache[lcore_id];
+		DPAA_MEMPOOL_DEBUG("lCore %d: cache->flushthresh %d -> %d",
+			lcore_id, cache->flushthresh,
+			(uint32_t)(cache->size + DPAA_MBUF_MAX_ACQ_REL));
+		if (cache->flushthresh)
+			cache->flushthresh = cache->size + DPAA_MBUF_MAX_ACQ_REL;
+	}
 
 	DPAA_MEMPOOL_INFO("BMAN pool created for bpid =%d", bpid);
 	return 0;
@@ -136,6 +164,7 @@ static void
 dpaa_mbuf_free_pool(struct rte_mempool *mp)
 {
 	struct dpaa_bp_info *bp_info = DPAA_MEMPOOL_TO_POOL_INFO(mp);
+	uint16_t i;
 
 	MEMPOOL_INIT_FUNC_TRACE();
 
@@ -143,10 +172,25 @@ dpaa_mbuf_free_pool(struct rte_mempool *mp)
 		bman_free_pool(bp_info->bp);
 		DPAA_MEMPOOL_INFO("BMAN pool freed for bpid =%d",
 				  bp_info->bpid);
-		rte_free(mp->pool_data);
-		bp_info->bp = NULL;
+		rte_dpaa_bpid_info[bp_info->bpid].mp = NULL;
+		rte_dpaa_bpid_info[bp_info->bpid].bp = NULL;
+		s_dpaa_bpid_allocated_flag[bp_info->bpid].used = false;
+		rte_free(bp_info);
 		mp->pool_data = NULL;
 	}
+
+	if (!rte_dpaa_bpid_info)
+		return;
+
+	for (i = 0; i < DPAA_MAX_BPOOLS; i++) {
+		if (rte_dpaa_bpid_info[i].mp)
+			break;
+	}
+
+	if (i == DPAA_MAX_BPOOLS) {
+		rte_free(rte_dpaa_bpid_info);
+		rte_dpaa_bpid_info = NULL;
+	}
 }
 
 static int
@@ -481,4 +525,21 @@ static const struct rte_mempool_ops dpaa_mpool_ops = {
 	.populate = dpaa_populate,
 };
 
+#define RTE_PRIORITY_104 104
+
+RTE_FINI_PRIO(dpaa_mpool_finish, 104)
+{
+	uint16_t bpid;
+
+	for (bpid = 0; bpid < DPAA_MAX_BPOOLS; bpid++) {
+		if (s_dpaa_bpid_allocated_flag[bpid].used) {
+			bman_free_bpid(bpid, s_dpaa_bpid_allocated_flag[bpid].flags);
+			s_dpaa_bpid_allocated_flag[bpid].used = false;
+		}
+	}
+	/** The rte_dpaa_bpid_info and bman_pool from EAL mem have been released
+	 * with EAL mem pool being destroyed.
+	 */
+}
+
 RTE_MEMPOOL_REGISTER_OPS(dpaa_mpool_ops);
diff --git a/drivers/mempool/dpaa/dpaa_mempool.h b/drivers/mempool/dpaa/dpaa_mempool.h
index 865b533b8f..d7ee49b557 100644
--- a/drivers/mempool/dpaa/dpaa_mempool.h
+++ b/drivers/mempool/dpaa/dpaa_mempool.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: BSD-3-Clause
  *
- *   Copyright 2017,2019,2024 -2025 NXP
+ *   Copyright 2017,2019,2024 -2026 NXP
  *
  */
 #ifndef __DPAA_MEMPOOL_H__
@@ -24,6 +24,7 @@
 
 /* total number of bpools on SoC */
 #define DPAA_MAX_BPOOLS	256
+#define DPAA_INVALID_BPID DPAA_MAX_BPOOLS
 
 /* Maximum release/acquire from BMAN */
 #define DPAA_MBUF_MAX_ACQ_REL  FSL_BM_BURST_MAX
-- 
2.25.1


^ permalink raw reply related

* [PATCH v6 16/19] drivers: optimize DPAA multi-entry buffer pool operations
From: Hemant Agrawal @ 2026-07-02  5:33 UTC (permalink / raw)
  To: stephen, david.marchand, dev; +Cc: Jun Yang
In-Reply-To: <20260702053359.3243907-1-hemant.agrawal@nxp.com>

From: Jun Yang <jun.yang@nxp.com>

Replace the hardcoded buffer acquire count of 8 with the FSL_BM_BURST_MAX
constant when acquiring buffers from the buffer pool. Use a single
bm_hw_buf_desc structure for HW initialization of the first entry and copy
it to remaining entries, ensuring consistent HW descriptor state across
all entries in the pool.

Signed-off-by: Jun Yang <jun.yang@nxp.com>
---
 drivers/bus/dpaa/base/qbman/bman.c  | 51 +++++++----------------------
 drivers/bus/dpaa/include/fsl_bman.h | 46 +++++++++++++++++++++-----
 drivers/mempool/dpaa/dpaa_mempool.c |  8 ++---
 3 files changed, 54 insertions(+), 51 deletions(-)

diff --git a/drivers/bus/dpaa/base/qbman/bman.c b/drivers/bus/dpaa/base/qbman/bman.c
index ee4232d0a0..225a8a9fd7 100644
--- a/drivers/bus/dpaa/base/qbman/bman.c
+++ b/drivers/bus/dpaa/base/qbman/bman.c
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  *
  * Copyright 2008-2016 Freescale Semiconductor Inc.
- * Copyright 2017, 2024 NXP
+ * Copyright 2017, 2024-2026 NXP
  *
  */
 #include <rte_memcpy.h>
@@ -17,20 +17,6 @@
 #define IRQNAME		"BMan portal %d"
 #define MAX_IRQNAME	16	/* big enough for "BMan portal %d" */
 
-
-#define MAX_U16 UINT16_MAX
-#define MAX_U32 UINT32_MAX
-#ifndef BIT_SIZE
-#define BIT_SIZE(t) (sizeof(t) * 8)
-#endif
-#define MAX_U48 \
-	((((uint64_t)MAX_U16) << BIT_SIZE(uint32_t)) | MAX_U32)
-#define HI16_OF_U48(x) \
-	(((x) >> BIT_SIZE(rte_be32_t)) & MAX_U16)
-#define LO32_OF_U48(x) ((x) & MAX_U32)
-#define U48_BY_HI16_LO32(hi, lo) \
-	(((hi) << BIT_SIZE(uint32_t)) | (lo))
-
 struct bman_portal {
 	struct bm_portal p;
 	/* 2-element array. pools[0] is mask, pools[1] is snapshot. */
@@ -273,7 +259,7 @@ bman_release_fast(struct bman_pool *pool, const uint64_t *bufs,
 	struct bm_rcr_entry *r;
 	uint8_t i, avail;
 	uint64_t bpid = pool->params.bpid;
-	struct bm_hw_buf_desc bm_bufs[FSL_BM_BURST_MAX];
+	struct bm_buffer bm_bufs[FSL_BM_BURST_MAX];
 
 #ifdef RTE_LIBRTE_DPAA_HWDEBUG
 	if (!num || (num > FSL_BM_BURST_MAX))
@@ -290,19 +276,17 @@ bman_release_fast(struct bman_pool *pool, const uint64_t *bufs,
 	if (unlikely(!r))
 		return -EBUSY;
 
+	bm_bufs[0].be_desc.bpid = bpid;
+	for (i = 0; i < num; i++)
+		bm_buffer_set64_to_be(&bm_bufs[i], bufs[i]);
 	/*
 	 * we can copy all but the first entry, as this can trigger badness
 	 * with the valid-bit
 	 */
-	bm_bufs[0].bpid = bpid;
-	bm_bufs[0].hi_addr = cpu_to_be16(HI16_OF_U48(bufs[0]));
-	bm_bufs[0].lo_addr = cpu_to_be32(LO32_OF_U48(bufs[0]));
-	for (i = 1; i < num; i++) {
-		bm_bufs[i].hi_addr = cpu_to_be16(HI16_OF_U48(bufs[i]));
-		bm_bufs[i].lo_addr = cpu_to_be32(LO32_OF_U48(bufs[i]));
-	}
-
-	memcpy(r->bufs, bm_bufs, sizeof(struct bm_buffer) * num);
+	r->bufs[0].opaque = bm_bufs[0].opaque;
+	if (num > 1)
+		memcpy(&r->bufs[1], &bm_bufs[1],
+			sizeof(struct bm_buffer) * (num - 1));
 
 	bm_rcr_pvb_commit(&p->p, BM_RCR_VERB_CMD_BPID_SINGLE |
 		(num & BM_RCR_VERB_BUFCOUNT_MASK));
@@ -360,16 +344,6 @@ __rte_unused bman_extract_addr(struct bm_buffer *buf)
 	return buf->addr;
 }
 
-static inline uint64_t
-bman_hw_extract_addr(struct bm_hw_buf_desc *buf)
-{
-	uint64_t hi, lo;
-
-	hi = be16_to_cpu(buf->hi_addr);
-	lo = be32_to_cpu(buf->lo_addr);
-	return U48_BY_HI16_LO32(hi, lo);
-}
-
 RTE_EXPORT_INTERNAL_SYMBOL(bman_acquire_fast)
 int
 bman_acquire_fast(struct bman_pool *pool, uint64_t *bufs, uint8_t num)
@@ -378,7 +352,7 @@ bman_acquire_fast(struct bman_pool *pool, uint64_t *bufs, uint8_t num)
 	struct bm_mc_command *mcc;
 	struct bm_mc_result *mcr;
 	uint8_t i, rst;
-	struct bm_hw_buf_desc bm_bufs[FSL_BM_BURST_MAX];
+	struct bm_buffer bm_bufs[FSL_BM_BURST_MAX];
 
 #ifdef RTE_LIBRTE_DPAA_HWDEBUG
 	if (!num || (num > FSL_BM_BURST_MAX))
@@ -397,11 +371,10 @@ bman_acquire_fast(struct bman_pool *pool, uint64_t *bufs, uint8_t num)
 	if (unlikely(rst < 1 || rst > FSL_BM_BURST_MAX))
 		return -EINVAL;
 
-	rte_memcpy(bm_bufs, mcr->acquire.bufs,
-		sizeof(struct bm_buffer) * rst);
+	rte_memcpy(bm_bufs, mcr->acquire.bufs, sizeof(struct bm_buffer) * rst);
 
 	for (i = 0; i < rst; i++)
-		bufs[i] = bman_hw_extract_addr(&bm_bufs[i]);
+		bufs[i] = bm_buffer_get64_from_be(&bm_bufs[i]);
 
 	return rst;
 }
diff --git a/drivers/bus/dpaa/include/fsl_bman.h b/drivers/bus/dpaa/include/fsl_bman.h
index 2d24b89889..67a7a09618 100644
--- a/drivers/bus/dpaa/include/fsl_bman.h
+++ b/drivers/bus/dpaa/include/fsl_bman.h
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  *
  * Copyright 2008-2012 Freescale Semiconductor, Inc.
- * Copyright 2024 NXP
+ * Copyright 2024-2026 NXP
  *
  */
 
@@ -42,6 +42,13 @@ struct bm_mc_result;	/* MC result */
  * pool id specific to this buffer is needed (BM_RCR_VERB_CMD_BPID_MULTI,
  * BM_MCC_VERB_ACQUIRE), the 'bpid' field is used.
  */
+struct __rte_packed_begin bm_hw_buf_desc {
+	uint8_t rsv;
+	uint8_t bpid;
+	rte_be16_t hi; /* High 16-bits of 48-bit address */
+	rte_be32_t lo; /* Low 32-bits of 48-bit address */
+} __rte_packed_end;
+
 struct __rte_aligned(8) bm_buffer {
 	union {
 		struct {
@@ -66,17 +73,11 @@ struct __rte_aligned(8) bm_buffer {
 			u64 __notaddress:16;
 #endif
 		};
+		struct bm_hw_buf_desc be_desc;
 		u64 opaque;
 	};
 };
 
-struct __rte_packed_begin bm_hw_buf_desc {
-	uint8_t rsv;
-	uint8_t bpid;
-	rte_be16_t hi_addr; /* High 16-bits of 48-bit address */
-	rte_be32_t lo_addr; /* Low 32-bits of 48-bit address */
-} __rte_packed_end;
-
 static inline u64 bm_buffer_get64(const struct bm_buffer *buf)
 {
 	return buf->addr;
@@ -87,6 +88,17 @@ static inline dma_addr_t bm_buf_addr(const struct bm_buffer *buf)
 	return (dma_addr_t)buf->addr;
 }
 
+#ifndef BIT_SIZE
+#define BIT_SIZE(t) (sizeof(t) * 8)
+#endif
+#define MAX_U48 \
+	((((uint64_t)UINT16_MAX) << BIT_SIZE(uint32_t)) | UINT32_MAX)
+#define HI16_OF_U48(x) \
+	(((x) >> BIT_SIZE(uint32_t)) & UINT16_MAX)
+#define LO32_OF_U48(x) ((x) & UINT32_MAX)
+#define U48_BY_HI16_LO32(hi, lo) \
+	(((hi) << BIT_SIZE(uint32_t)) | (lo))
+
 #define bm_buffer_set64(buf, v) \
 	do { \
 		struct bm_buffer *__buf931 = (buf); \
@@ -94,6 +106,24 @@ static inline dma_addr_t bm_buf_addr(const struct bm_buffer *buf)
 		__buf931->lo = lower_32_bits(v); \
 	} while (0)
 
+#define bm_buffer_set64_to_be(buf, v) \
+	do { \
+		struct bm_buffer *__buf931 = (buf); \
+		\
+		__buf931->be_desc.hi = cpu_to_be16(HI16_OF_U48(v)); \
+		__buf931->be_desc.lo = cpu_to_be32(LO32_OF_U48(v)); \
+	} while (0)
+
+#define bm_buffer_get64_from_be(buf) \
+	({ \
+		uint64_t hi, lo; \
+		struct bm_buffer *__buf931 = (buf); \
+		\
+		hi = be16_to_cpu(__buf931->be_desc.hi); \
+		lo = be32_to_cpu(__buf931->be_desc.lo); \
+		U48_BY_HI16_LO32(hi, lo); \
+	})
+
 #define FSL_BM_BURST_MAX 8
 
 /* See 1.5.3.5.4: "Release Command" */
diff --git a/drivers/mempool/dpaa/dpaa_mempool.c b/drivers/mempool/dpaa/dpaa_mempool.c
index 2f8555a026..3fdbcba646 100644
--- a/drivers/mempool/dpaa/dpaa_mempool.c
+++ b/drivers/mempool/dpaa/dpaa_mempool.c
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: BSD-3-Clause
  *
- *   Copyright 2017,2019,2023-2025 NXP
+ *   Copyright 2017,2019,2023-2026 NXP
  *
  */
 
@@ -50,7 +50,7 @@ static int
 dpaa_mbuf_create_pool(struct rte_mempool *mp)
 {
 	struct bman_pool *bp;
-	struct bm_buffer bufs[8];
+	struct bm_buffer bufs[FSL_BM_BURST_MAX];
 	struct dpaa_bp_info *bp_info;
 	uint8_t bpid;
 	int num_bufs = 0, ret = 0;
@@ -83,8 +83,8 @@ dpaa_mbuf_create_pool(struct rte_mempool *mp)
 		 * then in 1s for the remainder.
 		 */
 		if (ret != 1)
-			ret = bman_acquire(bp, bufs, 8, 0);
-		if (ret < 8)
+			ret = bman_acquire(bp, bufs, FSL_BM_BURST_MAX, 0);
+		if (ret < FSL_BM_BURST_MAX)
 			ret = bman_acquire(bp, bufs, 1, 0);
 		if (ret > 0)
 			num_bufs += ret;
-- 
2.25.1


^ permalink raw reply related

* [PATCH v6 15/19] net/dpaa: report error on using deferred start
From: Hemant Agrawal @ 2026-07-02  5:33 UTC (permalink / raw)
  To: stephen, david.marchand, dev
In-Reply-To: <20260702053359.3243907-1-hemant.agrawal@nxp.com>

This patch add support to report on error
for rx and tx deferred start config

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 drivers/net/dpaa/dpaa_ethdev.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 20c198406b..30dfaa95d6 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -1174,6 +1174,12 @@ int dpaa_eth_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 	rxq->nb_desc = UINT16_MAX;
 	rxq->offloads = rx_conf->offloads;
 
+	/* Rx deferred start is not supported */
+	if (rx_conf->rx_deferred_start) {
+		DPAA_PMD_ERR("%p:Rx deferred start not supported", (void *)dev);
+		return -EINVAL;
+	}
+
 	DPAA_PMD_INFO("Rx queue setup for queue index: %d fq_id (0x%x)",
 			queue_idx, rxq->fqid);
 
@@ -1480,6 +1486,12 @@ int dpaa_eth_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 	txq->nb_desc = UINT16_MAX;
 	txq->offloads = tx_conf->offloads;
 
+	/* Tx deferred start is not supported */
+	if (tx_conf->tx_deferred_start) {
+		DPAA_PMD_ERR("%p:Tx deferred start not supported", (void *)dev);
+		return -EINVAL;
+	}
+
 	if (queue_idx >= dev->data->nb_tx_queues) {
 		rte_errno = EOVERFLOW;
 		DPAA_PMD_ERR("%p: queue index out of range (%u >= %u)",
-- 
2.25.1


^ permalink raw reply related

* [PATCH v6 14/19] net/dpaa: optimize FMC MAC type parsing
From: Hemant Agrawal @ 2026-07-02  5:33 UTC (permalink / raw)
  To: stephen, david.marchand, dev; +Cc: Jun Yang
In-Reply-To: <20260702053359.3243907-1-hemant.agrawal@nxp.com>

From: Jun Yang <jun.yang@nxp.com>

For ls104xa, MAC9 and MAC10's type could be either of 10G/2.5G/1G
up to serdes configuration, MAC index should be identified by
port name instead of parsing MAC type and port number.

Signed-off-by: Jun Yang <jun.yang@nxp.com>
---
 drivers/net/dpaa/dpaa_fmc.c | 73 ++++++++++++++++++++++---------------
 1 file changed, 44 insertions(+), 29 deletions(-)

diff --git a/drivers/net/dpaa/dpaa_fmc.c b/drivers/net/dpaa/dpaa_fmc.c
index 7dc42f6e23..3034f534a5 100644
--- a/drivers/net/dpaa/dpaa_fmc.c
+++ b/drivers/net/dpaa/dpaa_fmc.c
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright 2017-2023 NXP
+ * Copyright 2017-2026 NXP
  */
 
 /* System headers */
@@ -204,6 +204,36 @@ struct fmc_model_t {
 
 struct fmc_model_t *g_fmc_model;
 
+static int
+dpaa_port_fmc_get_idx_from_name(const char *name)
+{
+	const char *found;
+	int idx_str_start = -1, idx;
+
+#define FMC_PORT_NAME_MAC "MAC/"
+#define FMC_PORT_NAME_OFFLINE "OFFLINE/"
+
+	found = strstr(name, FMC_PORT_NAME_MAC);
+	if (!found) {
+		found = strstr(name, FMC_PORT_NAME_OFFLINE);
+		if (found)
+			idx_str_start = strlen(FMC_PORT_NAME_OFFLINE);
+	} else {
+		idx_str_start = strlen(FMC_PORT_NAME_MAC);
+	}
+
+	if (!found) {
+		DPAA_PMD_ERR("Invalid fmc port name: %s", name);
+		return -EINVAL;
+	}
+
+	idx = atoi(&found[idx_str_start]);
+
+	DPAA_PMD_INFO("MAC index of %s is %d", name, idx);
+
+	return idx;
+}
+
 static int
 dpaa_port_fmc_port_parse(struct fman_if *fif,
 	const struct fmc_model_t *fmc_model,
@@ -211,7 +241,10 @@ dpaa_port_fmc_port_parse(struct fman_if *fif,
 {
 	int current_port = fmc_model->apply_order[apply_idx].index;
 	const fmc_port *pport = &fmc_model->port[current_port];
-	uint32_t num;
+	int num = dpaa_port_fmc_get_idx_from_name(pport->name);
+
+	if (num < 0)
+		return num;
 
 	if (pport->type == e_FM_PORT_TYPE_OH_OFFLINE_PARSING &&
 	    pport->number == fif->mac_idx &&
@@ -219,40 +252,22 @@ dpaa_port_fmc_port_parse(struct fman_if *fif,
 	     fif->mac_type == fman_onic))
 		return current_port;
 
-	if (fif->mac_type == fman_mac_1g) {
-		if (pport->type != e_FM_PORT_TYPE_RX)
-			return -ENODEV;
-		num = pport->number + DPAA_1G_MAC_START_IDX;
-		if (fif->mac_idx == num)
-			return current_port;
-
+	if (fif->mac_type == fman_mac_1g &&
+		pport->type != e_FM_PORT_TYPE_RX)
 		return -ENODEV;
-	}
-
-	if (fif->mac_type == fman_mac_2_5g) {
-		if (pport->type != e_FM_PORT_TYPE_RX_2_5G)
-			return -ENODEV;
-		num = pport->number + DPAA_2_5G_MAC_START_IDX;
-		if (fif->mac_idx == num)
-			return current_port;
 
+	if (fif->mac_type == fman_mac_2_5g &&
+		pport->type != e_FM_PORT_TYPE_RX_2_5G)
 		return -ENODEV;
-	}
-
-	if (fif->mac_type == fman_mac_10g) {
-		if (pport->type != e_FM_PORT_TYPE_RX_10G)
-			return -ENODEV;
-		num = pport->number + DPAA_10G_MAC_START_IDX;
-		if (fif->mac_idx == num)
-			return current_port;
 
+	if (fif->mac_type == fman_mac_10g &&
+		pport->type != e_FM_PORT_TYPE_RX_10G)
 		return -ENODEV;
-	}
 
-	DPAA_PMD_ERR("Invalid MAC(mac_idx=%d) type(%d)",
-		fif->mac_idx, fif->mac_type);
+	if (fif->mac_idx == num)
+		return current_port;
 
-	return -EINVAL;
+	return -ENODEV;
 }
 
 static int
-- 
2.25.1


^ permalink raw reply related

* [PATCH v6 13/19] bus/dpaa: improve log macro and fix bus detection
From: Hemant Agrawal @ 2026-07-02  5:33 UTC (permalink / raw)
  To: stephen, david.marchand, dev
In-Reply-To: <20260702053359.3243907-1-hemant.agrawal@nxp.com>

Replace DPAA_BUS_LOG(LEVEL, ...) calls with shorthand macros
(DPAA_BUS_INFO, DPAA_BUS_ERR, DPAA_BUS_WARN, DPAA_BUS_DEBUG) for
consistency across the driver.

Move bus detection (sysfs path check), portal key creation and
dpaa_bus.detected guard into dpaa_bus_dev_compare() so that bus
probe is properly gated on hardware presence.

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 drivers/bus/dpaa/base/fman/fman.c |  9 ++++-----
 drivers/bus/dpaa/dpaa_bus.c       | 33 +++++++++++++++++++++++++------
 2 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/drivers/bus/dpaa/base/fman/fman.c b/drivers/bus/dpaa/base/fman/fman.c
index 55f466d751..67f77265ca 100644
--- a/drivers/bus/dpaa/base/fman/fman.c
+++ b/drivers/bus/dpaa/base/fman/fman.c
@@ -119,7 +119,7 @@ _fman_init(const struct device_node *fman_node, int fd)
 	ip_rev_1 = in_be32((uint8_t *)fman->ccsr_vir + FMAN_IP_REV_1);
 	fman->ip_rev = ip_rev_1 >> FMAN_IP_REV_1_MAJOR_SHIFT;
 	fman->ip_rev &=	FMAN_IP_REV_1_MAJOR_MASK;
-	DPAA_BUS_LOG(NOTICE, "FMan version is 0x%02x", fman->ip_rev);
+	DPAA_BUS_INFO("FMan version is 0x%02x", fman->ip_rev);
 
 	if (fman->ip_rev >= FMAN_V3) {
 		/*
@@ -795,8 +795,7 @@ fman_if_init(const struct device_node *dpa_node, int fd)
 	fman_if_vsp_init(__if);
 
 	/* Parsing of the network interface is complete, add it to the list */
-	DPAA_BUS_LOG(DEBUG, "Found %s, Tx Channel = %x, FMAN = %x,"
-		    "Port ID = %x",
+	DPAA_BUS_DEBUG("Found %s, Tx Channel = %x, FMAN = %x, Port ID = %x",
 		    dname, __if->__if.tx_channel_id, __if->__if.fman->idx,
 		    __if->__if.mac_idx);
 
@@ -1109,14 +1108,14 @@ fman_init(void)
 
 	fd = open(FMAN_DEVICE_PATH, O_RDWR);
 	if (unlikely(fd < 0)) {
-		DPAA_BUS_LOG(ERR, "Unable to open %s: %s", FMAN_DEVICE_PATH, strerror(errno));
+		DPAA_BUS_ERR("Unable to open %s: %s", FMAN_DEVICE_PATH, strerror(errno));
 		return fd;
 	}
 	fman_ccsr_map_fd = fd;
 
 	parent_node = of_find_compatible_node(NULL, NULL, "fsl,dpaa");
 	if (!parent_node) {
-		DPAA_BUS_LOG(ERR, "Unable to find fsl,dpaa node");
+		DPAA_BUS_ERR("Unable to find fsl,dpaa node");
 		return -ENODEV;
 	}
 
diff --git a/drivers/bus/dpaa/dpaa_bus.c b/drivers/bus/dpaa/dpaa_bus.c
index 54779f82f7..60e20f402e 100644
--- a/drivers/bus/dpaa/dpaa_bus.c
+++ b/drivers/bus/dpaa/dpaa_bus.c
@@ -560,12 +560,36 @@ rte_dpaa_bus_parse(const char *name, void *out)
 static int
 dpaa_bus_dev_compare(const char *name1, const char *name2)
 {
+	int ret = 0;
 	char devname1[32], devname2[32];
 
 	if (rte_dpaa_bus_parse(name1, devname1) != 0 ||
 			rte_dpaa_bus_parse(name2, devname2) != 0)
 		return 1;
 
+#define DPAA_DEV_PATH1 "/sys/devices/platform/soc/soc:fsl,dpaa"
+#define DPAA_DEV_PATH2 "/sys/devices/platform/fsl,dpaa"
+	if ((access(DPAA_DEV_PATH1, F_OK) != 0) &&
+	    (access(DPAA_DEV_PATH2, F_OK) != 0)) {
+		DPAA_BUS_DEBUG("DPAA Bus not present. Skipping.");
+		return 0;
+	}
+
+	if (dpaa_bus.detected)
+		return 0;
+
+	dpaa_bus.detected = 1;
+
+	/* create the key, supplying a function that'll be invoked
+	 * when a portal affined thread will be deleted.
+	 */
+	ret = pthread_key_create(&dpaa_portal_key, dpaa_portal_finish);
+	if (ret) {
+		DPAA_BUS_DEBUG("Unable to create pthread key. (%d)", ret);
+		dpaa_clean_device_list();
+		return ret;
+	}
+
 	return strncmp(devname1, devname2, sizeof(devname1));
 }
 
@@ -667,8 +691,6 @@ static int rte_dpaa_setup_intr(struct rte_intr_handle *intr_handle)
 	return 0;
 }
 
-#define DPAA_DEV_PATH1 "/sys/devices/platform/soc/soc:fsl,dpaa"
-#define DPAA_DEV_PATH2 "/sys/devices/platform/fsl,dpaa"
 
 static int
 rte_dpaa_bus_scan(void)
@@ -715,12 +737,11 @@ rte_dpaa_bus_scan(void)
 		dpaa_bus.svr_ver = 0;
 	}
 	if (dpaa_bus.svr_ver == SVR_LS1046A_FAMILY) {
-		DPAA_BUS_LOG(INFO, "This is LS1046A family SoC.");
+		DPAA_BUS_INFO("This is LS1046A family SoC.");
 	} else if (dpaa_bus.svr_ver == SVR_LS1043A_FAMILY) {
-		DPAA_BUS_LOG(INFO, "This is LS1043A family SoC.");
+		DPAA_BUS_INFO("This is LS1043A family SoC.");
 	} else {
-		DPAA_BUS_LOG(WARNING,
-			"This is Unknown(%08x) DPAA1 family SoC.",
+		DPAA_BUS_WARN("This is Unknown(%08x) DPAA1 family SoC.",
 			dpaa_bus.svr_ver);
 	}
 
-- 
2.25.1


^ permalink raw reply related

* [PATCH v6 12/19] net/dpaa: optimize FM deconfig
From: Hemant Agrawal @ 2026-07-02  5:33 UTC (permalink / raw)
  To: stephen, david.marchand, dev
In-Reply-To: <20260702053359.3243907-1-hemant.agrawal@nxp.com>

Consolidate FM deconfiguration to avoid duplicate calls.
Move the fm_deconfig call to a single location and remove
redundant checks in the device close path.

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 drivers/net/dpaa/dpaa_ethdev.c | 27 +++++++++++++++++++++++----
 drivers/net/dpaa/dpaa_flow.c   |  9 +++++----
 2 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 9beced37a0..20c198406b 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -528,10 +528,12 @@ static int dpaa_eth_dev_close(struct rte_eth_dev *dev)
 
 	/* DPAA FM deconfig */
 	if (!(default_q || fmc_q)) {
-		ret = dpaa_fm_deconfig(dpaa_intf, dev->process_private);
-		if (ret) {
-			DPAA_PMD_WARN("%s: FM deconfig failed(%d)",
-				dev->data->name, ret);
+		if (dpaa_intf->port_handle) {
+			ret = dpaa_fm_deconfig(dpaa_intf, dev->process_private);
+			if (ret) {
+				DPAA_PMD_WARN("%s: FM deconfig failed(%d)",
+					dev->data->name, ret);
+			}
 		}
 	}
 
@@ -577,6 +579,23 @@ static int dpaa_eth_dev_close(struct rte_eth_dev *dev)
 	rte_free(dpaa_intf->fc_conf);
 	dpaa_intf->fc_conf = NULL;
 
+	/** For FMCLESS mode of share MAC, deconfig FM to direct
+	 * ingress traffic to kernel before fq shutdown.
+	 */
+	if (!(default_q || fmc_q) && dpaa_intf->port_handle) {
+		ret = dpaa_fm_deconfig(dpaa_intf, dev->process_private);
+		if (ret) {
+			DPAA_PMD_WARN("%s: FM deconfig failed(%d)",
+				dev->data->name, ret);
+		}
+	}
+	if (fif->num_profiles) {
+		ret = dpaa_port_vsp_cleanup(dpaa_intf, fif);
+		if (ret) {
+			DPAA_PMD_WARN("%s: cleanup VSP failed(%d)",
+				dev->data->name, ret);
+		}
+	}
 	/** Release congestion Groups after releasing FQIDs*/
 	/* Release RX congestion Groups */
 	if (dpaa_intf->cgr_rx) {
diff --git a/drivers/net/dpaa/dpaa_flow.c b/drivers/net/dpaa/dpaa_flow.c
index 417b9b6fbb..559850ced7 100644
--- a/drivers/net/dpaa/dpaa_flow.c
+++ b/drivers/net/dpaa/dpaa_flow.c
@@ -724,6 +724,9 @@ int dpaa_fm_deconfig(struct dpaa_if *dpaa_intf,
 
 	PMD_INIT_FUNC_TRACE();
 
+	if (!dpaa_intf->port_handle)
+		return 0;
+
 	/* FM PORT Disable */
 	ret = fm_port_disable(dpaa_intf->port_handle);
 	if (ret != E_OK) {
@@ -783,10 +786,8 @@ int dpaa_fm_config(struct rte_eth_dev *dev, uint64_t req_dist_set)
 	unsigned int i = 0;
 	PMD_INIT_FUNC_TRACE();
 
-	if (dpaa_intf->port_handle) {
-		if (dpaa_fm_deconfig(dpaa_intf, fif))
-			DPAA_PMD_ERR("DPAA FM deconfig failed");
-	}
+	if (dpaa_fm_deconfig(dpaa_intf, fif))
+		DPAA_PMD_ERR("DPAA FM deconfig failed");
 
 	if (!dev->data->nb_rx_queues)
 		return 0;
-- 
2.25.1


^ permalink raw reply related

* [PATCH v6 11/19] net/dpaa: remove redundant FQ shutdown from Rx queue setup
From: Hemant Agrawal @ 2026-07-02  5:33 UTC (permalink / raw)
  To: stephen, david.marchand, dev
In-Reply-To: <20260702053359.3243907-1-hemant.agrawal@nxp.com>

Remove the redundant qman_shutdown_fq() call from
dpaa_eth_rx_queue_setup(). The FQ is shut down during device stop,
so calling it again at queue setup time is unnecessary and may
interfere with a clean queue initialization.

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 drivers/net/dpaa/dpaa_ethdev.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 45bf2b8e59..9beced37a0 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -1158,9 +1158,6 @@ int dpaa_eth_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 	DPAA_PMD_INFO("Rx queue setup for queue index: %d fq_id (0x%x)",
 			queue_idx, rxq->fqid);
 
-	/* Shutdown FQ before configure */
-	qman_shutdown_fq(rxq->fqid);
-
 	if (!fif->num_profiles) {
 		if (dpaa_intf->bp_info && dpaa_intf->bp_info->bp &&
 			dpaa_intf->bp_info->mp != mp) {
-- 
2.25.1


^ permalink raw reply related

* [PATCH v6 10/19] net/dpaa: clean Tx confirmation FQ on device stop
From: Hemant Agrawal @ 2026-07-02  5:33 UTC (permalink / raw)
  To: stephen, david.marchand, dev
In-Reply-To: <20260702053359.3243907-1-hemant.agrawal@nxp.com>

Ensure the Tx confirmation FQ is also cleaned up during device
stop, preventing stale FQ state on subsequent device restarts.

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 drivers/net/dpaa/dpaa_ethdev.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index df6bcdce95..45bf2b8e59 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -575,6 +575,7 @@ static int dpaa_eth_dev_close(struct rte_eth_dev *dev)
 
 	/* release configuration memory */
 	rte_free(dpaa_intf->fc_conf);
+	dpaa_intf->fc_conf = NULL;
 
 	/** Release congestion Groups after releasing FQIDs*/
 	/* Release RX congestion Groups */
@@ -644,6 +645,10 @@ static int dpaa_eth_dev_close(struct rte_eth_dev *dev)
 
 	rte_free(dpaa_intf->tx_queues);
 	dpaa_intf->tx_queues = NULL;
+
+	rte_free(dpaa_intf->tx_conf_queues);
+	dpaa_intf->tx_conf_queues = NULL;
+
 	if (dpaa_intf->port_handle) {
 		ret = dpaa_fm_deconfig(dpaa_intf, fif);
 		if (ret) {
@@ -2538,6 +2543,8 @@ dpaa_dev_init(struct rte_eth_dev *eth_dev)
 	return 0;
 
 free_tx:
+	rte_free(dpaa_intf->tx_conf_queues);
+	dpaa_intf->tx_conf_queues = NULL;
 	rte_free(dpaa_intf->tx_queues);
 	dpaa_intf->tx_queues = NULL;
 	dpaa_intf->nb_tx_queues = 0;
-- 
2.25.1


^ permalink raw reply related

* [PATCH v6 09/19] drivers: add DPAA cgrid cleanup support
From: Hemant Agrawal @ 2026-07-02  5:33 UTC (permalink / raw)
  To: stephen, david.marchand, dev; +Cc: Jun Yang
In-Reply-To: <20260702053359.3243907-1-hemant.agrawal@nxp.com>

From: Jun Yang <jun.yang@nxp.com>

Add qman_find_fq_by_cgid() to find frame queues associated with
a given CGID. This allows the driver to verify that all FQs
using a CGR are shut down before releasing the CGR ID, preventing
use-after-free of CGR resources.

Signed-off-by: Jun Yang <jun.yang@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 drivers/bus/dpaa/dpaa_bus_base_symbols.c |  1 +
 drivers/bus/dpaa/include/fsl_qman.h      |  3 +++
 drivers/net/dpaa/dpaa_ethdev.c           | 29 ++++++++++++++++++++++--
 3 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/drivers/bus/dpaa/dpaa_bus_base_symbols.c b/drivers/bus/dpaa/dpaa_bus_base_symbols.c
index 52abec2b4c..514ab7b1f1 100644
--- a/drivers/bus/dpaa/dpaa_bus_base_symbols.c
+++ b/drivers/bus/dpaa/dpaa_bus_base_symbols.c
@@ -56,6 +56,7 @@ RTE_EXPORT_INTERNAL_SYMBOL(qman_reserve_fqid_range)
 RTE_EXPORT_INTERNAL_SYMBOL(qman_alloc_pool_range)
 RTE_EXPORT_INTERNAL_SYMBOL(qman_alloc_cgrid_range)
 RTE_EXPORT_INTERNAL_SYMBOL(qman_release_cgrid_range)
+RTE_EXPORT_INTERNAL_SYMBOL(qman_find_fq_by_cgrid)
 RTE_EXPORT_INTERNAL_SYMBOL(dpaa_intr_enable)
 RTE_EXPORT_INTERNAL_SYMBOL(dpaa_intr_disable)
 RTE_EXPORT_INTERNAL_SYMBOL(dpaa_get_ioctl_version_number)
diff --git a/drivers/bus/dpaa/include/fsl_qman.h b/drivers/bus/dpaa/include/fsl_qman.h
index bd46207232..20321ed355 100644
--- a/drivers/bus/dpaa/include/fsl_qman.h
+++ b/drivers/bus/dpaa/include/fsl_qman.h
@@ -1907,6 +1907,9 @@ static inline int qman_shutdown_fq_by_fqid(u32 fqid)
 	return qman_shutdown_fq(&fq);
 }
 
+__rte_internal
+int qman_find_fq_by_cgrid(u32 cgrid, u32 *fqid);
+
 /**
  * qman_reserve_fqid_range - Reserve the specified range of frame queue IDs
  * @fqid: the base FQID of the range to deallocate
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 8d54e022a3..df6bcdce95 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -513,7 +513,7 @@ static int dpaa_eth_dev_close(struct rte_eth_dev *dev)
 	struct rte_eth_link *link = &dev->data->dev_link;
 	struct dpaa_if *dpaa_intf = dev->data->dev_private;
 	struct qman_fq *fq;
-	int loop;
+	uint32_t fqid, loop;
 	int ret;
 
 	PMD_INIT_FUNC_TRACE();
@@ -576,28 +576,53 @@ static int dpaa_eth_dev_close(struct rte_eth_dev *dev)
 	/* release configuration memory */
 	rte_free(dpaa_intf->fc_conf);
 
+	/** Release congestion Groups after releasing FQIDs*/
 	/* Release RX congestion Groups */
 	if (dpaa_intf->cgr_rx) {
 		for (loop = 0; loop < dpaa_intf->nb_rx_queues; loop++) {
+			ret = qman_find_fq_by_cgrid(dpaa_intf->cgr_rx[loop].cgrid, &fqid);
+			if (!ret) {
+				/** Should be FQ not cleaned in previous program.*/
+				DPAA_PMD_DEBUG("FQ(fqid=0x%x) with rx cgid=%d is still alive?",
+					fqid, dpaa_intf->cgr_rx[loop].cgrid);
+				ret = qman_shutdown_fq_by_fqid(fqid);
+				if (ret) {
+					DPAA_PMD_WARN("Failed(%d) to shutdown fq(fqid=0x%x)",
+						ret, fqid);
+				}
+			}
 			ret = qman_delete_cgr(&dpaa_intf->cgr_rx[loop]);
 			if (ret) {
 				DPAA_PMD_WARN("%s: delete rxq%d's cgr err(%d)",
 					dev->data->name, loop, ret);
 			}
 		}
+		qman_release_cgrid_range(dpaa_intf->cgr_rx[0].cgrid, dpaa_intf->nb_rx_queues);
 		rte_free(dpaa_intf->cgr_rx);
 		dpaa_intf->cgr_rx = NULL;
 	}
 
 	/* Release TX congestion Groups */
 	if (dpaa_intf->cgr_tx) {
-		for (loop = 0; loop < MAX_DPAA_CORES; loop++) {
+		for (loop = 0; loop < dpaa_intf->nb_tx_queues; loop++) {
+			ret = qman_find_fq_by_cgrid(dpaa_intf->cgr_tx[loop].cgrid, &fqid);
+			if (!ret) {
+				/** Should be FQ not cleaned in previous program.*/
+				DPAA_PMD_DEBUG("FQ(fqid=0x%x) with tx cgid=%d is still alive?",
+					fqid, dpaa_intf->cgr_tx[loop].cgrid);
+				ret = qman_shutdown_fq_by_fqid(fqid);
+				if (ret) {
+					DPAA_PMD_WARN("Failed(%d) to shutdown fq(fqid=0x%x)",
+						ret, fqid);
+				}
+			}
 			ret = qman_delete_cgr(&dpaa_intf->cgr_tx[loop]);
 			if (ret) {
 				DPAA_PMD_WARN("%s: delete txq%d's cgr err(%d)",
 					dev->data->name, loop, ret);
 			}
 		}
+		qman_release_cgrid_range(dpaa_intf->cgr_tx[0].cgrid, dpaa_intf->nb_tx_queues);
 		rte_free(dpaa_intf->cgr_tx);
 		dpaa_intf->cgr_tx = NULL;
 	}
-- 
2.25.1


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox