DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 17/18] net/dpaa: fix null l3_len check in checksum offload
From: Hemant Agrawal @ 2026-06-19  6:09 UTC (permalink / raw)
  To: stephen, david.marchand, dev; +Cc: stable
In-Reply-To: <20260619060916.485258-1-hemant.agrawal@nxp.com>

In dpaa_checksum(), if mbuf->l3_len is zero the L4 header pointer
calculation (l3_hdr + mbuf->l3_len) will point to the start of the
L3 header rather than the L4 header, leading to incorrect checksum
computation on a corrupt or uninitialized packet. Add an early
return guard when l3_len is zero.

Fixes: 5a8cf1bef775 ("net/dpaa: support checksum offload")
Cc: stable@dpdk.org

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

diff --git a/drivers/net/dpaa/dpaa_rxtx.c b/drivers/net/dpaa/dpaa_rxtx.c
index c5e393159a..1cda68e5af 100644
--- a/drivers/net/dpaa/dpaa_rxtx.c
+++ b/drivers/net/dpaa/dpaa_rxtx.c
@@ -377,6 +377,8 @@ static inline void dpaa_checksum(struct rte_mbuf *mbuf)
 	struct rte_ipv6_hdr *ipv6_hdr = (struct rte_ipv6_hdr *)l3_hdr;
 
 	DPAA_DP_LOG(DEBUG, "Calculating checksum for mbuf: %p", mbuf);
+	if (mbuf->l3_len == 0)
+		return;
 
 	if (((mbuf->packet_type & RTE_PTYPE_L3_MASK) == RTE_PTYPE_L3_IPV4) ||
 	    ((mbuf->packet_type & RTE_PTYPE_L3_MASK) ==
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 16/18] net/dpaa: fix wrong buffer in xstats get by id
From: Hemant Agrawal @ 2026-06-19  6:09 UTC (permalink / raw)
  To: stephen, david.marchand, dev; +Cc: stable
In-Reply-To: <20260619060916.485258-1-hemant.agrawal@nxp.com>

In dpaa_xstats_get_by_id(), fman_if_bmi_stats_get_all() was called
with 'values' (the output array) instead of 'values_copy' (the
scratch buffer). This caused the BMI stats to overwrite already
computed xstat values and then the subsequent loop would copy
garbage from values_copy into the output.

Pass 'values_copy' as intended so that BMI stats are fetched into
the scratch buffer and then correctly indexed into 'values'.

Fixes: d2536b006d78 ("bus/dpaa: add port buffer manager stats")
Cc: stable@dpdk.org

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

diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index b7f3c4360b..a83499f332 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -928,7 +928,7 @@ dpaa_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
 			values[i] =
 				values_copy[dpaa_xstats_strings[i].offset / 8];
 
-		fman_if_bmi_stats_get_all(dev->process_private, values);
+		fman_if_bmi_stats_get_all(dev->process_private, values_copy);
 		for (j = 0; i < stat_cnt; i++, j++)
 			values[i] = values_copy[j];
 
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 15/18] net/dpaa: remove duplicate ptype entries
From: Hemant Agrawal @ 2026-06-19  6:09 UTC (permalink / raw)
  To: stephen, david.marchand, dev; +Cc: stable
In-Reply-To: <20260619060916.485258-1-hemant.agrawal@nxp.com>

RTE_PTYPE_L4_TCP and RTE_PTYPE_L4_UDP were listed twice in the
supported ptypes array returned by dpaa_supported_ptypes_get().
Remove the duplicate entries.

Fixes: ec503d8fa782 ("net/dpaa: update supported ptypes")
Cc: stable@dpdk.org

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

diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 3d6405d5fa..b7f3c4360b 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -406,8 +406,6 @@ dpaa_supported_ptypes_get(struct rte_eth_dev *dev, size_t *no_of_elements)
 		RTE_PTYPE_L4_TCP,
 		RTE_PTYPE_L4_UDP,
 		RTE_PTYPE_L4_FRAG,
-		RTE_PTYPE_L4_TCP,
-		RTE_PTYPE_L4_UDP,
 		RTE_PTYPE_L4_SCTP,
 		RTE_PTYPE_TUNNEL_ESP,
 		RTE_PTYPE_TUNNEL_GRE,
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 14/18] net/dpaa: fix xstat string typos in BMI stats table
From: Hemant Agrawal @ 2026-06-19  6:09 UTC (permalink / raw)
  To: stephen, david.marchand, dev; +Cc: stable
In-Reply-To: <20260619060916.485258-1-hemant.agrawal@nxp.com>

Fix three issues in the xstats name table:
- 'rx_frame_discrad_count' is a misspelling, correct to
  'rx_frame_discard_count'
- 'rx_out_of_buffer_discard ' has a trailing space, remove it
- 'rx_buf_diallocate' is a misspelling, correct to
  'rx_buf_deallocate'

Fixes: d2536b006d78 ("bus/dpaa: add port buffer manager stats")
Cc: stable@dpdk.org

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

diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 3d3f2773a1..3d6405d5fa 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -135,13 +135,13 @@ static const struct rte_dpaa_xstats_name_off dpaa_xstats_strings[] = {
 		offsetof(struct dpaa_if_rx_bmi_stats, fmbm_rlfc)},
 	{"rx_filter_frames_count",
 		offsetof(struct dpaa_if_rx_bmi_stats, fmbm_rffc)},
-	{"rx_frame_discrad_count",
+	{"rx_frame_discard_count",
 		offsetof(struct dpaa_if_rx_bmi_stats, fmbm_rfdc)},
 	{"rx_frame_list_dma_err_count",
 		offsetof(struct dpaa_if_rx_bmi_stats, fmbm_rfldec)},
-	{"rx_out_of_buffer_discard ",
+	{"rx_out_of_buffer_discard",
 		offsetof(struct dpaa_if_rx_bmi_stats, fmbm_rodc)},
-	{"rx_buf_diallocate",
+	{"rx_buf_deallocate",
 		offsetof(struct dpaa_if_rx_bmi_stats, fmbm_rbdc)},
 };
 
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 13/18] net/dpaa: fix xstat name for tx undersized counter
From: Hemant Agrawal @ 2026-06-19  6:09 UTC (permalink / raw)
  To: stephen, david.marchand, dev; +Cc: stable
In-Reply-To: <20260619060916.485258-1-hemant.agrawal@nxp.com>

The xstat entry mapping to 'tund' (TX undersized) was incorrectly
labeled as 'rx_undersized'. Fix the prefix to 'tx_undersized'.

Fixes: b21ed3e2a16d ("net/dpaa: support extended statistics")
Cc: stable@dpdk.org

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

diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index c143e66f77..3d3f2773a1 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -125,7 +125,7 @@ static const struct rte_dpaa_xstats_name_off dpaa_xstats_strings[] = {
 		offsetof(struct dpaa_if_stats, terr)},
 	{"tx_vlan_frame",
 		offsetof(struct dpaa_if_stats, tvlan)},
-	{"rx_undersized",
+	{"tx_undersized",
 		offsetof(struct dpaa_if_stats, tund)},
 	{"rx_frame_counter",
 		offsetof(struct dpaa_if_rx_bmi_stats, fmbm_rfrc)},
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 12/18] dma/dpaa: fix out-of-bounds access in SG descriptor enqueue
From: Hemant Agrawal @ 2026-06-19  6:09 UTC (permalink / raw)
  To: stephen, david.marchand, dev; +Cc: stable, Vanshika Shukla
In-Reply-To: <20260619060916.485258-1-hemant.agrawal@nxp.com>

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

In fsl_qdma_enqueue_desc_sg(), the code accesses desc_ssge[num - 1]
without validating num first. If pending_num is 0, num will be 0 and
the access underflows. Add a bounds check to return -EINVAL when num
is 0 or exceeds FSL_QDMA_SG_MAX_ENTRY.

Fixes: a77261f61245 ("dma/dpaa: support scatter-gather")
Cc: stable@dpdk.org

Signed-off-by: Vanshika Shukla <vanshika.shukla@nxp.com>
---
 drivers/dma/dpaa/dpaa_qdma.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/dpaa/dpaa_qdma.c b/drivers/dma/dpaa/dpaa_qdma.c
index 74e23d2ee5..b20ff24ab6 100644
--- a/drivers/dma/dpaa/dpaa_qdma.c
+++ b/drivers/dma/dpaa/dpaa_qdma.c
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright 2021-2024 NXP
+ * Copyright 2021-2026 NXP
  */
 
 #include <bus_dpaa_driver.h>
@@ -827,6 +827,11 @@ fsl_qdma_enqueue_desc_sg(struct fsl_qdma_queue *fsl_queue)
 		}
 	}
 
+	if (num == 0 || num > FSL_QDMA_SG_MAX_ENTRY) {
+		DPAA_QDMA_ERR("Invalid scatter-gather entry count: num=%u", num);
+		return -EINVAL;
+	}
+
 	ft->desc_ssge[num - 1].final = 1;
 	ft->desc_dsge[num - 1].final = 1;
 	csgf_src->length = total_len;
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 11/18] net/dpaa: fix port_handle leak in fm_prev_cleanup
From: Hemant Agrawal @ 2026-06-19  6:09 UTC (permalink / raw)
  To: stephen, david.marchand, dev; +Cc: stable, Vanshika Shukla
In-Reply-To: <20260619060916.485258-1-hemant.agrawal@nxp.com>

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

In fm_prev_cleanup(), the port_handle was not closed before being
overwritten on each iteration, causing a resource leak. Add a null
check and close the existing handle before opening a new one.

Fixes: e498f3b51f38 ("net/dpaa: improve port cleanup")
Cc: stable@dpdk.org

Signed-off-by: Vanshika Shukla <vanshika.shukla@nxp.com>
---
 drivers/net/dpaa/dpaa_flow.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/dpaa/dpaa_flow.c b/drivers/net/dpaa/dpaa_flow.c
index 417b9b6fbb..f21950f64d 100644
--- a/drivers/net/dpaa/dpaa_flow.c
+++ b/drivers/net/dpaa/dpaa_flow.c
@@ -81,6 +81,10 @@ static void fm_prev_cleanup(void)
 		devid = fm_model.device_order[i];
 		/* FM Port Open */
 		fm_model.fm_port_params[devid].h_fm = fm_info.fman_handle;
+		if (dpaa_intf.port_handle) {
+			fm_port_close(dpaa_intf.port_handle);
+			dpaa_intf.port_handle = NULL;
+		}
 		dpaa_intf.port_handle =
 				fm_port_open(&fm_model.fm_port_params[devid]);
 		dpaa_intf.scheme_handle[0] = create_device(fm_info.pcd_handle,
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 10/18] net/dpaa: fix invalid check on interrupt unregister
From: Hemant Agrawal @ 2026-06-19  6:09 UTC (permalink / raw)
  To: stephen, david.marchand, dev; +Cc: stable, Gagandeep Singh
In-Reply-To: <20260619060916.485258-1-hemant.agrawal@nxp.com>

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

rte_intr_callback_unregister() returns the number of callbacks
removed (>= 1) on success and a negative value on failure. The
previous check 'if (ret)' logged a spurious warning on every
successful unregister. Fix it to 'if (ret < 0)'.

Fixes: 2aa10990a8dd ("bus/dpaa: enable link state interrupt")
Cc: stable@dpdk.org

Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
 drivers/net/dpaa/dpaa_ethdev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 9a9c5ee817..c143e66f77 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -559,7 +559,7 @@ static int dpaa_eth_dev_close(struct rte_eth_dev *dev)
 		}
 		ret = rte_intr_callback_unregister(intr_handle,
 			dpaa_interrupt_handler, (void *)dev);
-		if (ret) {
+		if (ret < 0) {
 			DPAA_PMD_WARN("%s: unregister interrupt failed(%d)",
 				dev->data->name, ret);
 		}
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 09/18] net/dpaa: fix device remove
From: Hemant Agrawal @ 2026-06-19  6:09 UTC (permalink / raw)
  To: stephen, david.marchand, dev; +Cc: stable, Gagandeep Singh
In-Reply-To: <20260619060916.485258-1-hemant.agrawal@nxp.com>

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

Add a check to avoid closing a device that is already closed,
preventing a double-close condition during device removal.

Note: this also removes the explicit dpaa_finish() call that was
made at last-device remove time (!dpaa_valid_dev). dpaa_finish() is
registered as RTE_FINI_PRIO(dpaa_finish, 103) and will still run at
process exit, so for the normal run-then-exit path behaviour is
unchanged. For a remove-all-then-re-probe scenario, is_global_init
will remain set until exit; re-probe in a running process is not a
supported use case for this driver.

Fixes: 78ea4b4fcb52 ("bus/dpaa: improve cleanup")
Cc: stable@dpdk.org

Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
 drivers/net/dpaa/dpaa_ethdev.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 424458857e..9a9c5ee817 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -2674,18 +2674,19 @@ static int
 rte_dpaa_remove(struct rte_dpaa_device *dpaa_dev)
 {
 	struct rte_eth_dev *eth_dev;
-	int ret;
+	int ret = 0;
 
 	PMD_INIT_FUNC_TRACE();
 
 	eth_dev = dpaa_dev->eth_dev;
-	dpaa_eth_dev_close(eth_dev);
-	ret = rte_eth_dev_release_port(eth_dev);
+	if (eth_dev->state !=  RTE_ETH_DEV_UNUSED) {
+		dpaa_eth_dev_close(eth_dev);
+		ret = rte_eth_dev_release_port(eth_dev);
+	}
 	dpaa_valid_dev--;
-	if (!dpaa_valid_dev) {
+	if (!dpaa_valid_dev)
 		rte_mempool_free(dpaa_tx_sg_pool);
-		dpaa_finish();
-	}
+
 	return ret;
 }
 
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 08/18] bus/dpaa: fix device probe issue
From: Hemant Agrawal @ 2026-06-19  6:09 UTC (permalink / raw)
  To: stephen, david.marchand, dev; +Cc: stable, Gagandeep Singh
In-Reply-To: <20260619060916.485258-1-hemant.agrawal@nxp.com>

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

Remove an unintended early return in the LS1043 SoC version check
that was preventing device probing from completing successfully on
LS1043A platforms.

The early return did two things: set max_push_rxq_num = 0 and skip
the DPAA_PUSH_QUEUES_NUMBER env-var override. With the return gone,
the env-var could inadvertently re-enable push mode on LS1043A, which
must remain disabled due to the FMAN push-mode errata handled in
dpaa_rxtx.c. Guard the env-var override so it only applies to
non-LS1043A SoCs.

Fixes: 164e9e13e50f ("bus/dpaa: enhance SoC version")
Cc: stable@dpdk.org

Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
 drivers/bus/dpaa/dpaa_bus.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/bus/dpaa/dpaa_bus.c b/drivers/bus/dpaa/dpaa_bus.c
index ee467b94d5..02a8c5882e 100644
--- a/drivers/bus/dpaa/dpaa_bus.c
+++ b/drivers/bus/dpaa/dpaa_bus.c
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: BSD-3-Clause
  *
- * Copyright 2017-2025 NXP
+ * Copyright 2017-2026 NXP
  *
  */
 /* System headers */
@@ -724,18 +724,17 @@ rte_dpaa_bus_scan(void)
 			dpaa_bus.svr_ver);
 	}
 
-	/* Disabling the default push mode for LS1043A */
+	/* Disabling the default push mode for LS1043A due to errata */
 	if (dpaa_bus.svr_ver == SVR_LS1043A_FAMILY) {
 		dpaa_bus.max_push_rxq_num = 0;
-		return 0;
+	} else {
+		penv = getenv("DPAA_PUSH_QUEUES_NUMBER");
+		if (penv)
+			dpaa_bus.max_push_rxq_num = atoi(penv);
+		if (dpaa_bus.max_push_rxq_num > DPAA_MAX_PUSH_MODE_QUEUE)
+			dpaa_bus.max_push_rxq_num = DPAA_MAX_PUSH_MODE_QUEUE;
 	}
 
-	penv = getenv("DPAA_PUSH_QUEUES_NUMBER");
-	if (penv)
-		dpaa_bus.max_push_rxq_num = atoi(penv);
-	if (dpaa_bus.max_push_rxq_num > DPAA_MAX_PUSH_MODE_QUEUE)
-		dpaa_bus.max_push_rxq_num = DPAA_MAX_PUSH_MODE_QUEUE;
-
 	/* Device list creation is only done once */
 	if (!process_once) {
 		rte_dpaa_bus_dev_build();
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 07/18] bus/dpaa: fix fd leak for ccsr mmap
From: Hemant Agrawal @ 2026-06-19  6:09 UTC (permalink / raw)
  To: stephen, david.marchand, dev; +Cc: stable, Jun Yang
In-Reply-To: <20260619060916.485258-1-hemant.agrawal@nxp.com>

The CCSR file descriptor was kept open after mmap() was done.
Close the fd immediately after mmap() as it is no longer needed,
preventing a file descriptor leak.

Fixes: 8e253882cd31 ("bus/dpaa: support interrupt portal based fd")
Cc: stable@dpdk.org

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Signed-off-by: Jun Yang <jun.yang@nxp.com>
---
 drivers/bus/dpaa/base/qbman/bman_driver.c | 3 ++-
 drivers/bus/dpaa/base/qbman/qman_driver.c | 6 +++---
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/bus/dpaa/base/qbman/bman_driver.c b/drivers/bus/dpaa/base/qbman/bman_driver.c
index 23e44ac10b..71a2028383 100644
--- a/drivers/bus/dpaa/base/qbman/bman_driver.c
+++ b/drivers/bus/dpaa/base/qbman/bman_driver.c
@@ -145,7 +145,7 @@ void bman_thread_irq(void)
 
 int bman_init_ccsr(const struct device_node *node)
 {
-	static int ccsr_map_fd;
+	int ccsr_map_fd;
 	uint64_t phys_addr;
 	const uint32_t *bman_addr;
 	uint64_t regs_size;
@@ -169,6 +169,7 @@ int bman_init_ccsr(const struct device_node *node)
 
 	bman_ccsr_map = mmap(NULL, regs_size, PROT_READ |
 			     PROT_WRITE, MAP_SHARED, ccsr_map_fd, phys_addr);
+	close(ccsr_map_fd);
 	if (bman_ccsr_map == MAP_FAILED) {
 		pr_err("Can not map BMan CCSR base Bman: "
 		       "0x%x Phys: 0x%" PRIx64 " size 0x%" PRIu64,
diff --git a/drivers/bus/dpaa/base/qbman/qman_driver.c b/drivers/bus/dpaa/base/qbman/qman_driver.c
index 3bab8b8337..45b094e0c6 100644
--- a/drivers/bus/dpaa/base/qbman/qman_driver.c
+++ b/drivers/bus/dpaa/base/qbman/qman_driver.c
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  *
  * Copyright 2008-2016 Freescale Semiconductor Inc.
- * Copyright 2017-2022, 2025 NXP
+ * Copyright 2017-2022, 2025-2026 NXP
  *
  */
 
@@ -270,7 +270,7 @@ int qman_global_init(void)
 	const struct device_node *dt_node;
 	size_t lenp;
 	const u32 *chanid;
-	static int ccsr_map_fd;
+	int ccsr_map_fd;
 	const uint32_t *qman_addr;
 	uint64_t phys_addr;
 	uint64_t regs_size;
@@ -358,9 +358,9 @@ int qman_global_init(void)
 		pr_err("Can not open /dev/mem for qman ccsr map\n");
 		return ccsr_map_fd;
 	}
-
 	qman_ccsr_map = mmap(NULL, regs_size, PROT_READ | PROT_WRITE,
 			     MAP_SHARED, ccsr_map_fd, phys_addr);
+	close(ccsr_map_fd);
 	if (qman_ccsr_map == MAP_FAILED) {
 		pr_err("Can not map qman ccsr base\n");
 		return -EINVAL;
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 06/18] bus/dpaa: fix BMI RX stats register offset
From: Hemant Agrawal @ 2026-06-19  6:09 UTC (permalink / raw)
  To: stephen, david.marchand, dev; +Cc: stable, Jun Yang
In-Reply-To: <20260619060916.485258-1-hemant.agrawal@nxp.com>

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

Fix incorrect register offset for BMI RX statistics counters
in the fman.h header. The wrong offset caused incorrect stats
values to be reported.

Fixes: 0095306cdbda ("bus/dpaa: add FMan node")
Cc: stable@dpdk.org

Signed-off-by: Jun Yang <jun.yang@nxp.com>
---
 drivers/bus/dpaa/include/fman.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/bus/dpaa/include/fman.h b/drivers/bus/dpaa/include/fman.h
index c33fe81516..6e3abf1b50 100644
--- a/drivers/bus/dpaa/include/fman.h
+++ b/drivers/bus/dpaa/include/fman.h
@@ -2,7 +2,7 @@
  *
  * Copyright 2010-2012 Freescale Semiconductor, Inc.
  * All rights reserved.
- * Copyright 2019-2024 NXP
+ * Copyright 2019-2026 NXP
  *
  */
 
@@ -263,8 +263,8 @@ struct rx_bmi_regs {
 					/**< Buffer Manager pool Information-*/
 	uint32_t fmbm_acnt[FMAN_PORT_MAX_EXT_POOLS_NUM];
 					/**< Allocate Counter-*/
-	uint32_t reserved0120[16];
-					/**< 0x130/0x140 - 0x15F reserved -*/
+	uint32_t reserved0140[8];
+					/**< 0x140 - 0x15F reserved -*/
 	uint32_t fmbm_rcgm[FMAN_PORT_CG_MAP_NUM];
 					/**< Congestion Group Map*/
 	uint32_t fmbm_mpd;		/**< BM Pool Depletion  */
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 05/18] net/dpaa/fmlib: add null check in scheme delete
From: Hemant Agrawal @ 2026-06-19  6:09 UTC (permalink / raw)
  To: stephen, david.marchand, dev; +Cc: stable, Prashant Gupta
In-Reply-To: <20260619060916.485258-1-hemant.agrawal@nxp.com>

From: Prashant Gupta <prashant.gupta_3@nxp.com>

Add a null pointer check before dereferencing the scheme handle
in fm_pcd_kg_scheme_delete() to prevent potential null pointer
dereference. This matches the defensive pattern used in sibling
functions in fm_lib.c.

Fixes: 663ff698e38f ("net/dpaa: support VSP in fmlib")
Cc: stable@dpdk.org

Signed-off-by: Prashant Gupta <prashant.gupta_3@nxp.com>
---
 drivers/net/dpaa/fmlib/fm_lib.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/dpaa/fmlib/fm_lib.c b/drivers/net/dpaa/fmlib/fm_lib.c
index b35feba004..65a818372e 100644
--- a/drivers/net/dpaa/fmlib/fm_lib.c
+++ b/drivers/net/dpaa/fmlib/fm_lib.c
@@ -305,6 +305,9 @@ fm_pcd_kg_scheme_delete(t_handle h_scheme)
 
 	_fml_dbg("Calling...");
 
+	if (p_dev == NULL)
+		return E_NO_DEVICE;
+
 	p_pcd_dev =  (t_device *)p_dev->h_user_priv;
 	id.obj = UINT_TO_PTR(p_dev->id);
 
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 04/18] net/dpaa: fix modify cgr to use index
From: Hemant Agrawal @ 2026-06-19  6:09 UTC (permalink / raw)
  To: stephen, david.marchand, dev; +Cc: stable
In-Reply-To: <20260619060916.485258-1-hemant.agrawal@nxp.com>

In dpaa_modify_cgr(), the code was always using the pointer to
the first CGR element instead of indexing by the queue index.
Fix it to use the correct CGR entry by index.

Fixes: 62f53995caaf ("net/dpaa: add frame count based tail drop with CGR")
Cc: stable@dpdk.org

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

diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 9f976d179b..424458857e 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -1304,7 +1304,7 @@ int dpaa_eth_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 		rxq->nb_desc = nb_desc;
 		/* Enable tail drop with cgr on this queue */
 		qm_cgr_cs_thres_set64(&cgr_opts.cgr.cs_thres, nb_desc, 0);
-		ret = qman_modify_cgr(dpaa_intf->cgr_rx, 0, &cgr_opts);
+		ret = qman_modify_cgr(&dpaa_intf->cgr_rx[queue_idx], 0, &cgr_opts);
 		if (ret) {
 			DPAA_PMD_WARN(
 				"rx taildrop modify fail on fqid %d (ret=%d)",
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 03/18] bus/dpaa: fix error handling in qman_query
From: Hemant Agrawal @ 2026-06-19  6:09 UTC (permalink / raw)
  To: stephen, david.marchand, dev; +Cc: stable
In-Reply-To: <20260619060916.485258-1-hemant.agrawal@nxp.com>

Optimize error handling in qman_query() to avoid redundant
checks and properly propagate error codes.

Fixes: 06268e2cb175 ("bus/dpaa: query queue frame count support")
Cc: stable@dpdk.org

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 drivers/bus/dpaa/base/qbman/qman.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/bus/dpaa/base/qbman/qman.c b/drivers/bus/dpaa/base/qbman/qman.c
index 2da1b3e3f7..d289df2d33 100644
--- a/drivers/bus/dpaa/base/qbman/qman.c
+++ b/drivers/bus/dpaa/base/qbman/qman.c
@@ -1955,11 +1955,11 @@ int qman_query_fq(struct qman_fq *fq, struct qm_fqd *fqd)
 		cpu_relax();
 	DPAA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ);
 	res = mcr->result;
-	if (res == QM_MCR_RESULT_OK)
-		*fqd = mcr->queryfq.fqd;
-	hw_fqd_to_cpu(fqd);
 	if (res != QM_MCR_RESULT_OK)
 		return -EIO;
+
+	*fqd = mcr->queryfq.fqd;
+	hw_fqd_to_cpu(fqd);
 	return 0;
 }
 
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 02/18] bus/dpaa: fix fqid endianness
From: Hemant Agrawal @ 2026-06-19  6:09 UTC (permalink / raw)
  To: stephen, david.marchand, dev; +Cc: stable
In-Reply-To: <20260619060916.485258-1-hemant.agrawal@nxp.com>

In qman_fq_flow_control(), the fqid field in the management
command was set using the host-endian fqid instead of the
pre-converted big-endian fqid_be. Fix it to use fqid_be
consistent with all other enqueue paths.

Fixes: c47ff048b99a ("bus/dpaa: add QMAN driver core routines")
Cc: stable@dpdk.org

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 drivers/bus/dpaa/base/qbman/qman.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/bus/dpaa/base/qbman/qman.c b/drivers/bus/dpaa/base/qbman/qman.c
index 9a99eb9785..2da1b3e3f7 100644
--- a/drivers/bus/dpaa/base/qbman/qman.c
+++ b/drivers/bus/dpaa/base/qbman/qman.c
@@ -1921,7 +1921,7 @@ int qman_fq_flow_control(struct qman_fq *fq, int xon)
 		goto out;
 	}
 	mcc = qm_mc_start(&p->p);
-	mcc->alterfq.fqid = fq->fqid;
+	mcc->alterfq.fqid = fq->fqid_be;
 	mcc->alterfq.count = 0;
 	myverb = xon ? QM_MCC_VERB_ALTER_FQXON : QM_MCC_VERB_ALTER_FQXOFF;
 
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 01/18] bus/dpaa: fix error handling of qman_create_fq
From: Hemant Agrawal @ 2026-06-19  6:08 UTC (permalink / raw)
  To: stephen, david.marchand, dev; +Cc: stable
In-Reply-To: <20260619060916.485258-1-hemant.agrawal@nxp.com>

Fix the error handling path in qman_create_fq() to properly
return error codes instead of silently ignoring failures.

Fixes: c47ff048b99a ("bus/dpaa: add QMAN driver core routines")
Cc: stable@dpdk.org

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 drivers/bus/dpaa/base/qbman/qman.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/bus/dpaa/base/qbman/qman.c b/drivers/bus/dpaa/base/qbman/qman.c
index 5534e1846c..9a99eb9785 100644
--- a/drivers/bus/dpaa/base/qbman/qman.c
+++ b/drivers/bus/dpaa/base/qbman/qman.c
@@ -1579,6 +1579,9 @@ int qman_create_fq(u32 fqid, u32 flags, struct qman_fq *fq)
 err:
 	if (flags & QMAN_FQ_FLAG_DYNAMIC_FQID)
 		qman_release_fqid(fqid);
+#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
+	clear_fq_table_entry(fq->key);
+#endif
 	return -EIO;
 }
 
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 00/18] net/dpaa: bug fixes for bus, net and fmlib drivers
From: Hemant Agrawal @ 2026-06-19  6:08 UTC (permalink / raw)
  To: stephen, david.marchand, dev
In-Reply-To: <20260618141151.3990283-1-hemant.agrawal@nxp.com>

This series contains bug fixes for the DPAA PMD (bus/dpaa, net/dpaa,
net/dpaa/fmlib and dma/dpaa):

v2 changes:
- P05: Fix commit message API name (fm_pcd_kg_scheme_delete not FM_PCD_MatchTableSchemeDelete)
- P08: Guard DPAA_PUSH_QUEUES_NUMBER env-var override for LS1043A to prevent
  inadvertent re-enabling of push mode (errata)
- P09: Document dpaa_finish() call removal in commit message
- P10: Fix wrong Fixes: tag (was log macro commit, now correct interrupt commit)
- P11: Split into two patches with correct per-driver Fixes: tags
- P13: Also fix rx_buf_diallocate -> rx_buf_deallocate typo

All patches are bug fixes tagged with Fixes: and Cc: stable@dpdk.org.

Gagandeep Singh (3):
  bus/dpaa: fix device probe issue
  net/dpaa: fix device remove
  net/dpaa: fix invalid check on interrupt unregister

Hemant Agrawal (11):
  bus/dpaa: fix error handling of qman_create_fq
  bus/dpaa: fix fqid endianness
  bus/dpaa: fix error handling in qman_query
  net/dpaa: fix modify cgr to use index
  bus/dpaa: fix fd leak for ccsr mmap
  net/dpaa: fix xstat name for tx undersized counter
  net/dpaa: fix xstat string typos in BMI stats table
  net/dpaa: remove duplicate ptype entries
  net/dpaa: fix wrong buffer in xstats get by id
  net/dpaa: fix null l3_len check in checksum offload
  net/dpaa: fix mbuf leak in SG fd creation

Jun Yang (1):
  bus/dpaa: fix BMI RX stats register offset

Prashant Gupta (1):
  net/dpaa/fmlib: add null check in scheme delete

Vanshika Shukla (2):
  net/dpaa: fix port_handle leak in fm_prev_cleanup
  dma/dpaa: fix out-of-bounds access in SG descriptor enqueue

 drivers/bus/dpaa/base/qbman/bman_driver.c |  3 ++-
 drivers/bus/dpaa/base/qbman/qman.c        | 11 +++++----
 drivers/bus/dpaa/base/qbman/qman_driver.c |  6 ++---
 drivers/bus/dpaa/dpaa_bus.c               | 17 +++++++------
 drivers/bus/dpaa/include/fman.h           |  6 ++---
 drivers/dma/dpaa/dpaa_qdma.c              |  7 +++++-
 drivers/net/dpaa/dpaa_ethdev.c            | 29 +++++++++++------------
 drivers/net/dpaa/dpaa_flow.c              |  4 ++++
 drivers/net/dpaa/dpaa_rxtx.c              |  3 +++
 drivers/net/dpaa/fmlib/fm_lib.c           |  3 +++
 10 files changed, 53 insertions(+), 36 deletions(-)

-- 
2.43.0


^ permalink raw reply

* Re: [PATCH v3 00/20] net/sxe2: added Linkdata sxe2 ethernet driver
From: Stephen Hemminger @ 2026-06-19  2:16 UTC (permalink / raw)
  To: liujie5; +Cc: dev
In-Reply-To: <20260618082723.571054-1-liujie5@linkdatatechnology.com>

On Thu, 18 Jun 2026 16:27:03 +0800
liujie5@linkdatatechnology.com wrote:

> From: Jie Liu <liujie5@linkdatatechnology.com>
> 
> V3:
> 	Remove the `drv-sw-stats` devarg
> 
> Jie Liu (20):
>   net/sxe2: support AVX512 vectorized path for Rx and Tx
>   net/sxe2: add AVX2 vector data path for Rx and Tx
>   drivers: add supported packet types and link state
>   net/sxe2: support L2 filtering and MAC config
>   drivers: support RSS feature
>   net/sxe2: support TM hierarchy and shaping
>   net/sxe2: support IPsec inline protocol offload
>   net/sxe2: support statistics and multi-process
>   drivers: interrupt handling
>   net/sxe2: add NEON vec Rx/Tx burst functions
>   drivers: add support for VF representors
>   net/sxe2: add support for custom UDP tunnel ports
>   net/sxe2: support firmware version reading
>   net/sxe2: implement get monitor address
>   common/sxe2: add shared SFP module definitions
>   net/sxe2: support SFP module info and EEPROM access
>   net/sxe2: implement private dump info
>   net/sxe2: add mbuf validation in Tx debug mode
>   drivers: add parameters parsed using rte_kvargs
>   net/sxe2: update sxe2 feature matrix docs
> 
>  doc/guides/nics/features/sxe2.ini          |   56 +
>  doc/guides/nics/sxe2.rst                   |  132 ++
>  drivers/common/sxe2/sxe2_common.c          |  156 ++
>  drivers/common/sxe2/sxe2_common.h          |    4 +
>  drivers/common/sxe2/sxe2_flow_public.h     |  633 +++++++
>  drivers/common/sxe2/sxe2_ioctl_chnl.c      |  178 +-
>  drivers/common/sxe2/sxe2_ioctl_chnl_func.h |   18 +
>  drivers/common/sxe2/sxe2_msg.h             |  118 ++
>  drivers/net/sxe2/meson.build               |   54 +-
>  drivers/net/sxe2/sxe2_cmd_chnl.c           | 1587 +++++++++++++++-
>  drivers/net/sxe2/sxe2_cmd_chnl.h           |  139 ++
>  drivers/net/sxe2/sxe2_drv_cmd.h            |  523 +++++-
>  drivers/net/sxe2/sxe2_dump.c               |  302 +++
>  drivers/net/sxe2/sxe2_dump.h               |   12 +
>  drivers/net/sxe2/sxe2_ethdev.c             | 1515 ++++++++++++++-
>  drivers/net/sxe2/sxe2_ethdev.h             |  110 +-
>  drivers/net/sxe2/sxe2_ethdev_repr.c        |  609 ++++++
>  drivers/net/sxe2/sxe2_ethdev_repr.h        |   32 +
>  drivers/net/sxe2/sxe2_filter.c             |  895 +++++++++
>  drivers/net/sxe2/sxe2_filter.h             |  100 +
>  drivers/net/sxe2/sxe2_flow.c               | 1394 ++++++++++++++
>  drivers/net/sxe2/sxe2_flow.h               |   30 +
>  drivers/net/sxe2/sxe2_flow_define.h        |  144 ++
>  drivers/net/sxe2/sxe2_flow_parse_action.c  | 1182 ++++++++++++
>  drivers/net/sxe2/sxe2_flow_parse_action.h  |   23 +
>  drivers/net/sxe2/sxe2_flow_parse_engine.c  |  106 ++
>  drivers/net/sxe2/sxe2_flow_parse_engine.h  |   13 +
>  drivers/net/sxe2/sxe2_flow_parse_pattern.c | 1935 +++++++++++++++++++
>  drivers/net/sxe2/sxe2_flow_parse_pattern.h |   46 +
>  drivers/net/sxe2/sxe2_ipsec.c              | 1565 ++++++++++++++++
>  drivers/net/sxe2/sxe2_ipsec.h              |  254 +++
>  drivers/net/sxe2/sxe2_irq.c                | 1026 ++++++++++
>  drivers/net/sxe2/sxe2_irq.h                |   25 +
>  drivers/net/sxe2/sxe2_mac.c                |  530 ++++++
>  drivers/net/sxe2/sxe2_mac.h                |   84 +
>  drivers/net/sxe2/sxe2_mp.c                 |  414 ++++
>  drivers/net/sxe2/sxe2_mp.h                 |   67 +
>  drivers/net/sxe2/sxe2_queue.c              |   17 +-
>  drivers/net/sxe2/sxe2_queue.h              |   15 +-
>  drivers/net/sxe2/sxe2_rss.c                |  584 ++++++
>  drivers/net/sxe2/sxe2_rss.h                |   81 +
>  drivers/net/sxe2/sxe2_rx.c                 |   93 +-
>  drivers/net/sxe2/sxe2_rx.h                 |    2 +
>  drivers/net/sxe2/sxe2_security.c           |  335 ++++
>  drivers/net/sxe2/sxe2_security.h           |   77 +
>  drivers/net/sxe2/sxe2_stats.c              |  586 ++++++
>  drivers/net/sxe2/sxe2_stats.h              |   39 +
>  drivers/net/sxe2/sxe2_switchdev.c          |  332 ++++
>  drivers/net/sxe2/sxe2_switchdev.h          |   33 +
>  drivers/net/sxe2/sxe2_tm.c                 | 1169 ++++++++++++
>  drivers/net/sxe2/sxe2_tm.h                 |   78 +
>  drivers/net/sxe2/sxe2_tx.c                 |    7 +
>  drivers/net/sxe2/sxe2_txrx.c               | 1969 +++++++++++++++++++-
>  drivers/net/sxe2/sxe2_txrx.h               |    8 +
>  drivers/net/sxe2/sxe2_txrx_check_mbuf.c    |  595 ++++++
>  drivers/net/sxe2/sxe2_txrx_check_mbuf.h    |   38 +
>  drivers/net/sxe2/sxe2_txrx_poll.c          |  281 ++-
>  drivers/net/sxe2/sxe2_txrx_vec.c           |   46 +-
>  drivers/net/sxe2/sxe2_txrx_vec.h           |   38 +-
>  drivers/net/sxe2/sxe2_txrx_vec_avx2.c      |  748 ++++++++
>  drivers/net/sxe2/sxe2_txrx_vec_avx512.c    |  868 +++++++++
>  drivers/net/sxe2/sxe2_txrx_vec_common.h    |   53 +-
>  drivers/net/sxe2/sxe2_txrx_vec_neon.c      |  691 +++++++
>  drivers/net/sxe2/sxe2_txrx_vec_sse.c       |   29 +-
>  drivers/net/sxe2/sxe2_vsi.c                |  146 ++
>  drivers/net/sxe2/sxe2_vsi.h                |   12 +-
>  drivers/net/sxe2/sxe2vf_regs.h             |   85 +
>  67 files changed, 24800 insertions(+), 266 deletions(-)
>  create mode 100644 drivers/common/sxe2/sxe2_flow_public.h
>  create mode 100644 drivers/common/sxe2/sxe2_msg.h
>  create mode 100644 drivers/net/sxe2/sxe2_dump.c
>  create mode 100644 drivers/net/sxe2/sxe2_dump.h
>  create mode 100644 drivers/net/sxe2/sxe2_ethdev_repr.c
>  create mode 100644 drivers/net/sxe2/sxe2_ethdev_repr.h
>  create mode 100644 drivers/net/sxe2/sxe2_filter.c
>  create mode 100644 drivers/net/sxe2/sxe2_filter.h
>  create mode 100644 drivers/net/sxe2/sxe2_flow.c
>  create mode 100644 drivers/net/sxe2/sxe2_flow.h
>  create mode 100644 drivers/net/sxe2/sxe2_flow_define.h
>  create mode 100644 drivers/net/sxe2/sxe2_flow_parse_action.c
>  create mode 100644 drivers/net/sxe2/sxe2_flow_parse_action.h
>  create mode 100644 drivers/net/sxe2/sxe2_flow_parse_engine.c
>  create mode 100644 drivers/net/sxe2/sxe2_flow_parse_engine.h
>  create mode 100644 drivers/net/sxe2/sxe2_flow_parse_pattern.c
>  create mode 100644 drivers/net/sxe2/sxe2_flow_parse_pattern.h
>  create mode 100644 drivers/net/sxe2/sxe2_ipsec.c
>  create mode 100644 drivers/net/sxe2/sxe2_ipsec.h
>  create mode 100644 drivers/net/sxe2/sxe2_irq.c
>  create mode 100644 drivers/net/sxe2/sxe2_mac.c
>  create mode 100644 drivers/net/sxe2/sxe2_mac.h
>  create mode 100644 drivers/net/sxe2/sxe2_mp.c
>  create mode 100644 drivers/net/sxe2/sxe2_mp.h
>  create mode 100644 drivers/net/sxe2/sxe2_rss.c
>  create mode 100644 drivers/net/sxe2/sxe2_rss.h
>  create mode 100644 drivers/net/sxe2/sxe2_security.c
>  create mode 100644 drivers/net/sxe2/sxe2_security.h
>  create mode 100644 drivers/net/sxe2/sxe2_stats.c
>  create mode 100644 drivers/net/sxe2/sxe2_stats.h
>  create mode 100644 drivers/net/sxe2/sxe2_switchdev.c
>  create mode 100644 drivers/net/sxe2/sxe2_switchdev.h
>  create mode 100644 drivers/net/sxe2/sxe2_tm.c
>  create mode 100644 drivers/net/sxe2/sxe2_tm.h
>  create mode 100644 drivers/net/sxe2/sxe2_txrx_check_mbuf.c
>  create mode 100644 drivers/net/sxe2/sxe2_txrx_check_mbuf.h
>  create mode 100644 drivers/net/sxe2/sxe2_txrx_vec_avx2.c
>  create mode 100644 drivers/net/sxe2/sxe2_txrx_vec_avx512.c
>  create mode 100644 drivers/net/sxe2/sxe2_txrx_vec_neon.c
>  create mode 100644 drivers/net/sxe2/sxe2vf_regs.h
> 

I will do manual review on next series, but could you address these things
found by redoing AI review on this version.

[PATCH v3 00/20] net/sxe2: support AVX512 vectorized path

Good news first: the atomic-operations issue raised against v2 is properly
fixed. struct sxe2_rxq_sw_stats now uses plain uint64_t, the hot-path writer
uses ordinary += increments, and the if (sw_stats_en) gating is gone -
software stats are now always-on, which is what was asked for. Verified
against the assembled tree.

The rest of v3 has problems.

[PATCH v3 01/20] - and patches 02-09 - do not build

08/20 still has `if (adapter->devargs.sw_stats_en)` at sxe2_stats.c:212,
but 01/20 removed that field from struct sxe2_devargs. The series builds
at HEAD but commits 08 through 09 fail with "struct sxe2_devargs has no
member named 'sw_stats_en'". This is the same class of break as the
SXE2_DEV_TO_PCI issue in v1: the atomic-removal cleanup was applied to
the AVX512 patch (01/20) when it logically belongs to the stats patch
(08/20), and one straggler use was missed in the rebase.

The fix is twofold:
- Move the struct field removal and the cleanup of all its uses into
  08/20 ("support statistics and multi-process"), where the field is
  actually about.
- Delete the SXE2_DEVARG_SW_STATS / "drv-sw-stats" devarg entirely. After
  the atomic removal it has no consumer in the assembled tree - it is
  defined, registered with rte_kvargs and listed in
  RTE_PMD_REGISTER_PARAM_STRING, but nothing reads it. Dead code.

Please run per-commit builds before posting the next revision. Both this
break and the v1 break would have been caught by `git rebase -x "ninja
-C build" <base>`, or by devtools/test-meson-builds.sh. Two consecutive
revisions with broken bisect bands in the same series is the wrong
trend.

[PATCH v3 19/20] commit message contains LLM citation placeholders

The body has "[citation:1][citation:3][citation:5]" markers, which are
unresolved LLM output. Same shape as the "Performance shows approximately
X% improvement in small packet forwarding scenarios" placeholder in
01/20. Please rewrite both commit messages by hand.

The 19/20 commit message also describes two unrelated changes (kvargs
parsing and memseg_walk callback infrastructure). These are separate
features and should be separate patches.

Patch scope drift

The v2 review noted that 03/20 carried scope unrelated to its subject.
In v3 this got worse:
- 03/20 grew by 777 lines and now creates sxe2_txrx.c (1793 lines) under
  the subject "drivers: add supported packet types and link state". Tx/Rx
  framework is not the same feature as a ptype callback.
- 01/20 grew by 227 lines and now touches 13 files including
  sxe2_txrx_poll.c, sxe2_queue.h, sxe2_rx.c, sxe2_txrx_vec_sse.c,
  sxe2_ethdev.c/h, and meson.build. The subject is "support AVX512 vector
  path"; the atomic-removal cleanup, the struct rename of
  high_performance_mode to no_sched_mode, and the SSE common-code changes
  do not belong under that subject.
- 19/20 touches 15 files spanning kvargs, memseg walking, tm, flow, irq,
  rx, and dump. Pick one feature per patch.

Each patch should do one thing the commit message describes. The split
makes review tractable and bisect meaningful.

Devargs design - mostly unresolved from off-list discussion

Of the seven devargs, only no-sched-mode and rx-low-latency have
defensible justification. The rest need to either be removed or have
their justifications documented in sxe2.rst:

- drv-sw-stats - orphaned dead code as noted above, remove.
- flow-duplicate-pattern - default value 1 ("allow duplicate rte_flow
  rules") changes the standard rte_flow contract per boot flag. The
  duplicate-rule behaviour should be one fixed policy compiled into the
  driver, not a runtime knob; pick one and remove the devarg.
- function-flow-direct - no documented rationale anywhere. Either
  explain what cross-PMD feature this represents and why no standard API
  covers it, or remove.
- fnav-stat-type - selects which set of fnav (flow-director) counters
  the driver exposes. These should be xstats names the user picks at
  query time, not a boot-time selection.
- sched-layer-mode - TM hierarchy depth should be inferred from the
  rte_tm topology the application builds, not configured by devarg.
  Propose this as an rte_tm enhancement if the standard API really
  cannot express it.

Minor

In sxe2_parse_no_sched_mode() the local variable is still named
high_performance_mode - the rename did not propagate from the struct
field to the parser. Cosmetic, but the name no longer matches what the
function parses.

The earlier suggestion to convert the 469-entry runtime-initialised
ptype table into a single static const uint32_t with designated
initialisers was not addressed. Lower priority but still worth doing.

The atomics fix and the kvargs work are real progress - this revision
is much closer to mergeable than v2 was. The two essential items for v4
are: fix the build break in commits 08-09 (and run per-commit builds),
and the devargs cleanup. Patch scope and the commit-message placeholders
are secondary but should also be addressed.

Stephen Hemminger <stephen@networkplumber.org>

^ permalink raw reply

* Re: [PATCH v2 1/6] bpf/x86: fix JIT encoding of BPF_JSET with immediate
From: Stephen Hemminger @ 2026-06-19  2:09 UTC (permalink / raw)
  To: dev; +Cc: stable, Konstantin Ananyev, Marat Khalili, Ferruh Yigit
In-Reply-To: <20260618210026.430288-2-stephen@networkplumber.org>

On Thu, 18 Jun 2026 13:47:05 -0700
Stephen Hemminger <stephen@networkplumber.org> wrote:

> emit_tst_imm() emits TEST (0xF7 /0) but sized the immediate with
> imm_size(), which can return 1 byte. TEST has no imm8 form; it always
> takes imm32. A small mask like BPF_JSET | BPF_K #0x1 then produced a
> 4-byte instruction the CPU decodes as 7, swallowing the following Jcc
> and crashing.
> 
> Always emit a 32-bit immediate for TEST.
> 
> Bugzilla ID: 1959
> Fixes: cc752e43e079 ("bpf: add JIT compilation for x86_64 ISA")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---

Turns out there are two more places with similar bugs (spotted with AI review).

^ permalink raw reply

* Re: [PATCH v1 0/5] prefix lcore role enum values
From: Stephen Hemminger @ 2026-06-19  2:03 UTC (permalink / raw)
  To: Morten Brørup; +Cc: Huisong Li, thomas, andrew.rybchenko, dev, zhanjie9
In-Reply-To: <98CBD80474FA8B44BF855DF32C47DC35F65917@smartserver.smartshare.dk>

On Wed, 17 Jun 2026 13:48:37 +0200
Morten Brørup <mb@smartsharesystems.com> wrote:

> > From: Huisong Li [mailto:lihuisong@huawei.com]
> > Sent: Wednesday, 17 June 2026 12.28
> > 
> > Add the RTE_LCORE_ prefix to the lcore role enum values in
> > rte_lcore_role_t
> > to follow DPDK naming conventions.
> > 
> > - ROLE_RTE      -> RTE_LCORE_ROLE_RTE
> > - ROLE_OFF      -> RTE_LCORE_ROLE_OFF
> > - ROLE_SERVICE  -> RTE_LCORE_ROLE_SERVICE
> > - ROLE_NON_EAL  -> RTE_LCORE_ROLE_NON_EAL
> > 
> > Old names are kept as macros aliasing to the new names to preserve
> > backward compatibility.
> >   
> 
> Series-Acked-by: Morten Brørup <mb@smartsharesystems.com>
> 

The problem with this patch it causes build failures now with abi diff.

Example build log...


2 functions with some indirect sub-type change:





 [C] 'function rte_lcore_role_t rte_eal_lcore_role(unsigned int)' at eal_common_lcore.c:74:1 has some indirect sub-type changes:

 return type changed:

 type size hasn't changed

 4 enumerator deletions:

 'rte_lcore_role_t::ROLE_RTE' value '0'

 'rte_lcore_role_t::ROLE_OFF' value '1'

 'rte_lcore_role_t::ROLE_SERVICE' value '2'

 'rte_lcore_role_t::ROLE_NON_EAL' value '3'

 4 enumerator insertions:

 'rte_lcore_role_t::RTE_LCORE_ROLE_RTE' value '0'

 'rte_lcore_role_t::RTE_LCORE_ROLE_OFF' value '1'

 'rte_lcore_role_t::RTE_LCORE_ROLE_SERVICE' value '2'

 'rte_lcore_role_t::RTE_LCORE_ROLE_NON_EAL' value '3'





 [C] 'function int rte_lcore_has_role(unsigned int, rte_lcore_role_t)' at eal_common_lcore.c:85:1 has some indirect sub-type changes:

 parameter 2 of type 'enum rte_lcore_role_t' has sub-type changes:

 enum type 'enum rte_lcore_role_t' changed at rte_lcore.h:33:1, as reported earlier







Error: ABI issue reported for abidiff --suppr /home/runner/work/dpdk/dpdk/devtools/libabigail.abignore --no-added-syms --headers-dir1 reference/usr/local/include --headers-dir2 install/usr/local/include reference/usr/local/lib/librte_eal.so.26.1 install/usr/local/lib/librte_eal.so.26.2

^ permalink raw reply

* [PATCH v2 6/6] test/bpf: check that bpf_convert can be JIT'd
From: Stephen Hemminger @ 2026-06-18 20:47 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Konstantin Ananyev, Marat Khalili
In-Reply-To: <20260618210026.430288-1-stephen@networkplumber.org>

Add followup in bpf conversion tests to make sure resulting
code was also run through JIT and that JIT produces
same results as non-JIT.

Reduce log output to make it easier to match which
expression might be causing issues.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 app/test/test_bpf.c | 94 +++++++++++++++++++++++++++++++++++++--------
 1 file changed, 79 insertions(+), 15 deletions(-)

diff --git a/app/test/test_bpf.c b/app/test/test_bpf.c
index 3a88434c3c..973dd7d659 100644
--- a/app/test/test_bpf.c
+++ b/app/test/test_bpf.c
@@ -8,6 +8,7 @@
 #include <inttypes.h>
 #include <unistd.h>
 
+#include <rte_byteorder.h>
 #include <rte_memory.h>
 #include <rte_debug.h>
 #include <rte_hexdump.h>
@@ -32,6 +33,7 @@ test_bpf(void)
 #include <rte_bpf.h>
 #include <rte_ether.h>
 #include <rte_ip.h>
+#include <rte_udp.h>
 
 
 /* Tests of most simple BPF programs (no instructions, one instruction etc.) */
@@ -4529,6 +4531,7 @@ test_bpf_match(pcap_t *pcap, const char *str,
 	int ret = -1;
 	uint64_t rc;
 
+	printf("%s '%s'\n", __func__, str);
 	if (pcap_compile(pcap, &fcode, str, 1, PCAP_NETMASK_UNKNOWN)) {
 		printf("%s@%d: pcap_compile(\"%s\") failed: %s;\n",
 		       __func__, __LINE__,  str, pcap_geterr(pcap));
@@ -4550,6 +4553,24 @@ test_bpf_match(pcap_t *pcap, const char *str,
 	}
 
 	rc = rte_bpf_exec(bpf, mb);
+#if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_ARM64)
+	{
+		struct rte_bpf_jit jit;
+
+		rte_bpf_get_jit(bpf, &jit);
+		if (jit.func == NULL) {
+			printf("%s@%d: no JIT generated\n", __func__, __LINE__);
+			goto error;
+		}
+
+		fflush(stdout);
+		uint64_t rc_jit = jit.func(mb);
+		if (rc_jit != rc) {
+			printf("%s@%d: JIT return code does not match\n", __func__, __LINE__);
+			goto error;
+		}
+	}
+#endif
 	/* The return code from bpf capture filter is non-zero if matched */
 	ret = (rc == 0);
 error:
@@ -4560,23 +4581,16 @@ test_bpf_match(pcap_t *pcap, const char *str,
 	return ret;
 }
 
-/* Basic sanity test can we match a IP packet */
-static int
-test_bpf_filter_sanity(pcap_t *pcap)
+/* Setup mbuf for filter test */
+static void
+dummy_ip_prep(void *data, uint16_t plen)
 {
-	const uint32_t plen = 100;
-	struct rte_mbuf mb, *m;
-	uint8_t tbuf[RTE_MBUF_DEFAULT_BUF_SIZE];
 	struct {
 		struct rte_ether_hdr eth_hdr;
 		struct rte_ipv4_hdr ip_hdr;
-	} *hdr;
+		struct rte_udp_hdr udp_hdr;
+	} *hdr = data;
 
-	memset(&mb, 0, sizeof(mb));
-	dummy_mbuf_prep(&mb, tbuf, sizeof(tbuf), plen);
-	m = &mb;
-
-	hdr = rte_pktmbuf_mtod(m, typeof(hdr));
 	hdr->eth_hdr = (struct rte_ether_hdr) {
 		.dst_addr.addr_bytes = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
 		.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4),
@@ -4589,13 +4603,32 @@ test_bpf_filter_sanity(pcap_t *pcap)
 		.src_addr = rte_cpu_to_be_32(RTE_IPV4_LOOPBACK),
 		.dst_addr = rte_cpu_to_be_32(RTE_IPV4_BROADCAST),
 	};
+	hdr->udp_hdr = (struct rte_udp_hdr) {
+		.src_port = rte_rand_max(UINT16_MAX),
+		.dst_port = rte_cpu_to_be_16(9),	/* discard port */
+		.dgram_len = rte_cpu_to_be_16(plen - sizeof(struct rte_ipv4_hdr)),
+		.dgram_cksum = 0,
+	};
+}
+
+
+/* Basic sanity test can we match a IP packet */
+static int
+test_bpf_filter_sanity(pcap_t *pcap)
+{
+	struct rte_mbuf mb = { 0 };
+	uint8_t tbuf[RTE_MBUF_DEFAULT_BUF_SIZE];
+	const uint32_t plen = 100;
+
+	dummy_mbuf_prep(&mb, tbuf, sizeof(tbuf), plen);
+	dummy_ip_prep(rte_pktmbuf_mtod(&mb, void *), plen);
 
-	if (test_bpf_match(pcap, "ip", m) != 0) {
+	if (test_bpf_match(pcap, "ip", &mb) != 0) {
 		printf("%s@%d: filter \"ip\" doesn't match test data\n",
 		       __func__, __LINE__);
 		return -1;
 	}
-	if (test_bpf_match(pcap, "not ip", m) == 0) {
+	if (test_bpf_match(pcap, "not ip", &mb) == 0) {
 		printf("%s@%d: filter \"not ip\" does match test data\n",
 		       __func__, __LINE__);
 		return -1;
@@ -4648,10 +4681,15 @@ static const char * const sample_filters[] = {
 static int
 test_bpf_filter(pcap_t *pcap, const char *s)
 {
+	struct rte_mbuf mb = { 0 };
+	uint8_t tbuf[RTE_MBUF_DEFAULT_BUF_SIZE];
+	const uint32_t plen = 100;
 	struct bpf_program fcode;
 	struct rte_bpf_prm *prm = NULL;
 	struct rte_bpf *bpf = NULL;
+	int ret = -1;
 
+	printf("%s '%s'\n", __func__, s);
 	if (pcap_compile(pcap, &fcode, s, 1, PCAP_NETMASK_UNKNOWN)) {
 		printf("%s@%d: pcap_compile('%s') failed: %s;\n",
 		       __func__, __LINE__, s, pcap_geterr(pcap));
@@ -4665,8 +4703,10 @@ test_bpf_filter(pcap_t *pcap, const char *s)
 		goto error;
 	}
 
+#ifdef DEBUG
 	printf("bpf convert for \"%s\" produced:\n", s);
 	rte_bpf_dump(stdout, prm->ins, prm->nb_ins);
+#endif
 
 	bpf = rte_bpf_load(prm);
 	if (bpf == NULL) {
@@ -4675,6 +4715,30 @@ test_bpf_filter(pcap_t *pcap, const char *s)
 		goto error;
 	}
 
+	dummy_mbuf_prep(&mb, tbuf, sizeof(tbuf), plen);
+	dummy_ip_prep(rte_pktmbuf_mtod(&mb, void *), plen);
+
+	uint64_t rc = rte_bpf_exec(bpf, &mb);
+#if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_ARM64)
+	{
+		struct rte_bpf_jit jit;
+
+		rte_bpf_get_jit(bpf, &jit);
+		if (jit.func == NULL) {
+			printf("%s@%d: no JIT generated\n", __func__, __LINE__);
+			goto error;
+		}
+
+		fflush(stdout);
+		uint64_t rc_jit = jit.func(&mb);
+		if (rc_jit != rc) {
+			printf("%s@%d: JIT return code does not match\n", __func__, __LINE__);
+			goto error;
+		}
+	}
+#endif
+	ret = 0;
+
 error:
 	if (bpf)
 		rte_bpf_destroy(bpf);
@@ -4685,7 +4749,7 @@ test_bpf_filter(pcap_t *pcap, const char *s)
 
 	rte_free(prm);
 	pcap_freecode(&fcode);
-	return (bpf == NULL) ? -1 : 0;
+	return ret;
 }
 
 static int
-- 
2.53.0


^ permalink raw reply related

* [PATCH v2 5/6] bpf/arm64: add BPF_ABS/BPF_IND packet load support
From: Stephen Hemminger @ 2026-06-18 20:47 UTC (permalink / raw)
  To: dev
  Cc: Stephen Hemminger, Wathsala Vithanage, Konstantin Ananyev,
	Marat Khalili
In-Reply-To: <20260618210026.430288-1-stephen@networkplumber.org>

The arm64 JIT rejected BPF_LD | BPF_ABS and BPF_LD | BPF_IND with
"invalid opcode", so cBPF programs converted by rte_bpf_convert() could
not be JITed. Add these opcodes, mirroring the x86 JIT: a fast path for
data held in the first mbuf segment, and a __rte_pktmbuf_read() slow
path for everything else.

The forward branches over the call cannot use fixed distances:
emit_call() materializes the helper address with a variable number of
mov/movk instructions, so the block sizes are not known up front. Size
the three blocks (fast path, slow path, common tail) in a dry run, then
emit for real with the branches resolved from the measured offsets.

Programs using these opcodes use the call register layout, since the
slow path makes a function call.

Bugzilla ID: 1427

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/bpf/bpf_jit_arm64.c | 149 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 148 insertions(+), 1 deletion(-)

diff --git a/lib/bpf/bpf_jit_arm64.c b/lib/bpf/bpf_jit_arm64.c
index 67e42015de..3fc16fd984 100644
--- a/lib/bpf/bpf_jit_arm64.c
+++ b/lib/bpf/bpf_jit_arm64.c
@@ -1125,6 +1125,135 @@ emit_branch(struct a64_jit_ctx *ctx, uint8_t op, uint32_t i, int16_t off)
 	emit_b_cond(ctx, ebpf_to_a64_cond(op), jump_offset_get(ctx, i, off));
 }
 
+/* LD_ABS/LD_IND code block offsets (in arm64 instructions) */
+enum {
+	LDMB_FAST_OFS, /* fast path */
+	LDMB_SLOW_OFS, /* slow path */
+	LDMB_FIN_OFS,  /* common tail */
+	LDMB_OFS_NUM
+};
+
+/*
+ * Helper for emit_ld_mbuf(): fast path.
+ * Compute the packet offset; if it lies inside the first segment leave the
+ * data pointer in R0, otherwise branch to the slow path.
+ */
+static void
+emit_ldmb_fast_path(struct a64_jit_ctx *ctx, uint8_t src, uint8_t mode,
+		    uint32_t sz, int32_t imm, const uint32_t ofs[LDMB_OFS_NUM])
+{
+	uint8_t r0 = ebpf_to_a64_reg(ctx, EBPF_REG_0);
+	uint8_t r6 = ebpf_to_a64_reg(ctx, EBPF_REG_6);
+	uint8_t tmp1 = ebpf_to_a64_reg(ctx, TMP_REG_1);
+	uint8_t tmp2 = ebpf_to_a64_reg(ctx, TMP_REG_2);
+	uint8_t tmp3 = ebpf_to_a64_reg(ctx, TMP_REG_3);
+
+	/* off = imm (+ src for BPF_IND) */
+	emit_mov_imm(ctx, 1, tmp1, imm);
+	if (mode == BPF_IND)
+		emit_add(ctx, 1, tmp1, src);
+
+	/* if ((int64_t)(mbuf->data_len - off) < sz) goto slow_path */
+	emit_mov_imm(ctx, 1, tmp2, offsetof(struct rte_mbuf, data_len));
+	emit_ldr(ctx, BPF_H, tmp2, r6, tmp2);
+	emit_sub(ctx, 1, tmp2, tmp1);
+	emit_mov_imm(ctx, 1, tmp3, sz);
+	emit_cmp(ctx, 1, tmp2, tmp3);
+	emit_b_cond(ctx, A64_LT, (int32_t)(ofs[LDMB_SLOW_OFS] - ctx->idx));
+
+	/* R0 = mbuf->buf_addr + mbuf->data_off + off */
+	emit_mov_imm(ctx, 1, tmp2, offsetof(struct rte_mbuf, data_off));
+	emit_ldr(ctx, BPF_H, tmp2, r6, tmp2);
+	emit_mov_imm(ctx, 1, r0, offsetof(struct rte_mbuf, buf_addr));
+	emit_ldr(ctx, EBPF_DW, r0, r6, r0);
+	emit_add(ctx, 1, r0, tmp2);
+	emit_add(ctx, 1, r0, tmp1);
+
+	emit_b(ctx, (int32_t)(ofs[LDMB_FIN_OFS] - ctx->idx));
+}
+
+/*
+ * Helper for emit_ld_mbuf(): slow path.
+ * R0 = __rte_pktmbuf_read(mbuf, off, sz, buf); return 0 if NULL.
+ * The scratch buffer is the space reserved by __rte_bpf_validate() at the
+ * bottom of the eBPF stack frame, i.e. (frame_pointer - stack_ofs).
+ */
+static void
+emit_ldmb_slow_path(struct a64_jit_ctx *ctx, uint32_t sz, uint32_t stack_ofs)
+{
+	uint8_t r0 = ebpf_to_a64_reg(ctx, EBPF_REG_0);
+	uint8_t r6 = ebpf_to_a64_reg(ctx, EBPF_REG_6);
+	uint8_t fp = ebpf_to_a64_reg(ctx, EBPF_FP);
+	uint8_t tmp1 = ebpf_to_a64_reg(ctx, TMP_REG_1);
+
+	/* arguments of __rte_pktmbuf_read(mbuf, off, len, buf) */
+	emit_mov_64(ctx, A64_R(1), tmp1);		/* off (held in tmp1) */
+	emit_mov_64(ctx, A64_R(0), r6);			/* mbuf */
+	emit_mov_imm(ctx, 0, A64_R(2), sz);		/* len */
+	emit_sub_imm_64(ctx, A64_R(3), fp, stack_ofs);	/* buf */
+
+	emit_call(ctx, tmp1, (void *)(uintptr_t)__rte_pktmbuf_read);
+	emit_return_zero_if_src_zero(ctx, 1, r0);
+}
+
+/*
+ * Helper for emit_ld_mbuf(): common tail.
+ * Load the value pointed to by R0 and convert from network byte order.
+ */
+static void
+emit_ldmb_fin(struct a64_jit_ctx *ctx, uint8_t opsz, uint32_t sz)
+{
+	uint8_t r0 = ebpf_to_a64_reg(ctx, EBPF_REG_0);
+
+	emit_ldr(ctx, opsz, r0, r0, A64_ZR);
+	if (opsz != BPF_B)
+		emit_be(ctx, r0, sz * 8);
+}
+
+/*
+ * emit code for BPF_ABS/BPF_IND load.
+ * generates the following construction:
+ * fast_path:
+ *   off = src + imm
+ *   if (mbuf->data_len - off < sz)
+ *      goto slow_path;
+ *   ptr = mbuf->buf_addr + mbuf->data_off + off;
+ *   goto fin_part;
+ * slow_path:
+ *   typeof(sz) buf;  // scratch space reserved on the eBPF stack
+ *   ptr = __rte_pktmbuf_read(mbuf, off, sz, &buf);
+ *   if (ptr == NULL)
+ *      return 0;
+ * fin_part:
+ *   res = *(typeof(sz))ptr;
+ *   res = ntoh(res);
+ */
+static void
+emit_ld_mbuf(struct a64_jit_ctx *ctx, uint8_t op, uint8_t src, int32_t imm,
+	     uint32_t stack_ofs)
+{
+	uint8_t mode = BPF_MODE(op);
+	uint8_t opsz = BPF_SIZE(op);
+	uint32_t sz = bpf_size(opsz);
+	uint32_t ofs[LDMB_OFS_NUM];
+
+	/* seed offsets so the dry-run branches stay in range */
+	ofs[LDMB_FAST_OFS] = ofs[LDMB_SLOW_OFS] = ofs[LDMB_FIN_OFS] = ctx->idx;
+
+	/* dry run to record block offsets */
+	emit_ldmb_fast_path(ctx, src, mode, sz, imm, ofs);
+	ofs[LDMB_SLOW_OFS] = ctx->idx;
+	emit_ldmb_slow_path(ctx, sz, stack_ofs);
+	ofs[LDMB_FIN_OFS] = ctx->idx;
+	emit_ldmb_fin(ctx, opsz, sz);
+
+	/* rewind and emit for real with resolved offsets */
+	ctx->idx = ofs[LDMB_FAST_OFS];
+	emit_ldmb_fast_path(ctx, src, mode, sz, imm, ofs);
+	emit_ldmb_slow_path(ctx, sz, stack_ofs);
+	emit_ldmb_fin(ctx, opsz, sz);
+}
+
 static void
 check_program_has_call(struct a64_jit_ctx *ctx, struct rte_bpf *bpf)
 {
@@ -1137,8 +1266,17 @@ check_program_has_call(struct a64_jit_ctx *ctx, struct rte_bpf *bpf)
 		op = ins->code;
 
 		switch (op) {
-		/* Call imm */
+		/*
+		 * BPF_ABS/BPF_IND can fall through to __rte_pktmbuf_read(),
+		 * so they need the call-clobbered register layout as well.
+		 */
 		case (BPF_JMP | EBPF_CALL):
+		case (BPF_LD | BPF_ABS | BPF_B):
+		case (BPF_LD | BPF_ABS | BPF_H):
+		case (BPF_LD | BPF_ABS | BPF_W):
+		case (BPF_LD | BPF_IND | BPF_B):
+		case (BPF_LD | BPF_IND | BPF_H):
+		case (BPF_LD | BPF_IND | BPF_W):
 			ctx->foundcall = 1;
 			return;
 		}
@@ -1340,6 +1478,15 @@ emit(struct a64_jit_ctx *ctx, struct rte_bpf *bpf)
 			emit_mov_imm(ctx, 1, dst, u64);
 			i++;
 			break;
+		/* R0 = ntoh(*(size *)(mbuf data + (src) + imm)) */
+		case (BPF_LD | BPF_ABS | BPF_B):
+		case (BPF_LD | BPF_ABS | BPF_H):
+		case (BPF_LD | BPF_ABS | BPF_W):
+		case (BPF_LD | BPF_IND | BPF_B):
+		case (BPF_LD | BPF_IND | BPF_H):
+		case (BPF_LD | BPF_IND | BPF_W):
+			emit_ld_mbuf(ctx, op, src, imm, bpf->stack_sz);
+			break;
 		/* *(size *)(dst + off) = src */
 		case (BPF_STX | BPF_MEM | BPF_B):
 		case (BPF_STX | BPF_MEM | BPF_H):
-- 
2.53.0


^ permalink raw reply related

* [PATCH v2 4/6] test/bpf: check that JIT was generated
From: Stephen Hemminger @ 2026-06-18 20:47 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Marat Khalili, Konstantin Ananyev
In-Reply-To: <20260618210026.430288-1-stephen@networkplumber.org>

Avoid silently ignoring JIT failures. The test cases should
all succeed JIT compilation; if not it is a bug in the JIT
implementation and should be reported.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Marat Khalili <marat.khalili@huawei.com>
---
 app/test/test_bpf.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/app/test/test_bpf.c b/app/test/test_bpf.c
index e70dea736f..3a88434c3c 100644
--- a/app/test/test_bpf.c
+++ b/app/test/test_bpf.c
@@ -3590,6 +3590,14 @@ run_test(const struct bpf_test *tst)
 				rv, strerror(rv));
 		}
 	}
+#if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_ARM64)
+	else {
+		/* a JIT backend exists for this arch, so it must compile */
+		printf("%s@%d: %s: no JIT code generated;\n",
+			__func__, __LINE__, tst->name);
+		ret = -1;
+	}
+#endif
 
 	rte_bpf_destroy(bpf);
 	return ret;
-- 
2.53.0


^ permalink raw reply related

* [PATCH v2 3/6] bpf/arm64: fix offset type to allow a negative jump
From: Stephen Hemminger @ 2026-06-18 20:47 UTC (permalink / raw)
  To: dev
  Cc: Christophe Fontaine, stable, Stephen Hemminger,
	Wathsala Vithanage, Konstantin Ananyev, Marat Khalili,
	Jerin Jacob
In-Reply-To: <20260618210026.430288-1-stephen@networkplumber.org>

From: Christophe Fontaine <cfontain@redhat.com>

The DPDK BPF JIT standalone test test_ld_mbuf1 fails on arm64.
It does:
	r6 = r1                    // mbuf
	r0 = *(u8 *)pkt[0]         // BPF_ABS
	if ((r0 & 0xf0) == 0x40)
		goto parse
	r0 = 0
	exit                       // epilogue E0
parse:
	r0 = *(u8 *)pkt[r0 + 3]    // BPF_IND
	...
	exit

emit_return_zero_if_src_zero() returns 0 by branching to a function
epilogue. The target maybe a previous epilogue so branch
might be backwards; therefore the offset needs to be negative.

The offset was stored in a uint16_t, so a negative value wrapped to a
large positive number; emit_b() then branched past the end of the
program and faulted at run time.

Fixes: 111e2a747a4f ("bpf/arm: add basic arithmetic operations")
Cc: stable@dpdk.org

Signed-off-by: Christophe Fontaine <cfontain@redhat.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/bpf/bpf_jit_arm64.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/lib/bpf/bpf_jit_arm64.c b/lib/bpf/bpf_jit_arm64.c
index a04ef33a9c..67e42015de 100644
--- a/lib/bpf/bpf_jit_arm64.c
+++ b/lib/bpf/bpf_jit_arm64.c
@@ -957,10 +957,12 @@ static void
 emit_return_zero_if_src_zero(struct a64_jit_ctx *ctx, bool is64, uint8_t src)
 {
 	uint8_t r0 = ebpf_to_a64_reg(ctx, EBPF_REG_0);
-	uint16_t jump_to_epilogue;
+	int32_t jump_to_epilogue;
 
 	emit_cbnz(ctx, is64, src, 3);
 	emit_mov_imm(ctx, is64, r0, 0);
+
+	/* maybe backwards branch to earlier epilogue */
 	jump_to_epilogue = (ctx->program_start + ctx->program_sz) - ctx->idx;
 	emit_b(ctx, jump_to_epilogue);
 }
-- 
2.53.0


^ 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