DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v5] graph: add optional profiling stats
From: Jerin Jacob @ 2026-06-23  5:13 UTC (permalink / raw)
  To: Morten Brørup
  Cc: dev, Jerin Jacob, Kiran Kumar K, Nithin Dabilpuram, Zhirun Yan
In-Reply-To: <20260621184140.2878132-1-mb@smartsharesystems.com>

On Mon, Jun 22, 2026 at 12:11 AM Morten Brørup <mb@smartsharesystems.com> wrote:
>
> Added graph node profiling stats, build time configurable by enabling
> RTE_GRAPH_PROFILE in rte_config.h.
>
> Signed-off-by: Morten Brørup <mb@smartsharesystems.com>
> ---
> v5:
> * Added stats for a half burst and a full burst.
> v4:
> * Added documentation. (AI)
> * Added more comments. (AI)
> * Improved dump. (AI)
> * Debug shows both cycles/call and cycles/obj.
> v3:
> * Debug shows cycles/obj instead of cycles/call.
> * Fixed missing --in-reply-to.
> v2:
> * Fixed indentation.
> ---
>  config/rte_config.h                 |  1 +
>  doc/guides/prog_guide/graph_lib.rst |  1 +
>  lib/graph/graph_debug.c             | 57 ++++++++++++++++++++++++++++-
>  lib/graph/node.c                    |  2 +
>  lib/graph/rte_graph_worker_common.h | 33 +++++++++++++++--

Please update app/test/test_graph.c to validate this featue.

>  5 files changed, 90 insertions(+), 4 deletions(-)
>
> diff --git a/config/rte_config.h b/config/rte_config.h
> index 0447cdf2ad..1942c1b1ec 100644
> --- a/config/rte_config.h
> +++ b/config/rte_config.h
> @@ -106,6 +106,7 @@
>  /* rte_graph defines */
>  #define RTE_GRAPH_BURST_SIZE 256
>  #define RTE_LIBRTE_GRAPH_STATS 1
> +/* RTE_GRAPH_PROFILE is not set */
>
>  /****** driver defines ********/
>
> diff --git a/doc/guides/prog_guide/graph_lib.rst b/doc/guides/prog_guide/graph_lib.rst
> index 8dd49c19d2..bc36042296 100644
> --- a/doc/guides/prog_guide/graph_lib.rst
> +++ b/doc/guides/prog_guide/graph_lib.rst
> @@ -49,6 +49,7 @@ Performance tuning parameters
>    RTE_GRAPH_BURST_SIZE config option.
>    The testing shows, on x86 and arm64 servers, The sweet spot is 256 burst
>    size. While on arm64 embedded SoCs, it is either 64 or 128.
> +- Enable the ``RTE_GRAPH_PROFILE`` config option for more profiling details.
>  - Disable node statistics (using ``RTE_LIBRTE_GRAPH_STATS`` config option)
>    if not needed.
>
> diff --git a/lib/graph/graph_debug.c b/lib/graph/graph_debug.c
> index e3b8cccdc1..7c97e23748 100644
> --- a/lib/graph/graph_debug.c
> +++ b/lib/graph/graph_debug.c
> @@ -92,7 +92,62 @@ rte_graph_obj_dump(FILE *f, struct rte_graph *g, bool all)
>                         fprintf(f, "       total_sched_fail=%" PRId64 "\n",
>                                 n->dispatch.total_sched_fail);
>                 }
> -               fprintf(f, "       total_calls=%" PRId64 "\n", n->total_calls);
> +               fprintf(f, "       total_calls=%" PRIu64 "\n", n->total_calls);
> +               if (rte_graph_has_stats_feature()) {
> +                       fprintf(f, "       total_cycles=%" PRIu64 ", avg cycles/call=%.1f\n",
> +                                       n->total_cycles,
> +                                       n->total_calls == 0 ? (double)0 :
> +                                       (double)n->total_cycles / (double)n->total_calls);
> +               }
> +#ifdef RTE_GRAPH_PROFILE


Please introduce rte_graph_has_profile_featue() similar to
rte_graph_has_stats_feature() to reduce if def clutter as possible.

> +               uint64_t calls = n->usage_stats[0].calls;
> +               fprintf(f, "       objs[0]\n");
> +               fprintf(f, "         calls=%" PRIu64 ", cycles=%" PRIu64 ", avg cycles/call=%.1f\n",
> +                               calls,

>
> diff --git a/lib/graph/rte_graph_worker_common.h b/lib/graph/rte_graph_worker_common.h
> index 4ab53a533e..0d8039575d 100644
> --- a/lib/graph/rte_graph_worker_common.h
> +++ b/lib/graph/rte_graph_worker_common.h
> @@ -144,12 +144,26 @@ struct __rte_cache_aligned rte_node {
>                         rte_node_process_t process; /**< Process function. */
>                         uint64_t process_u64;
>                 };
> +               /** Fast path area cache line 3. */
> +#ifdef RTE_GRAPH_PROFILE
> +               struct {
> +                       uint64_t calls;     /**< Calls processing resp. 0 or 1 objects. */
> +                       uint64_t cycles;    /**< Cycles spent processing resp. 0 or 1 objects. */
> +               } usage_stats[2];       /**< Usage when this node processed 0 or 1 objects. */
> +               uint64_t full_burst_calls;  /**< Calls processing a full burst of objects. */
> +               uint64_t full_burst_cycles; /**< Cycles spent processing a full burst of objects. */
> +               uint64_t half_burst_calls;  /**< Calls processing a half burst of objects. */
> +               uint64_t half_burst_cycles; /**< Cycles spent processing a half burst of objects. */
> +               /** Fast path area cache line 4. */
> +#endif

Is it an ABI breakage?

>                 alignas(RTE_CACHE_LINE_MIN_SIZE) struct rte_node *nodes[]; /**< Next nodes. */
>         };
>  };
>

^ permalink raw reply

* [PATCH] app/dma_perf: skip case if worker maps to main lcore
From: Rupesh Chiluka @ 2026-06-23  4:58 UTC (permalink / raw)
  To: Cheng Jiang, Chengwen Feng; +Cc: dev, gakhil, anoobj, ktejasree, Rupesh Chiluka

Refuse to run DMA/CPU mem-copy cases when any worker is bound to the
EAL main lcore.

Signed-off-by: Rupesh Chiluka <rchiluka@marvell.com>
---
 app/test-dma-perf/main.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/app/test-dma-perf/main.c b/app/test-dma-perf/main.c
index 4249dcfd3d..b6aa5b8401 100644
--- a/app/test-dma-perf/main.c
+++ b/app/test-dma-perf/main.c
@@ -109,6 +109,7 @@ run_test_case(struct test_configure *case_cfg)
 static void
 run_test(uint32_t case_id, struct test_configure *case_cfg)
 {
+	uint32_t main_lcore = rte_get_main_lcore();
 	uint32_t nb_lcores = rte_lcore_count();
 	struct test_configure_entry *mem_size = &case_cfg->mem_size;
 	struct test_configure_entry *buf_size = &case_cfg->buf_size;
@@ -122,6 +123,14 @@ run_test(uint32_t case_id, struct test_configure *case_cfg)
 		return;
 	}
 
+	for (uint32_t i = 0; i < case_cfg->num_worker; i++) {
+		if (case_cfg->dma_config[i].lcore_dma_map.lcore == main_lcore) {
+			printf("Case %u: worker %u cannot run on the EAL main lcore (%u).\n",
+			       case_id, i, main_lcore);
+			return;
+		}
+	}
+
 	printf("Number of used lcores: %u.\n", nb_lcores);
 
 	if (mem_size->incr != 0)
-- 
2.48.1


^ permalink raw reply related

* [PATCH v2 3/3] test/crypto: add unit test for Rx inject multi seg
From: Tejasree Kondoj @ 2026-06-23  4:27 UTC (permalink / raw)
  To: Akhil Goyal, Fan Zhang; +Cc: Vidya Sagar Velumuri, Anoob Joseph, dev
In-Reply-To: <20260623042723.89226-1-ktejasree@marvell.com>

From: Vidya Sagar Velumuri <vvelumuri@marvell.com>

Add unit test to verify the multi segment support in RX Inject

Signed-off-by: Vidya Sagar Velumuri <vvelumuri@marvell.com>
Signed-off-by: Tejasree Kondoj <ktejasree@marvell.com>
---
 app/test/test_cryptodev.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c
index 884629ec8c..fd02107baf 100644
--- a/app/test/test_cryptodev.c
+++ b/app/test/test_cryptodev.c
@@ -1564,7 +1564,8 @@ ut_setup_security_rx_inject(void)
 	struct rte_eth_conf port_conf = {
 		.rxmode = {
 			.offloads = RTE_ETH_RX_OFFLOAD_CHECKSUM |
-				    RTE_ETH_RX_OFFLOAD_SECURITY,
+				    RTE_ETH_RX_OFFLOAD_SECURITY |
+					RTE_ETH_RX_OFFLOAD_SCATTER,
 		},
 		.txmode = {
 			.offloads = RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE,
@@ -10781,6 +10782,25 @@ test_ipsec_proto_known_vec_inb_rx_inject(const void *test_data)
 	return test_ipsec_proto_process(&td_inb, NULL, 1, false, &flags);
 }
 
+static int
+test_ipsec_proto_known_vec_inb_rx_inject_multi_seg(const void *test_data)
+{
+	const struct ipsec_test_data *td = test_data;
+	struct ipsec_test_flags flags;
+	struct ipsec_test_data td_inb;
+
+	memset(&flags, 0, sizeof(flags));
+	flags.rx_inject = true;
+	flags.nb_segs_in_mbuf = 4;
+
+	if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS)
+		test_ipsec_td_in_from_out(td, &td_inb);
+	else
+		memcpy(&td_inb, td, sizeof(td_inb));
+
+	return test_ipsec_proto_process(&td_inb, NULL, 1, false, &flags);
+}
+
 static int
 test_ipsec_proto_all(const struct ipsec_test_flags *flags)
 {
@@ -18389,6 +18409,11 @@ static struct unit_test_suite ipsec_proto_testsuite  = {
 			"Inbound known vector (ESP tunnel mode IPv4 AES-GCM 128) Rx inject",
 			ut_setup_security_rx_inject, ut_teardown_rx_inject,
 			test_ipsec_proto_known_vec_inb_rx_inject, &pkt_aes_128_gcm),
+		TEST_CASE_NAMED_WITH_DATA(
+			"Inbound known vector (ESP tunnel mode IPv4 AES-GCM 128) Rx inject multi seg",
+			ut_setup_security_rx_inject, ut_teardown_rx_inject,
+			test_ipsec_proto_known_vec_inb_rx_inject_multi_seg, &pkt_aes_128_gcm),
+
 		TEST_CASES_END() /**< NULL terminate unit test array */
 	}
 };
-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 2/3] test/crypto: add autotest support for cn20k
From: Tejasree Kondoj @ 2026-06-23  4:27 UTC (permalink / raw)
  To: Akhil Goyal, Fan Zhang; +Cc: Vidya Sagar Velumuri, Anoob Joseph, dev
In-Reply-To: <20260623042723.89226-1-ktejasree@marvell.com>

From: Vidya Sagar Velumuri <vvelumuri@marvell.com>

Add crypto autotest support for cn20k

Signed-off-by: Vidya Sagar Velumuri <vvelumuri@marvell.com>
Signed-off-by: Tejasree Kondoj <ktejasree@marvell.com>
---
 app/test/test_cryptodev.c | 15 +++++++++++++++
 app/test/test_cryptodev.h |  1 +
 2 files changed, 16 insertions(+)

diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c
index b908f10317..884629ec8c 100644
--- a/app/test/test_cryptodev.c
+++ b/app/test/test_cryptodev.c
@@ -20863,6 +20863,18 @@ test_cryptodev_cn10k_raw_api(void)
 	return run_cryptodev_raw_testsuite(RTE_STR(CRYPTODEV_NAME_CN10K_PMD));
 }
 
+static int
+test_cryptodev_cn20k(void)
+{
+	return run_cryptodev_testsuite(RTE_STR(CRYPTODEV_NAME_CN20K_PMD));
+}
+
+static int
+test_cryptodev_cn20k_raw_api(void)
+{
+	return run_cryptodev_raw_testsuite(RTE_STR(CRYPTODEV_NAME_CN20K_PMD));
+}
+
 static int
 test_cryptodev_dpaa2_sec_raw_api(void)
 {
@@ -20883,6 +20895,8 @@ test_cryptodev_zsda(void)
 
 REGISTER_DRIVER_TEST(cryptodev_cn10k_raw_api_autotest,
 		test_cryptodev_cn10k_raw_api);
+REGISTER_DRIVER_TEST(cryptodev_cn20k_raw_api_autotest,
+		test_cryptodev_cn20k_raw_api);
 REGISTER_DRIVER_TEST(cryptodev_dpaa2_sec_raw_api_autotest,
 		test_cryptodev_dpaa2_sec_raw_api);
 REGISTER_DRIVER_TEST(cryptodev_dpaa_sec_raw_api_autotest,
@@ -20915,4 +20929,5 @@ REGISTER_DRIVER_TEST(cryptodev_nitrox_autotest, test_cryptodev_nitrox);
 REGISTER_DRIVER_TEST(cryptodev_bcmfs_autotest, test_cryptodev_bcmfs);
 REGISTER_DRIVER_TEST(cryptodev_cn9k_autotest, test_cryptodev_cn9k);
 REGISTER_DRIVER_TEST(cryptodev_cn10k_autotest, test_cryptodev_cn10k);
+REGISTER_DRIVER_TEST(cryptodev_cn20k_autotest, test_cryptodev_cn20k);
 REGISTER_DRIVER_TEST(cryptodev_zsda_autotest, test_cryptodev_zsda);
diff --git a/app/test/test_cryptodev.h b/app/test/test_cryptodev.h
index 49aa45ec17..d125dea958 100644
--- a/app/test/test_cryptodev.h
+++ b/app/test/test_cryptodev.h
@@ -74,6 +74,7 @@
 #define CRYPTODEV_NAME_BCMFS_PMD	crypto_bcmfs
 #define CRYPTODEV_NAME_CN9K_PMD		crypto_cn9k
 #define CRYPTODEV_NAME_CN10K_PMD	crypto_cn10k
+#define CRYPTODEV_NAME_CN20K_PMD	crypto_cn20k
 #define CRYPTODEV_NAME_MLX5_PMD		crypto_mlx5
 #define CRYPTODEV_NAME_UADK_PMD		crypto_uadk
 #define CRYPTODEV_NAME_ZSDA_SYM_PMD	crypto_zsda
-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 1/3] test/crypto: add asym autotest support for cn20k
From: Tejasree Kondoj @ 2026-06-23  4:27 UTC (permalink / raw)
  To: Akhil Goyal, Fan Zhang; +Cc: Vidya Sagar Velumuri, Anoob Joseph, dev
In-Reply-To: <20260623042723.89226-1-ktejasree@marvell.com>

From: Vidya Sagar Velumuri <vvelumuri@marvell.com>

Add crypto asym autotest support for cn20k

Signed-off-by: Vidya Sagar Velumuri <vvelumuri@marvell.com>
Signed-off-by: Tejasree Kondoj <ktejasree@marvell.com>
---
 app/test/test_cryptodev_asym.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/app/test/test_cryptodev_asym.c b/app/test/test_cryptodev_asym.c
index 90af49e485..7b8afe5f92 100644
--- a/app/test/test_cryptodev_asym.c
+++ b/app/test/test_cryptodev_asym.c
@@ -5500,6 +5500,12 @@ test_cryptodev_cn10k_asym(void)
 	return run_cryptodev_asym_testsuite(RTE_STR(CRYPTODEV_NAME_CN10K_PMD));
 }
 
+static int
+test_cryptodev_cn20k_asym(void)
+{
+	return run_cryptodev_asym_testsuite(RTE_STR(CRYPTODEV_NAME_CN20K_PMD));
+}
+
 static int
 test_cryptodev_virtio_asym(void)
 {
@@ -5517,5 +5523,6 @@ REGISTER_DRIVER_TEST(cryptodev_qat_asym_autotest, test_cryptodev_qat_asym);
 REGISTER_DRIVER_TEST(cryptodev_octeontx_asym_autotest, test_cryptodev_octeontx_asym);
 REGISTER_DRIVER_TEST(cryptodev_cn9k_asym_autotest, test_cryptodev_cn9k_asym);
 REGISTER_DRIVER_TEST(cryptodev_cn10k_asym_autotest, test_cryptodev_cn10k_asym);
+REGISTER_DRIVER_TEST(cryptodev_cn20k_asym_autotest, test_cryptodev_cn20k_asym);
 REGISTER_DRIVER_TEST(cryptodev_virtio_asym_autotest, test_cryptodev_virtio_asym);
 REGISTER_DRIVER_TEST(cryptodev_virtio_user_asym_autotest, test_cryptodev_virtio_user_asym);
-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 0/3] update tests with CN20K support
From: Tejasree Kondoj @ 2026-06-23  4:27 UTC (permalink / raw)
  To: Akhil Goyal, Fan Zhang; +Cc: Vidya Sagar Velumuri, Anoob Joseph, dev

Add CN20K sym/asym autotests and Rx-inject multi-segment unit test.

v2:
- Removed asym sessionless test patch
- Fixed test names ordering

Vidya Sagar Velumuri (3):
  test/crypto: add asym autotest support for cn20k
  test/crypto: add autotest support for cn20k
  test/crypto: add unit test for Rx inject multi seg

 app/test/test_cryptodev.c      | 42 +++++++++++++++++++++++++++++++++-
 app/test/test_cryptodev.h      |  1 +
 app/test/test_cryptodev_asym.c |  7 ++++++
 3 files changed, 49 insertions(+), 1 deletion(-)

-- 
2.34.1


^ permalink raw reply

* [PATCH] examples/l3fwd: dynamic NUMA-aware alloc lcore_conf
From: Chengwen Feng @ 2026-06-23  3:23 UTC (permalink / raw)
  To: thomas, stephen; +Cc: dev

Currently lcore_conf is a global static array. When multiple
ports/lcores are distributed across different NUMA nodes, datapath
suffers from severe cross-NUMA memory access penalty.

On Kunpeng platform, sizeof(struct lcore_conf) reaches 133760 bytes.
Such a huge per-lcore structure significantly amplifies cross-NUMA
overhead in multi-port multi-NUMA deployment scenarios.

This commit refactors lcore_conf to pointer array and implements
per-lcore NUMA-aware hugepage allocation, allocating each lcore's
configuration on its local socket to eliminate remote memory access.

Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
---
 examples/l3fwd/l3fwd.h     |  2 +-
 examples/l3fwd/l3fwd_acl.c |  2 +-
 examples/l3fwd/l3fwd_em.c  |  8 ++++----
 examples/l3fwd/l3fwd_fib.c |  6 +++---
 examples/l3fwd/l3fwd_lpm.c |  8 ++++----
 examples/l3fwd/main.c      | 42 ++++++++++++++++++++++++++++++--------
 6 files changed, 46 insertions(+), 22 deletions(-)

diff --git a/examples/l3fwd/l3fwd.h b/examples/l3fwd/l3fwd.h
index 349fc37c79..20c457ee7f 100644
--- a/examples/l3fwd/l3fwd.h
+++ b/examples/l3fwd/l3fwd.h
@@ -104,7 +104,7 @@ extern uint32_t hash_entry_number;
 
 extern xmm_t val_eth[RTE_MAX_ETHPORTS];
 
-extern struct lcore_conf lcore_conf[RTE_MAX_LCORE];
+extern struct lcore_conf *lcore_conf[RTE_MAX_LCORE];
 
 extern struct parm_cfg parm_config;
 
diff --git a/examples/l3fwd/l3fwd_acl.c b/examples/l3fwd/l3fwd_acl.c
index 4ee3411d2a..0605f6feb9 100644
--- a/examples/l3fwd/l3fwd_acl.c
+++ b/examples/l3fwd/l3fwd_acl.c
@@ -1090,7 +1090,7 @@ acl_main_loop(__rte_unused void *dummy)
 
 	prev_tsc = 0;
 	lcore_id = rte_lcore_id();
-	qconf = &lcore_conf[lcore_id];
+	qconf = lcore_conf[lcore_id];
 	socketid = rte_lcore_to_socket_id(lcore_id);
 
 	if (qconf->n_rx_queue == 0) {
diff --git a/examples/l3fwd/l3fwd_em.c b/examples/l3fwd/l3fwd_em.c
index d8748a0edd..9aa23759d3 100644
--- a/examples/l3fwd/l3fwd_em.c
+++ b/examples/l3fwd/l3fwd_em.c
@@ -597,7 +597,7 @@ em_main_loop(__rte_unused void *dummy)
 		US_PER_S * BURST_TX_DRAIN_US;
 
 	lcore_id = rte_lcore_id();
-	qconf = &lcore_conf[lcore_id];
+	qconf = lcore_conf[lcore_id];
 
 	const uint16_t n_rx_q = qconf->n_rx_queue;
 	const uint16_t n_tx_p = qconf->n_tx_port;
@@ -685,7 +685,7 @@ em_event_loop_single(struct l3fwd_event_resources *evt_rsrc,
 		return;
 
 	lcore_id = rte_lcore_id();
-	lconf = &lcore_conf[lcore_id];
+	lconf = lcore_conf[lcore_id];
 
 	RTE_LOG(INFO, L3FWD, "entering %s on lcore %u\n", __func__, lcore_id);
 	while (!force_quit) {
@@ -747,7 +747,7 @@ em_event_loop_burst(struct l3fwd_event_resources *evt_rsrc,
 
 	lcore_id = rte_lcore_id();
 
-	lconf = &lcore_conf[lcore_id];
+	lconf = lcore_conf[lcore_id];
 
 	RTE_LOG(INFO, L3FWD, "entering %s on lcore %u\n", __func__, lcore_id);
 
@@ -877,7 +877,7 @@ em_event_loop_vector(struct l3fwd_event_resources *evt_rsrc,
 	if (dst_ports == NULL)
 		return;
 	lcore_id = rte_lcore_id();
-	lconf = &lcore_conf[lcore_id];
+	lconf = lcore_conf[lcore_id];
 
 	RTE_LOG(INFO, L3FWD, "entering %s on lcore %u\n", __func__, lcore_id);
 
diff --git a/examples/l3fwd/l3fwd_fib.c b/examples/l3fwd/l3fwd_fib.c
index 4fc6bf90d5..32c8847130 100644
--- a/examples/l3fwd/l3fwd_fib.c
+++ b/examples/l3fwd/l3fwd_fib.c
@@ -192,7 +192,7 @@ fib_main_loop(__rte_unused void *dummy)
 			US_PER_S * BURST_TX_DRAIN_US;
 
 	lcore_id = rte_lcore_id();
-	qconf = &lcore_conf[lcore_id];
+	qconf = lcore_conf[lcore_id];
 
 	const uint16_t n_rx_q = qconf->n_rx_queue;
 	const uint16_t n_tx_p = qconf->n_tx_port;
@@ -282,7 +282,7 @@ fib_event_loop(struct l3fwd_event_resources *evt_rsrc,
 
 	lcore_id = rte_lcore_id();
 
-	lconf = &lcore_conf[lcore_id];
+	lconf = lcore_conf[lcore_id];
 
 	RTE_LOG(INFO, L3FWD, "entering %s on lcore %u\n", __func__, lcore_id);
 
@@ -446,7 +446,7 @@ fib_process_event_vector(struct rte_event_vector *vec, uint8_t *type_arr,
 	uint16_t nh;
 	int i;
 
-	lconf = &lcore_conf[rte_lcore_id()];
+	lconf = lcore_conf[rte_lcore_id()];
 
 	/* Reset counters. */
 	ipv4_cnt = 0;
diff --git a/examples/l3fwd/l3fwd_lpm.c b/examples/l3fwd/l3fwd_lpm.c
index 2d2651e750..77701503f7 100644
--- a/examples/l3fwd/l3fwd_lpm.c
+++ b/examples/l3fwd/l3fwd_lpm.c
@@ -154,7 +154,7 @@ lpm_main_loop(__rte_unused void *dummy)
 		US_PER_S * BURST_TX_DRAIN_US;
 
 	lcore_id = rte_lcore_id();
-	qconf = &lcore_conf[lcore_id];
+	qconf = lcore_conf[lcore_id];
 
 	const uint16_t n_rx_q = qconf->n_rx_queue;
 	const uint16_t n_tx_p = qconf->n_tx_port;
@@ -270,7 +270,7 @@ lpm_event_loop_single(struct l3fwd_event_resources *evt_rsrc,
 		return;
 
 	lcore_id = rte_lcore_id();
-	lconf = &lcore_conf[lcore_id];
+	lconf = lcore_conf[lcore_id];
 
 	RTE_LOG(INFO, L3FWD, "entering %s on lcore %u\n", __func__, lcore_id);
 	while (!force_quit) {
@@ -324,7 +324,7 @@ lpm_event_loop_burst(struct l3fwd_event_resources *evt_rsrc,
 
 	lcore_id = rte_lcore_id();
 
-	lconf = &lcore_conf[lcore_id];
+	lconf = lcore_conf[lcore_id];
 
 	RTE_LOG(INFO, L3FWD, "entering %s on lcore %u\n", __func__, lcore_id);
 
@@ -468,7 +468,7 @@ lpm_event_loop_vector(struct l3fwd_event_resources *evt_rsrc,
 		return;
 
 	lcore_id = rte_lcore_id();
-	lconf = &lcore_conf[lcore_id];
+	lconf = lcore_conf[lcore_id];
 	dst_port_list =
 		rte_zmalloc("", sizeof(uint16_t) * evt_rsrc->vector_size,
 			    RTE_CACHE_LINE_SIZE);
diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index df035b508c..c533a90bb4 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -96,7 +96,7 @@ uint32_t enabled_port_mask;
 /* Used only in exact match mode. */
 bool ipv6_enabled; /**< ipv6 is false by default. */
 
-struct lcore_conf lcore_conf[RTE_MAX_LCORE];
+struct lcore_conf *lcore_conf[RTE_MAX_LCORE];
 
 struct parm_cfg parm_config;
 
@@ -368,17 +368,17 @@ init_lcore_rx_queues(void)
 
 	for (i = 0; i < nb_lcore_params; ++i) {
 		lcore = lcore_params[i].lcore_id;
-		nb_rx_queue = lcore_conf[lcore].n_rx_queue;
+		nb_rx_queue = lcore_conf[lcore]->n_rx_queue;
 		if (nb_rx_queue >= MAX_RX_QUEUE_PER_LCORE) {
 			printf("error: too many queues (%u) for lcore: %u\n",
 				(unsigned int)nb_rx_queue + 1, lcore);
 			return -1;
 		} else {
-			lcore_conf[lcore].rx_queue_list[nb_rx_queue].port_id =
+			lcore_conf[lcore]->rx_queue_list[nb_rx_queue].port_id =
 				lcore_params[i].port_id;
-			lcore_conf[lcore].rx_queue_list[nb_rx_queue].queue_id =
+			lcore_conf[lcore]->rx_queue_list[nb_rx_queue].queue_id =
 				lcore_params[i].queue_id;
-			lcore_conf[lcore].n_rx_queue++;
+			lcore_conf[lcore]->n_rx_queue++;
 		}
 	}
 	return 0;
@@ -1118,6 +1118,26 @@ print_ethaddr(const char *name, const struct rte_ether_addr *eth_addr)
 	printf("%s%s", name, buf);
 }
 
+static int
+init_lcore_conf(void)
+{
+	unsigned int lcore_id;
+	int socketid;
+
+	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
+		if (rte_lcore_is_enabled(lcore_id) == 0)
+			continue;
+
+		socketid = rte_lcore_to_socket_id(lcore_id);
+		lcore_conf[lcore_id] = rte_zmalloc_socket(NULL, sizeof(struct lcore_conf),
+							  RTE_CACHE_LINE_SIZE, socketid);
+		if (lcore_conf[lcore_id] == NULL)
+			return -ENOMEM;
+	}
+
+	return 0;
+}
+
 int
 init_mem(uint16_t portid, unsigned int nb_mbuf)
 {
@@ -1189,7 +1209,7 @@ init_mem(uint16_t portid, unsigned int nb_mbuf)
 		}
 #endif
 
-		qconf = &lcore_conf[lcore_id];
+		qconf = lcore_conf[lcore_id];
 		qconf->ipv4_lookup_struct =
 			l3fwd_lkp.get_ipv4_lookup_struct(socketid);
 		qconf->ipv6_lookup_struct =
@@ -1492,7 +1512,7 @@ l3fwd_poll_resource_setup(void)
 					"rte_eth_tx_queue_setup: err=%d, "
 					"port=%d\n", ret, portid);
 
-			qconf = &lcore_conf[lcore_id];
+			qconf = lcore_conf[lcore_id];
 			qconf->tx_queue_id[portid] = queueid;
 			queueid++;
 
@@ -1505,7 +1525,7 @@ l3fwd_poll_resource_setup(void)
 	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
 		if (rte_lcore_is_enabled(lcore_id) == 0)
 			continue;
-		qconf = &lcore_conf[lcore_id];
+		qconf = lcore_conf[lcore_id];
 		printf("\nInitializing rx queues on lcore %u ... ", lcore_id );
 		fflush(stdout);
 		/* init RX queues */
@@ -1667,6 +1687,10 @@ main(int argc, char **argv)
 	argc -= ret;
 	argv += ret;
 
+	ret = init_lcore_conf();
+	if (ret)
+		rte_exit(EXIT_FAILURE, "Init lcore conf failed!\n");
+
 	force_quit = false;
 	signal(SIGINT, signal_handler);
 	signal(SIGTERM, signal_handler);
@@ -1749,7 +1773,7 @@ main(int argc, char **argv)
 	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
 		if (rte_lcore_is_enabled(lcore_id) == 0)
 			continue;
-		qconf = &lcore_conf[lcore_id];
+		qconf = lcore_conf[lcore_id];
 		for (queue = 0; queue < qconf->n_rx_queue; ++queue) {
 			portid = qconf->rx_queue_list[queue].port_id;
 			queueid = qconf->rx_queue_list[queue].queue_id;
-- 
2.17.1


^ permalink raw reply related

* RE: [PATCH v9 00/21] Wangxun Fixes
From: Zaiyu Wang @ 2026-06-23  3:15 UTC (permalink / raw)
  To: 'Stephen Hemminger'; +Cc: dev
In-Reply-To: <20260622083000.16a572ee@phoenix.local>



> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Monday, June 22, 2026 11:30 PM
> To: Zaiyu Wang <zaiyuwang@trustnetic.com>; Zaiyu Wang <zaiyuwang@trustnetic.com>
> Cc: dev@dpdk.org; dev@dpdk.org
> Subject: Re: [PATCH v9 00/21] Wangxun Fixes
> 
> On Mon, 22 Jun 2026 19:10:48 +0800
> Zaiyu Wang <zaiyuwang@trustnetic.com> wrote:
> 
> > This series fixes several issues found on Wangxun Emerald, Sapphire
> > and Amber-lite NICs, with a focus on link-related problems.
> > ---
> > v9:
> > - Fixed several checkpatch errors
> > ---
> > v8:
> > - Fixed compilation error by replacing RTE_ETH_DEV_TO_PCI with
> > RTE_CLASS_TO_BUS_DEVICE
> > ---
> > v7:
> > - Fixed inverted semantics of is_flat_mem to match SFF8636
> > ---
> > v6:
> > - Fixed more issues identified by AI review
> > ---
> > v5:
> > - Fixed issues identified by AI review
> > ---
> > v4:
> > - Fixed issues identified by devtools scripts
> > ---
> > v3:
> > - Addressed Stephen's comments
> > ---
> > v2:
> > - Fixed compilation error and code style issues
> > ---
> >
> > Zaiyu Wang (21):
> >   net/txgbe: remove duplicate xstats counters
> >   net/ngbe: remove duplicate xstats counters
> >   net/ngbe: add missing CDR config for YT PHY
> >   net/ngbe: fix VF promiscuous and allmulticast
> >   net/txgbe: fix inaccuracy in Tx rate limiting
> >   net/txgbe: fix link status check condition
> >   net/txgbe: fix Tx desc free logic
> >   net/txgbe: fix link flow control registers for Amber-Lite
> >   net/txgbe: fix link flow control config for Sapphire
> >   net/txgbe: fix a mass of unknown interrupts
> >   net/txgbe: fix traffic class priority configuration
> >   net/txgbe: fix link stability for 25G NIC
> >   net/txgbe: fix link stability for 40G NIC
> >   net/txgbe: fix link stability for Amber-Lite backplane mode
> >   net/txgbe: fix FEC mode configuration on 25G NIC
> >   net/txgbe: fix SFP module identification
> >   net/txgbe: fix get module info operation
> >   net/txgbe: fix get EEPROM operation
> >   net/txgbe: fix to reset Tx write-back pointer
> >   net/txgbe: fix to enable Tx desc check
> >   net/txgbe: fix temperature track for AML NIC
> >
> >  drivers/net/ngbe/base/ngbe_phy_yt.c       |    3 +
> >  drivers/net/ngbe/ngbe_ethdev.c            |    5 -
> >  drivers/net/ngbe/ngbe_ethdev_vf.c         |   11 +-
> >  drivers/net/txgbe/base/meson.build        |    2 +
> >  drivers/net/txgbe/base/txgbe.h            |    2 +
> >  drivers/net/txgbe/base/txgbe_aml.c        |  185 +-
> >  drivers/net/txgbe/base/txgbe_aml.h        |    6 +-
> >  drivers/net/txgbe/base/txgbe_aml40.c      |  114 +-
> >  drivers/net/txgbe/base/txgbe_aml40.h      |    6 +-
> >  drivers/net/txgbe/base/txgbe_dcb_hw.c     |    2 +-
> >  drivers/net/txgbe/base/txgbe_e56.c        | 3773 +++++++++++++++++++++
> >  drivers/net/txgbe/base/txgbe_e56.h        | 1753 ++++++++++
> >  drivers/net/txgbe/base/txgbe_e56_bp.c     | 2597 ++++++++++++++
> >  drivers/net/txgbe/base/txgbe_e56_bp.h     |  282 ++
> >  drivers/net/txgbe/base/txgbe_hw.c         |   54 +-
> >  drivers/net/txgbe/base/txgbe_hw.h         |    4 +-
> >  drivers/net/txgbe/base/txgbe_osdep.h      |    4 +
> >  drivers/net/txgbe/base/txgbe_phy.c        |  362 +-
> >  drivers/net/txgbe/base/txgbe_phy.h        |   46 +-
> >  drivers/net/txgbe/base/txgbe_regs.h       |   13 +-
> >  drivers/net/txgbe/base/txgbe_type.h       |   43 +-
> >  drivers/net/txgbe/txgbe_ethdev.c          |  472 ++-
> >  drivers/net/txgbe/txgbe_ethdev.h          |    7 +-
> >  drivers/net/txgbe/txgbe_rxtx.c            |  109 +-
> >  drivers/net/txgbe/txgbe_rxtx.h            |   36 +
> >  drivers/net/txgbe/txgbe_rxtx_vec_common.h |   17 +-
> >  26 files changed, 9464 insertions(+), 444 deletions(-)  create mode
> > 100644 drivers/net/txgbe/base/txgbe_e56.c
> >  create mode 100644 drivers/net/txgbe/base/txgbe_e56.h
> >  create mode 100644 drivers/net/txgbe/base/txgbe_e56_bp.c
> >  create mode 100644 drivers/net/txgbe/base/txgbe_e56_bp.h
> >
> 
> Applied to next-net, but this driver still has some unprefixed symbols:
> 
>  $ nm ./drivers/librte_net_txgbe.a  | grep ' [TD] ' | grep -v ' txgbe'
> 0000000000000510 T set_fields_e56
> 0000000000007ca0 T handle_e56_bkp_an73_flow
> 
Thanks.


^ permalink raw reply

* RE: [PATCH v8 12/21] net/txgbe: fix link stability for 25G NIC
From: Zaiyu Wang @ 2026-06-23  3:15 UTC (permalink / raw)
  To: 'Stephen Hemminger'; +Cc: dev
In-Reply-To: <20260622075323.276cb2de@phoenix.local>



> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Monday, June 22, 2026 10:53 PM
> To: Zaiyu Wang <zaiyuwang@trustnetic.com>; Zaiyu Wang <zaiyuwang@trustnetic.com>
> Cc: dev@dpdk.org; dev@dpdk.org
> Subject: Re: [PATCH v8 12/21] net/txgbe: fix link stability for 25G NIC
> 
> On Mon, 22 Jun 2026 19:09:32 +0800
> Zaiyu Wang <zaiyuwang@trustnetic.com> wrote:
> 
> > > > +void
> > > > +set_fields_e56(unsigned int *src_data, unsigned int bit_high,
> > > > +	       unsigned int bit_low, unsigned int set_value) {
> > >
> > > Function could be static here?
> >
> > Hi Stephen,
> > Thanks for your time. This function is used in both txgbe_e56.c (for
> > general PHY
> > configuration) and txgbe_e56_bp.c (for backplane mode configuration).
> > Therefore, making it static would not be feasible?
> > I have also fixed the other issues you pointed out, including the
> > spelling corrections, replacing tabs with spaces in log messages, and removing the
term "master"
> from comments.
> >
> > Best regards,
> > Zaiyu
> 
> 
> Why I noticed was that it is a global function not following naming conventions.
> Either make it inline in a header or rename.
> 
Thank you for the clarification.
I agree that renaming it would be a better approach.


^ permalink raw reply

* Re: [PATCH v3] dts: clean cryptodev environment after a test run
From: Patrick Robb @ 2026-06-23  0:39 UTC (permalink / raw)
  To: Andrew Bailey; +Cc: luca.vizzarro, lylavoie, ahassick, knimoji, dev
In-Reply-To: <CABJ3N2XixQhhXEnfWJYU_rOou4zXUiYd2SuAV5WYkAgCDOFn6Q@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 29 bytes --]

Applied to next-dts, thanks.

[-- Attachment #2: Type: text/html, Size: 50 bytes --]

^ permalink raw reply

* [PATCH] test/pmd_af_packet: cleanups
From: Stephen Hemminger @ 2026-06-22 23:21 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Fix two coverity bugs where fcntl() return value not checked.
Also mark some other cases as FAILED instead of skipped.
Such as failure to transmit or failure to allocate mbuf's.

Coverity ID: 503765
Coverity ID: 503766

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 app/test/test_pmd_af_packet.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/app/test/test_pmd_af_packet.c b/app/test/test_pmd_af_packet.c
index b668ca5b81..9fe595d606 100644
--- a/app/test/test_pmd_af_packet.c
+++ b/app/test/test_pmd_af_packet.c
@@ -556,19 +556,22 @@ test_af_packet_loopback(void)
 
 	/* Set TAP fd to non-blocking for reading */
 	int flags = fcntl(tap_fd, F_GETFL, 0);
-	fcntl(tap_fd, F_SETFL, flags | O_NONBLOCK);
+	if (flags < 0 || fcntl(tap_fd, F_SETFL, flags | O_NONBLOCK) < 0) {
+		printf("fcntl failed: %s\n", strerror(errno));
+		return TEST_FAILED;
+	}
 
 	/* Allocate and send packets */
 	allocated = alloc_tx_mbufs(tx_bufs, BURST_SIZE);
 	if (allocated == 0) {
-		printf("SKIPPED: Could not allocate mbufs\n");
-		return TEST_SKIPPED;
+		printf("Could not allocate mbufs\n");
+		return TEST_FAILED;
 	}
 
 	nb_tx = do_tx_burst(port_id, 0, tx_bufs, allocated);
 	if (nb_tx == 0) {
-		printf("SKIPPED: No packets transmitted\n");
-		return TEST_SKIPPED;
+		printf("No packets transmitted\n");
+		return TEST_FAILED;
 	}
 
 	/*
-- 
2.53.0


^ permalink raw reply related

* RE: [EXTERNAL] [PATCH v5 14/24] bus/vmbus: convert from rte_atomic to stdatomic
From: Long Li @ 2026-06-22 20:57 UTC (permalink / raw)
  To: Stephen Hemminger, dev@dpdk.org; +Cc: Wei Hu
In-Reply-To: <20260620023134.42877-15-stephen@networkplumber.org>

> Replace deprecated rte_atomic32 operations in the vmbus ring buffer
> producer with stdatomic equivalents, and replace the smp_wmb + CAS-spin
> publish with rte_wait_until_equal_32 + release-store.
> 
> The two-cursor design is preserved: tbr->windex is the driver-private
> reservation cursor that lets producers reserve slots concurrently without a
> lock; vbr->windex is the host-visible commit cursor, updated in reservation
> order so the host never observes windex pointing past unwritten data. This is
> the lockless analogue of the spinlock-around- single-cursor pattern used by
> the Linux (drivers/hv/ring_buffer.c
> hv_ringbuffer_write) and FreeBSD (sys/dev/hyperv/vmbus/vmbus_br.c
> vmbus_txbr_write) implementations of the same host contract.
> 
> The memory ordering mirrors __rte_ring_headtail_move_head and
> __rte_ring_update_tail in lib/ring/rte_ring_c11_pvt.h: relaxed wait for the
> previous producer's commit, release-store to publish. The rte_smp_wmb
> before the publish is folded into the release ordering on the store itself.
> 
> The host-shared vbr->windex remains volatile uint32_t in the packed bufring
> struct; the atomic qualifier is added via cast at the access site. The (uintptr_t)
> launder on the store-side cast suppresses a spurious misaligned-atomic
> warning from the packed-struct attribute (windex is 4-byte aligned in practice,
> at offset 0 of a page-aligned struct).
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>

Reviewed-by: Long Li <longli@microsoft.com>

> ---
>  drivers/bus/vmbus/private.h       |  2 +-
>  drivers/bus/vmbus/vmbus_bufring.c | 39 +++++++++++++++++--------------
>  2 files changed, 23 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/bus/vmbus/private.h b/drivers/bus/vmbus/private.h index
> 6efac86b77..6b7782724f 100644
> --- a/drivers/bus/vmbus/private.h
> +++ b/drivers/bus/vmbus/private.h
> @@ -25,7 +25,7 @@ extern int vmbus_logtype_bus;  struct vmbus_br {
>  	struct vmbus_bufring *vbr;
>  	uint32_t	dsize;
> -	uint32_t	windex; /* next available location */
> +	RTE_ATOMIC(uint32_t) windex; /* next available location */
>  };
> 
>  #define UIO_NAME_MAX 64
> diff --git a/drivers/bus/vmbus/vmbus_bufring.c
> b/drivers/bus/vmbus/vmbus_bufring.c
> index fcb97287dc..624fe8b6c5 100644
> --- a/drivers/bus/vmbus/vmbus_bufring.c
> +++ b/drivers/bus/vmbus/vmbus_bufring.c
> @@ -15,7 +15,7 @@
>  #include <rte_tailq.h>
>  #include <rte_log.h>
>  #include <rte_malloc.h>
> -#include <rte_atomic.h>
> +#include <rte_stdatomic.h>
>  #include <rte_memory.h>
>  #include <rte_pause.h>
>  #include <rte_bus_vmbus.h>
> @@ -114,6 +114,7 @@ vmbus_txbr_write(struct vmbus_br *tbr, const struct
> iovec iov[], int iovlen,
>  	uint32_t ring_size = tbr->dsize;
>  	uint32_t old_windex, next_windex, windex, total;
>  	uint64_t save_windex;
> +	bool success;
>  	int i;
> 
>  	total = 0;
> @@ -121,17 +122,13 @@ vmbus_txbr_write(struct vmbus_br *tbr, const
> struct iovec iov[], int iovlen,
>  		total += iov[i].iov_len;
>  	total += sizeof(save_windex);
> 
> +	/* Get current free location */
> +	old_windex = rte_atomic_load_explicit(&tbr->windex,
> +					      rte_memory_order_relaxed);
> +
>  	/* Reserve space in ring */
>  	do {
> -		uint32_t avail;
> -
> -		/* Get current free location */
> -		old_windex = tbr->windex;
> -
> -		/* Prevent compiler reordering this with calculation */
> -		rte_compiler_barrier();
> -
> -		avail = vmbus_br_availwrite(tbr, old_windex);
> +		uint32_t avail = vmbus_br_availwrite(tbr, old_windex);
> 
>  		/* If not enough space in ring, then tell caller. */
>  		if (avail <= total)
> @@ -139,8 +136,13 @@ vmbus_txbr_write(struct vmbus_br *tbr, const
> struct iovec iov[], int iovlen,
> 
>  		next_windex = vmbus_br_idxinc(old_windex, total, ring_size);
> 
> -		/* Atomic update of next write_index for other threads */
> -	} while (!rte_atomic32_cmpset(&tbr->windex, old_windex,
> next_windex));
> +		/* Atomic update of next write_index for other threads
> +		 * Can use weak since easy to recompute and retry.
> +		 */
> +		success = rte_atomic_compare_exchange_weak_explicit(
> +				&tbr->windex, &old_windex, next_windex,
> +				rte_memory_order_acquire,
> rte_memory_order_relaxed);
> +	} while (unlikely(!success));
> 
>  	/* Space from old..new is now reserved */
>  	windex = old_windex;
> @@ -157,12 +159,15 @@ vmbus_txbr_write(struct vmbus_br *tbr, const
> struct iovec iov[], int iovlen,
>  	/* The region reserved should match region used */
>  	RTE_ASSERT(windex == next_windex);
> 
> -	/* Ensure that data is available before updating host index */
> -	rte_smp_wmb();
> +	/* Wait for previous producer to publish their windex update */
> +	rte_wait_until_equal_32(&vbr->windex, old_windex,
> +rte_memory_order_relaxed);
> 
> -	/* Checkin for our reservation. wait for our turn to update host */
> -	while (!rte_atomic32_cmpset(&vbr->windex, old_windex,
> next_windex))
> -		rte_pause();
> +	/* Publish our windex update; prior data writes ordered via release.
> +	 * windex is 4-byte aligned in practice (struct is page-aligned, windex
> +	 * at offset 0); cast launders the packed-struct alignment-1 attribute.
> +	 */
> +	rte_atomic_store_explicit((volatile __rte_atomic uint32_t
> *)(uintptr_t)&vbr->windex,
> +				  next_windex, rte_memory_order_release);
> 
>  	/* If host had read all data before this, then need to signal */
>  	*need_sig |= vmbus_txbr_need_signal(vbr, old_windex);
> --
> 2.53.0


^ permalink raw reply

* RE: [EXTERNAL] [PATCH v5 12/24] net/netvsc: replace rte_atomic32 with stdatomic
From: Long Li @ 2026-06-22 20:43 UTC (permalink / raw)
  To: Stephen Hemminger, dev@dpdk.org; +Cc: Wei Hu
In-Reply-To: <20260620023134.42877-13-stephen@networkplumber.org>

> 
> Change the rndis transaction id and buffer usage to use stdatomic functions.
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>

Reviewed-by: Long Li <longli@microsoft.com>


> ---
>  drivers/net/netvsc/hn_rndis.c | 28 +++++++++++++++++++---------
> drivers/net/netvsc/hn_rxtx.c  | 12 +++++++-----
>  drivers/net/netvsc/hn_var.h   |  6 +++---
>  3 files changed, 29 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/net/netvsc/hn_rndis.c b/drivers/net/netvsc/hn_rndis.c
> index 7c54eebcef..4b1d3d5539 100644
> --- a/drivers/net/netvsc/hn_rndis.c
> +++ b/drivers/net/netvsc/hn_rndis.c
> @@ -17,7 +17,7 @@
>  #include <rte_string_fns.h>
>  #include <rte_memzone.h>
>  #include <rte_malloc.h>
> -#include <rte_atomic.h>
> +#include <rte_stdatomic.h>
>  #include <rte_alarm.h>
>  #include <rte_branch_prediction.h>
>  #include <rte_ether.h>
> @@ -59,7 +59,8 @@ hn_rndis_rid(struct hn_data *hv)
>  	uint32_t rid;
> 
>  	do {
> -		rid = rte_atomic32_add_return(&hv->rndis_req_id, 1);
> +		rid = rte_atomic_fetch_add_explicit(&hv->rndis_req_id, 1,
> +
> rte_memory_order_seq_cst);
>  	} while (rid == 0);
> 
>  	return rid;
> @@ -357,12 +358,14 @@ void hn_rndis_receive_response(struct hn_data
> *hv,
>  	memcpy(hv->rndis_resp, data, len);
> 
>  	/* make sure response copied before update */
> -	rte_smp_wmb();
> -
> -	if (rte_atomic32_cmpset(&hv->rndis_pending, hdr->rid, 0) == 0) {
> +	uint32_t expected = hdr->rid;
> +	if (!rte_atomic_compare_exchange_strong_explicit(&hv-
> >rndis_pending,
> +							 &expected, 0,
> +
> rte_memory_order_release,
> +
> rte_memory_order_relaxed)) {
>  		PMD_DRV_LOG(NOTICE,
>  			    "received id %#x pending id %#x",
> -			    hdr->rid, (uint32_t)hv->rndis_pending);
> +			    hdr->rid, expected);
>  	}
>  }
> 
> @@ -388,8 +391,11 @@ static int hn_rndis_exec1(struct hn_data *hv,
>  		return -EINVAL;
>  	}
> 
> +	uint32_t expected = 0;
>  	if (comp != NULL &&
> -	    rte_atomic32_cmpset(&hv->rndis_pending, 0, rid) == 0) {
> +	    !rte_atomic_compare_exchange_strong_explicit(
> +		    &hv->rndis_pending, &expected, rid,
> +		    rte_memory_order_acquire, rte_memory_order_relaxed)) {
>  		PMD_DRV_LOG(ERR,
>  			    "Request already pending");
>  		return -EBUSY;
> @@ -405,7 +411,8 @@ static int hn_rndis_exec1(struct hn_data *hv,
>  		time_t start = time(NULL);
> 
>  		/* Poll primary channel until response received */
> -		while (hv->rndis_pending == rid) {
> +		while (rte_atomic_load_explicit(&hv->rndis_pending,
> +						rte_memory_order_acquire)
> == rid) {
>  			if (hv->closed)
>  				return -ENETDOWN;
> 
> @@ -413,7 +420,10 @@ static int hn_rndis_exec1(struct hn_data *hv,
>  				PMD_DRV_LOG(ERR,
>  					    "RNDIS response timed out");
> 
> -				rte_atomic32_cmpset(&hv->rndis_pending,
> rid, 0);
> +				expected = rid;
> +
> 	rte_atomic_compare_exchange_strong_explicit(
> +					&hv->rndis_pending, &expected, 0,
> +					rte_memory_order_release,
> rte_memory_order_relaxed);
>  				return -ETIMEDOUT;
>  			}
> 
> diff --git a/drivers/net/netvsc/hn_rxtx.c b/drivers/net/netvsc/hn_rxtx.c index
> 0d770d1b25..6f536610f2 100644
> --- a/drivers/net/netvsc/hn_rxtx.c
> +++ b/drivers/net/netvsc/hn_rxtx.c
> @@ -17,7 +17,7 @@
>  #include <rte_string_fns.h>
>  #include <rte_memzone.h>
>  #include <rte_malloc.h>
> -#include <rte_atomic.h>
> +#include <rte_stdatomic.h>
>  #include <rte_bitmap.h>
>  #include <rte_branch_prediction.h>
>  #include <rte_ether.h>
> @@ -558,7 +558,8 @@ static void hn_rx_buf_free_cb(void *buf
> __rte_unused, void *opaque)
>  	struct hn_rx_queue *rxq = rxb->rxq;
>  	struct hn_data *hv = rxq->hv;
> 
> -	rte_atomic32_dec(&rxq->rxbuf_outstanding);
> +	rte_atomic_fetch_sub_explicit(&rxq->rxbuf_outstanding, 1,
> +				      rte_memory_order_release);
>  	hn_nvs_ack_rxbuf(hv, rxb->chan, rxb->xactid);  }
> 
> @@ -602,8 +603,8 @@ static void hn_rxpkt(struct hn_rx_queue *rxq, struct
> hn_rx_bufinfo *rxb,
>  	 * some space available in receive area for later packets.
>  	 */
>  	if (hv->rx_extmbuf_enable && dlen > hv->rx_copybreak &&
> -	    (uint32_t)rte_atomic32_read(&rxq->rxbuf_outstanding) <
> -			hv->rxbuf_section_cnt / 2) {
> +	    rte_atomic_load_explicit(&rxq->rxbuf_outstanding,
> +				     rte_memory_order_relaxed) < hv-
> >rxbuf_section_cnt / 2) {
>  		struct rte_mbuf_ext_shared_info *shinfo;
>  		const void *rxbuf;
>  		rte_iova_t iova;
> @@ -619,7 +620,8 @@ static void hn_rxpkt(struct hn_rx_queue *rxq, struct
> hn_rx_bufinfo *rxb,
> 
>  		/* shinfo is already set to 1 by the caller */
>  		if (rte_mbuf_ext_refcnt_update(shinfo, 1) == 2)
> -			rte_atomic32_inc(&rxq->rxbuf_outstanding);
> +			rte_atomic_fetch_add_explicit(&rxq-
> >rxbuf_outstanding, 1,
> +
> rte_memory_order_acquire);
> 
>  		rte_pktmbuf_attach_extbuf(m, data, iova,
>  					  dlen + headroom, shinfo);
> diff --git a/drivers/net/netvsc/hn_var.h b/drivers/net/netvsc/hn_var.h index
> 574b909c82..d7124a7df9 100644
> --- a/drivers/net/netvsc/hn_var.h
> +++ b/drivers/net/netvsc/hn_var.h
> @@ -85,7 +85,7 @@ struct hn_rx_queue {
> 
>  	void *event_buf;
>  	struct hn_rx_bufinfo *rxbuf_info;
> -	rte_atomic32_t  rxbuf_outstanding;
> +	RTE_ATOMIC(uint32_t) rxbuf_outstanding;
>  };
> 
> 
> @@ -167,8 +167,8 @@ struct hn_data {
>  	uint32_t	rndis_agg_pkts;
>  	uint32_t	rndis_agg_align;
> 
> -	volatile uint32_t  rndis_pending;
> -	rte_atomic32_t	rndis_req_id;
> +	RTE_ATOMIC(uint32_t) rndis_pending;
> +	RTE_ATOMIC(uint32_t) rndis_req_id;
>  	uint8_t		rndis_resp[256];
> 
>  	uint32_t	rss_hash;
> --
> 2.53.0


^ permalink raw reply

* [PATCH v3 2/2] dts: add build arguments to test run configuration
From: Koushik Bhargav Nimoji @ 2026-06-22 17:02 UTC (permalink / raw)
  To: luca.vizzarro, patrickrobb1997
  Cc: dev, abailey, ahassick, lylavoie, Koushik Bhargav Nimoji
In-Reply-To: <20260622170223.1152746-1-knimoji@iol.unh.edu>

This patch adds the ability to specify build arguments when building DPDK
through DTS. Doing so allows users to build DPDK with the desired build
arguments, which allows for a more configurable DTS run.

Signed-off-by: Koushik Bhargav Nimoji <knimoji@iol.unh.edu>
---
 dts/configurations/test_run.example.yaml | 13 +++++++++++++
 dts/framework/config/test_run.py         |  2 ++
 dts/framework/remote_session/dpdk.py     | 12 ++++++++----
 dts/framework/utils.py                   | 21 ++++++++++++++++++++-
 4 files changed, 43 insertions(+), 5 deletions(-)

diff --git a/dts/configurations/test_run.example.yaml b/dts/configurations/test_run.example.yaml
index ee641f5dce..0bd5151801 100644
--- a/dts/configurations/test_run.example.yaml
+++ b/dts/configurations/test_run.example.yaml
@@ -16,6 +16,8 @@
 #       `precompiled_build_dir` or `build_options` can be defined, but not both.
 #   `compiler_wrapper`:
 #       Optional, adds a compiler wrapper if present.
+#   `build_args`:
+#       The additional build arguments to be used when building DPDK.
 #   `func_traffic_generator` & `perf_traffic_generator`:
 #       Define `func_traffic_generator` when `func` set to true.
 #       Define `perf_traffic_generator` when `perf` set to true.
@@ -40,6 +42,17 @@ dpdk:
       # the combination of the following two makes CC="ccache gcc"
       compiler: gcc
       compiler_wrapper: ccache # see `Optional Fields`
+      # arguments to be used when building DPDK
+      # build_args:
+      #   c_args:
+      #     - O3
+      #     - g
+      #   b_coverage:
+      #     - "true"
+      #   buildtype:
+      #     - release
+      #   flags:
+      #     - strip
 func_traffic_generator:
   type: SCAPY
 # perf_traffic_generator:
diff --git a/dts/framework/config/test_run.py b/dts/framework/config/test_run.py
index 76e24d1785..eab12041fc 100644
--- a/dts/framework/config/test_run.py
+++ b/dts/framework/config/test_run.py
@@ -191,6 +191,8 @@ class DPDKBuildOptionsConfiguration(FrozenModel):
     #: This string will be put in front of the compiler when executing the build. Useful for adding
     #: wrapper commands, such as ``ccache``.
     compiler_wrapper: str = ""
+    #: The build arguments to build dpdk with
+    build_args: dict[str, list[str]] = {}
 
 
 class DPDKUncompiledBuildConfiguration(BaseDPDKBuildConfiguration):
diff --git a/dts/framework/remote_session/dpdk.py b/dts/framework/remote_session/dpdk.py
index 865f97f6ca..4dc0ceeaaf 100644
--- a/dts/framework/remote_session/dpdk.py
+++ b/dts/framework/remote_session/dpdk.py
@@ -100,8 +100,8 @@ def setup(self) -> None:
         match self.config:
             case DPDKPrecompiledBuildConfiguration(precompiled_build_dir=build_dir):
                 self._set_remote_dpdk_build_dir(build_dir)
-            case DPDKUncompiledBuildConfiguration(build_options=build_options):
-                self._configure_dpdk_build(build_options)
+            case DPDKUncompiledBuildConfiguration():
+                self._configure_dpdk_build(self.config.build_options)
                 self._build_dpdk()
 
     def teardown(self) -> None:
@@ -277,16 +277,20 @@ def _build_dpdk(self) -> None:
         `remote_dpdk_tree_path` has already been set on the SUT node.
         """
         ctx = get_ctx()
+        build_options = getattr(self.config, "build_options")
         # If the SUT is an ice driver device, make sure to build with 16B descriptors.
         if (
             ctx.topology.sut_port_ingress
             and ctx.topology.sut_port_ingress.config.os_driver == "ice"
         ):
             meson_args = MesonArgs(
-                default_library="static", libdir="lib", c_args="-DRTE_NET_INTEL_USE_16BYTE_DESC"
+                build_options.build_args,
+                default_library="static",
+                libdir="lib",
+                c_args="-DRTE_NET_INTEL_USE_16BYTE_DESC",
             )
         else:
-            meson_args = MesonArgs(default_library="static", libdir="lib")
+            meson_args = MesonArgs(build_options.build_args, default_library="static", libdir="lib")
 
         if SETTINGS.code_coverage:
             meson_args._add_arg("-Db_coverage=true")
diff --git a/dts/framework/utils.py b/dts/framework/utils.py
index 38da88cd9c..e0ed35066c 100644
--- a/dts/framework/utils.py
+++ b/dts/framework/utils.py
@@ -99,10 +99,16 @@ class MesonArgs:
 
     _default_library: str
 
-    def __init__(self, default_library: str | None = None, **dpdk_args: str | bool):
+    def __init__(
+        self,
+        dpdk_build_args: dict[str, list[str]],
+        default_library: str | None = None,
+        **dpdk_args: str | bool,
+    ):
         """Initialize the meson arguments.
 
         Args:
+            dpdk_build_args: The DPDK build arguments specified in the test run configuration file.
             default_library: The default library type, Meson supports ``shared``, ``static`` and
                 ``both``. Defaults to :data:`None`, in which case the argument won't be used.
             dpdk_args: The arguments found in ``meson_options.txt`` in root DPDK directory.
@@ -121,6 +127,19 @@ def __init__(self, default_library: str | None = None, **dpdk_args: str | bool):
             )
         )
 
+        arguments = []
+        for option, value in dpdk_build_args.items():
+            if option == "c_args":
+                values = " ".join(f"-{val}" for val in value)
+                arguments.append(f'-D{option}="{values}"')
+            elif option == "flags":
+                values = " ".join(f"--{val}" for val in value)
+                arguments.append(values)
+            else:
+                arguments.append(f" -D{option}={value[0]}")
+
+        self._dpdk_args = " ".join(arguments)
+
     def __str__(self) -> str:
         """The actual args."""
         return " ".join(f"{self._default_library} {self._dpdk_args}".split())
-- 
2.54.0


^ permalink raw reply related

* [PATCH v3 1/2] dts: add code coverage reporting to DTS
From: Koushik Bhargav Nimoji @ 2026-06-22 17:02 UTC (permalink / raw)
  To: luca.vizzarro, patrickrobb1997
  Cc: dev, abailey, ahassick, lylavoie, Koushik Bhargav Nimoji
In-Reply-To: <20260522154637.952588-1-knimoji@iol.unh.edu>

Previously, DTS had no code coverage. This patch adds a command line
argument in order to build DPDK with code coverage enabled. This allows
users to create and view code coverage reports of what code and functions
were called during a DTS run.

Signed-off-by: Koushik Bhargav Nimoji <knimoji@iol.unh.edu>
---
v2:
    *Fixed error in lcov/gcov tool detection
v3:
    *Fixed type hints and error message typos    
---
 .mailmap                                      |  1 +
 doc/guides/tools/dts.rst                      | 15 +++++++++++++
 dts/README.md                                 |  5 +++++
 dts/framework/remote_session/dpdk.py          | 19 ++++++++++++++++
 .../remote_session/remote_session.py          |  5 ++++-
 dts/framework/settings.py                     | 10 +++++++++
 dts/framework/testbed_model/os_session.py     | 10 +++++++++
 dts/framework/testbed_model/posix_session.py  | 22 +++++++++++++++++++
 dts/framework/utils.py                        |  8 +++++++
 9 files changed, 94 insertions(+), 1 deletion(-)

diff --git a/.mailmap b/.mailmap
index e052b85213..a1209150ad 100644
--- a/.mailmap
+++ b/.mailmap
@@ -877,6 +877,7 @@ Klaus Degner <kd@allegro-packets.com>
 Kommula Shiva Shankar <kshankar@marvell.com>
 Konstantin Ananyev <konstantin.ananyev@huawei.com> <konstantin.v.ananyev@yandex.ru>
 Konstantin Ananyev <konstantin.ananyev@huawei.com> <konstantin.ananyev@intel.com>
+Koushik Bhargav Nimoji <knimoji@iol.unh.edu>
 Krishna Murthy <krishna.j.murthy@intel.com>
 Krzysztof Galazka <krzysztof.galazka@intel.com>
 Krzysztof Kanas <kkanas@marvell.com> <krzysztof.kanas@caviumnetworks.com>
diff --git a/doc/guides/tools/dts.rst b/doc/guides/tools/dts.rst
index 5b9a348016..a838a317ee 100644
--- a/doc/guides/tools/dts.rst
+++ b/doc/guides/tools/dts.rst
@@ -352,6 +352,10 @@ DTS is run with ``main.py`` located in the ``dts`` directory using the ``poetry
      --precompiled-build-dir DIR_NAME
                            [DTS_PRECOMPILED_BUILD_DIR] Define the subdirectory under the DPDK tree root directory or tarball where the pre-
                            compiled binaries are located. (default: None)
+     --code-coverage       Builds DPDK on the SUT node with code coverage enabled. Generates a code coverage report which can be found on
+                           the local filesystem at dts/output/coverage_reports/meson-logs/coveragereport/index.html, or the specified output
+                           directory. To use code coverage, please ensure lcov v1.15 and gcov v8.0 or higher (included in gcc package) are
+                           installed on the SUT node.
 
 
 The brackets contain the names of environment variables that set the same thing.
@@ -367,6 +371,17 @@ Results are stored in the output dir by default
 which be changed with the ``--output-dir`` command line argument.
 The results contain basic statistics of passed/failed test cases and DPDK version.
 
+Code Coverage
+~~~~~~~~~~~~~
+
+DTS has the ablilty to track code usage during test runs, and generate an HTML
+coverage report with that data. This can be done by using the "--code-coverage"
+CLI parameter when running DTS.
+
+To use code coverage, please make sure the following dependencies are available
+on the SUT node:
+- lcov v1.15
+- gcov v8.0 or greater (included in gcc package)
 
 Contributing to DTS
 -------------------
diff --git a/dts/README.md b/dts/README.md
index d257b7a167..51f824e077 100644
--- a/dts/README.md
+++ b/dts/README.md
@@ -64,6 +64,11 @@ $ poetry run ./main.py
 These commands will give you a bash shell inside a docker container
 with all DTS Python dependencies installed.
 
+# Code Coverage
+
+To generate code coverage reports, ensure the SUT has lcov v1.15 and gcov v8.0 or greater
+installed, and that DTS is run using the '--code-coverage' argument.
+
 ## Visual Studio Code
 
 Usage of VScode devcontainers is NOT required for developing on DTS and running DTS,
diff --git a/dts/framework/remote_session/dpdk.py b/dts/framework/remote_session/dpdk.py
index c3575cfcaf..865f97f6ca 100644
--- a/dts/framework/remote_session/dpdk.py
+++ b/dts/framework/remote_session/dpdk.py
@@ -29,6 +29,7 @@
 from framework.logger import DTSLogger, get_dts_logger
 from framework.params.eal import EalParams
 from framework.remote_session.remote_session import CommandResult
+from framework.settings import SETTINGS
 from framework.testbed_model.cpu import LogicalCore, LogicalCoreCount, LogicalCoreList, lcore_filter
 from framework.testbed_model.node import Node
 from framework.testbed_model.os_session import OSSession
@@ -107,7 +108,22 @@ def teardown(self) -> None:
         """Teardown the DPDK build on the target node.
 
         Removes the DPDK tree and/or build directory/tarball depending on the configuration.
+        If code coverage is enabled, the coverage report and .info file are generated and
+        copied onto the local filesystem before teardown.
         """
+        if SETTINGS.code_coverage:
+            report_folder = PurePath(self.remote_dpdk_build_dir / "meson-logs")
+            output_dir = SETTINGS.output_dir
+            Path(output_dir).mkdir(parents=True, exist_ok=True)
+
+            coverage_status = self._session.generate_coverage_report(self.remote_dpdk_build_dir)
+            if coverage_status:
+                self._session.copy_dir_from(report_folder, output_dir)
+                self._logger.info(
+                    "Coverage HTML report generated, "
+                    f"available at {output_dir}/meson-logs/coveragereports/index.html"
+                )
+
         match self.config.dpdk_location:
             case LocalDPDKTreeLocation():
                 self._node.main_session.remove_remote_dir(self.remote_dpdk_tree_path)
@@ -272,6 +288,9 @@ def _build_dpdk(self) -> None:
         else:
             meson_args = MesonArgs(default_library="static", libdir="lib")
 
+        if SETTINGS.code_coverage:
+            meson_args._add_arg("-Db_coverage=true")
+
         self._session.build_dpdk(
             self._env_vars,
             meson_args,
diff --git a/dts/framework/remote_session/remote_session.py b/dts/framework/remote_session/remote_session.py
index 158325bb7f..d2440dc2d8 100644
--- a/dts/framework/remote_session/remote_session.py
+++ b/dts/framework/remote_session/remote_session.py
@@ -252,7 +252,10 @@ def copy_from(self, source_file: str | PurePath, destination_dir: str | Path) ->
             destination_dir: The directory path on the local filesystem where the `source_file`
                 will be saved.
         """
-        self.session.get(str(source_file), str(destination_dir))
+        source_file = PurePath(source_file)
+        destination_dir = Path(destination_dir)
+        local_path = destination_dir / source_file.name
+        self.session.get(str(source_file), str(local_path))
 
     def copy_to(self, source_file: str | Path, destination_dir: str | PurePath) -> None:
         """Copy a file from local filesystem to the remote Node.
diff --git a/dts/framework/settings.py b/dts/framework/settings.py
index b08373b7ea..7df535bd84 100644
--- a/dts/framework/settings.py
+++ b/dts/framework/settings.py
@@ -159,6 +159,8 @@ class Settings:
     re_run: int = 0
     #:
     random_seed: int | None = None
+    #:
+    code_coverage: bool = False
 
 
 SETTINGS: Settings = Settings()
@@ -489,6 +491,14 @@ def _get_parser() -> _DTSArgumentParser:
     )
     _add_env_var_to_action(action)
 
+    action = parser.add_argument(
+        "--code-coverage",
+        action="store_true",
+        default=False,
+        help="Used to build DPDK with code coverage enabled.",
+    )
+    _add_env_var_to_action(action)
+
     return parser
 
 
diff --git a/dts/framework/testbed_model/os_session.py b/dts/framework/testbed_model/os_session.py
index 2c267afed1..742b074948 100644
--- a/dts/framework/testbed_model/os_session.py
+++ b/dts/framework/testbed_model/os_session.py
@@ -480,6 +480,16 @@ def build_dpdk(
             timeout: Wait at most this long in seconds for the build execution to complete.
         """
 
+    @abstractmethod
+    def generate_coverage_report(self, remote_build_dir: PurePath | None) -> bool:
+        """Generates a code coverage report for a DTS run.
+
+        Args:
+            remote_build_dir: The remote DPDK build directory
+        Returns:
+            Whether the coverage report was able to be created or not.
+        """
+
     @abstractmethod
     def get_dpdk_version(self, version_path: str | PurePath) -> str:
         """Inspect the DPDK version on the remote node.
diff --git a/dts/framework/testbed_model/posix_session.py b/dts/framework/testbed_model/posix_session.py
index dec952685a..d18ce27de2 100644
--- a/dts/framework/testbed_model/posix_session.py
+++ b/dts/framework/testbed_model/posix_session.py
@@ -295,6 +295,28 @@ def build_dpdk(
         except RemoteCommandExecutionError as e:
             raise DPDKBuildError(f"DPDK build failed when doing '{e.command}'.")
 
+    def generate_coverage_report(self, remote_build_dir: PurePath | None) -> bool:
+        """Overrides :meth:`~.os_session.OSSession.generate_coverage_report`."""
+        command_result = self.send_command(r"lcov --version | grep -oP '\d+\.\d+'")
+        lcov_version = float(
+            command_result.stdout if command_result.return_code == 0 and command_result else -1
+        )
+        command_result = self.send_command(
+            r"gcov --version | head -n 1 | grep -oP '\d+\.\d+' | tail -n 1"
+        )
+        gcov_version = float(
+            command_result.stdout if command_result.return_code == 0 and command_result else -1
+        )
+
+        if lcov_version >= 1.15 and gcov_version >= 8.0:
+            self.send_command(f"ninja -C {remote_build_dir} coverage-html", timeout=600)
+            return True
+        else:
+            self._logger.info(
+                "Unable to generate code coverage report, ensure lcov v1.15 and at least gcov v8.0"
+            )
+            return False
+
     def get_dpdk_version(self, build_dir: str | PurePath) -> str:
         """Overrides :meth:`~.os_session.OSSession.get_dpdk_version`."""
         out = self.send_command(f"cat {self.join_remote_path(build_dir, 'VERSION')}", verify=True)
diff --git a/dts/framework/utils.py b/dts/framework/utils.py
index 9917ffbfaa..38da88cd9c 100644
--- a/dts/framework/utils.py
+++ b/dts/framework/utils.py
@@ -125,6 +125,14 @@ def __str__(self) -> str:
         """The actual args."""
         return " ".join(f"{self._default_library} {self._dpdk_args}".split())
 
+    def _add_arg(self, arg: str):
+        """Used to add a meson build argument to the DPDK build.
+
+        Args:
+            arg: The meson build argument to be added.
+        """
+        self._dpdk_args = self._dpdk_args + " " + arg
+
 
 class TarCompressionFormat(StrEnum):
     """Compression formats that tar can use.
-- 
2.54.0


^ permalink raw reply related

* RE: [PATCH v3 3/6] bpf/arm64: fix offset type to allow a negative jump
From: Marat Khalili @ 2026-06-22 16:26 UTC (permalink / raw)
  To: Stephen Hemminger, dev@dpdk.org
  Cc: Christophe Fontaine, stable@dpdk.org, Wathsala Vithanage,
	Konstantin Ananyev, Jerin Jacob
In-Reply-To: <20260621162524.82690-4-stephen@networkplumber.org>

> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Sunday 21 June 2026 17:24
> To: dev@dpdk.org
> Cc: Christophe Fontaine <cfontain@redhat.com>; stable@dpdk.org; Stephen Hemminger
> <stephen@networkplumber.org>; Wathsala Vithanage <wathsala.vithanage@arm.com>; Konstantin Ananyev
> <konstantin.ananyev@huawei.com>; Marat Khalili <marat.khalili@huawei.com>; Jerin Jacob
> <jerinj@marvell.com>
> Subject: [PATCH v3 3/6] bpf/arm64: fix offset type to allow a negative jump
> 
> 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

I still wish it was not called program_sz here, but the fix is not wrong, so

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

^ permalink raw reply

* Re: [PATCH v5 00/23] net/sxe2: added Linkdata sxe2 ethernet driver
From: Stephen Hemminger @ 2026-06-22 15:44 UTC (permalink / raw)
  To: liujie5; +Cc: dev
In-Reply-To: <20260622092324.3091185-1-liujie5@linkdatatechnology.com>

On Mon, 22 Jun 2026 17:23:24 +0800
liujie5@linkdatatechnology.com wrote:

> From: Jie Liu <liujie5@linkdatatechnology.com>
> 
> This patch set implements core functionality for the SXE2 PMD,
> including basic driver framework, data path setup, and advanced
> offload features (VLAN, RSS,TM, PTP etc.).
> 
> V5:
> 	Refactored sxe2_ptype_tbl from adapter-indirection pattern (adapter->ptype_tbl[]) 
> 	to extern const direct-access pattern, matching txgbe PMD convention
> 
> 	All vector/SIMD Rx paths (SSE, AVX2, AVX512, NEON) index sxe2_ptype_tbl[] directly without local pointer indirection
> 
> Jie Liu (23):
>   net/sxe2: remove software statistics devargs
>   net/sxe2: add Rx framework and packet types callback
>   net/sxe2: support AVX512 vectorized path for Rx and Tx
>   net/sxe2: add AVX2 vector data path for Rx and Tx
>   net/sxe2: add link update callback
>   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
>   common/sxe2: add callback for memory event handling
>   net/sxe2: add private devargs parsing
>   net/sxe2: update sxe2 feature matrix docs
> 
>  doc/guides/nics/features/sxe2.ini          |   56 +
>  doc/guides/nics/sxe2.rst                   |  164 ++
>  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               |   52 +
>  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             | 1511 ++++++++++++++-
>  drivers/net/sxe2/sxe2_ethdev.h             |  111 +-
>  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                 | 1151 ++++++++++++
>  drivers/net/sxe2/sxe2_tm.h                 |   76 +
>  drivers/net/sxe2/sxe2_tx.c                 |    7 +
>  drivers/net/sxe2/sxe2_txrx.c               | 1958 +++++++++++++++++++-
>  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          |  284 ++-
>  drivers/net/sxe2/sxe2_txrx_vec.c           |   46 +-
>  drivers/net/sxe2/sxe2_txrx_vec.h           |   38 +-
>  drivers/net/sxe2/sxe2_txrx_vec_avx2.c      |  747 ++++++++
>  drivers/net/sxe2/sxe2_txrx_vec_avx512.c    |  867 +++++++++
>  drivers/net/sxe2/sxe2_txrx_vec_common.h    |   54 +-
>  drivers/net/sxe2/sxe2_txrx_vec_neon.c      |  689 +++++++
>  drivers/net/sxe2/sxe2_txrx_vec_sse.c       |   38 +-
>  drivers/net/sxe2/sxe2_vsi.c                |  146 ++
>  drivers/net/sxe2/sxe2_vsi.h                |   12 +-
>  drivers/net/sxe2/sxe2vf_regs.h             |   85 +
>  67 files changed, 24798 insertions(+), 273 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
> 

Much better, still some AI review feedback items.
I agree with AI on this; duplicate rules should be handled similar to other
drivers.

[PATCH v5 00/23] sxe2 driver feature additions

v5 cleanly addresses the v4 follow-ups except flow-duplicate-pattern.

Verified across the assembled tree:

- All 23 commits build end-to-end. Bisect works. The structural
  reorganization (Rx framework now precedes the vector paths instead of
  the other way around) was non-trivial and could easily have
  reintroduced the build-band problem; it didn't.

- The v4 "subject does not match content" issue on 04/23 is resolved by
  reshuffling: 02/23 ("net/sxe2: add Rx framework and packet types
  callback") now correctly bundles the sxe2_txrx.c creation with the
  ptype callback registration, AVX512 and AVX2 are layered on top as
  separate patches (03/23, 04/23), and the old standalone "supported
  packet types get callback" patch is absorbed into 02/23. The
  ordering also makes more sense - frame, then vector specializations.

- The ptype-table refactor is now complete: adapter->ptype_tbl field
  removed from struct sxe2_adapter, sxe2_init_ptype_tbl() function
  removed entirely, all readers (vec_avx2, vec_avx512, vec_sse, vec_neon,
  poll) now reference the file-scope static const sxe2_ptype_tbl[]
  directly. One indirection saved per packet in the inner loop, and
  SXE2_MAX_PTYPE_NUM * 4 bytes saved per port.

- The high_performance_mode local in sxe2_parse_no_sched_mode() is
  renamed to no_sched_mode, matching the struct field and the devarg
  string. The rename is now consistent throughout the series.

- No regressions: full rescan for the usual high-value classes
  (raw_free_bulk on mixed pools, volatile inter-thread flags, 64-bit
  shifts, forbidden tokens, asm-generic, LLM placeholders) finds
  nothing. All long-standing fixes from earlier rounds persist (atomics
  removed from sw_stats, event_thread_run atomic, monitor DD_MASK,
  Inline crypto matrix entry).

One open design item:

[PATCH v5 22/23] flow-duplicate-pattern still defaults to 1

This was the only v4 item I considered design-blocking, and it isn't
addressed in v5. The devarg still toggles whether rte_flow rules with
identical patterns are accepted (value=1) or rejected with EEXIST
(value=0), and 1 is the default. The behaviour of a standard API
shouldn't vary per boot flag, and every other PMD rejects duplicates
with EEXIST. Pick that policy, apply it unconditionally, and drop the
devarg. The switch_pattern_dup_allow field on rule metadata can stay
if the hardware/firmware path internally needs it - just don't expose
the policy choice to userspace as a boot-time knob.

With that one change, this is ready.


^ permalink raw reply

* Re: [PATCH v9 00/21] Wangxun Fixes
From: Stephen Hemminger @ 2026-06-22 15:30 UTC (permalink / raw)
  To: Zaiyu Wang; +Cc: dev
In-Reply-To: <20260622111111.21024-1-zaiyuwang@trustnetic.com>

On Mon, 22 Jun 2026 19:10:48 +0800
Zaiyu Wang <zaiyuwang@trustnetic.com> wrote:

> This series fixes several issues found on Wangxun Emerald, Sapphire and
> Amber-lite NICs, with a focus on link-related problems.
> ---
> v9:
> - Fixed several checkpatch errors
> ---
> v8:
> - Fixed compilation error by replacing RTE_ETH_DEV_TO_PCI with RTE_CLASS_TO_BUS_DEVICE
> ---
> v7:
> - Fixed inverted semantics of is_flat_mem to match SFF8636
> ---
> v6:
> - Fixed more issues identified by AI review
> ---
> v5:
> - Fixed issues identified by AI review
> ---
> v4:
> - Fixed issues identified by devtools scripts
> ---
> v3:
> - Addressed Stephen's comments
> ---
> v2:
> - Fixed compilation error and code style issues
> ---
> 
> Zaiyu Wang (21):
>   net/txgbe: remove duplicate xstats counters
>   net/ngbe: remove duplicate xstats counters
>   net/ngbe: add missing CDR config for YT PHY
>   net/ngbe: fix VF promiscuous and allmulticast
>   net/txgbe: fix inaccuracy in Tx rate limiting
>   net/txgbe: fix link status check condition
>   net/txgbe: fix Tx desc free logic
>   net/txgbe: fix link flow control registers for Amber-Lite
>   net/txgbe: fix link flow control config for Sapphire
>   net/txgbe: fix a mass of unknown interrupts
>   net/txgbe: fix traffic class priority configuration
>   net/txgbe: fix link stability for 25G NIC
>   net/txgbe: fix link stability for 40G NIC
>   net/txgbe: fix link stability for Amber-Lite backplane mode
>   net/txgbe: fix FEC mode configuration on 25G NIC
>   net/txgbe: fix SFP module identification
>   net/txgbe: fix get module info operation
>   net/txgbe: fix get EEPROM operation
>   net/txgbe: fix to reset Tx write-back pointer
>   net/txgbe: fix to enable Tx desc check
>   net/txgbe: fix temperature track for AML NIC
> 
>  drivers/net/ngbe/base/ngbe_phy_yt.c       |    3 +
>  drivers/net/ngbe/ngbe_ethdev.c            |    5 -
>  drivers/net/ngbe/ngbe_ethdev_vf.c         |   11 +-
>  drivers/net/txgbe/base/meson.build        |    2 +
>  drivers/net/txgbe/base/txgbe.h            |    2 +
>  drivers/net/txgbe/base/txgbe_aml.c        |  185 +-
>  drivers/net/txgbe/base/txgbe_aml.h        |    6 +-
>  drivers/net/txgbe/base/txgbe_aml40.c      |  114 +-
>  drivers/net/txgbe/base/txgbe_aml40.h      |    6 +-
>  drivers/net/txgbe/base/txgbe_dcb_hw.c     |    2 +-
>  drivers/net/txgbe/base/txgbe_e56.c        | 3773 +++++++++++++++++++++
>  drivers/net/txgbe/base/txgbe_e56.h        | 1753 ++++++++++
>  drivers/net/txgbe/base/txgbe_e56_bp.c     | 2597 ++++++++++++++
>  drivers/net/txgbe/base/txgbe_e56_bp.h     |  282 ++
>  drivers/net/txgbe/base/txgbe_hw.c         |   54 +-
>  drivers/net/txgbe/base/txgbe_hw.h         |    4 +-
>  drivers/net/txgbe/base/txgbe_osdep.h      |    4 +
>  drivers/net/txgbe/base/txgbe_phy.c        |  362 +-
>  drivers/net/txgbe/base/txgbe_phy.h        |   46 +-
>  drivers/net/txgbe/base/txgbe_regs.h       |   13 +-
>  drivers/net/txgbe/base/txgbe_type.h       |   43 +-
>  drivers/net/txgbe/txgbe_ethdev.c          |  472 ++-
>  drivers/net/txgbe/txgbe_ethdev.h          |    7 +-
>  drivers/net/txgbe/txgbe_rxtx.c            |  109 +-
>  drivers/net/txgbe/txgbe_rxtx.h            |   36 +
>  drivers/net/txgbe/txgbe_rxtx_vec_common.h |   17 +-
>  26 files changed, 9464 insertions(+), 444 deletions(-)
>  create mode 100644 drivers/net/txgbe/base/txgbe_e56.c
>  create mode 100644 drivers/net/txgbe/base/txgbe_e56.h
>  create mode 100644 drivers/net/txgbe/base/txgbe_e56_bp.c
>  create mode 100644 drivers/net/txgbe/base/txgbe_e56_bp.h
> 

Applied to next-net, but this driver still has some unprefixed symbols:

 $ nm ./drivers/librte_net_txgbe.a  | grep ' [TD] ' | grep -v ' txgbe'
0000000000000510 T set_fields_e56
0000000000007ca0 T handle_e56_bkp_an73_flow

^ permalink raw reply

* Re: [PATCH v2 0/9] ENETC driver related changes series
From: Stephen Hemminger @ 2026-06-22 15:06 UTC (permalink / raw)
  To: Gagandeep Singh; +Cc: dev, hemant.agrawal
In-Reply-To: <20260622113517.1616028-1-g.singh@nxp.com>

On Mon, 22 Jun 2026 17:05:08 +0530
Gagandeep Singh <g.singh@nxp.com> wrote:

> V2 changes:
>   - Fixed an un-used variable compilation issue reported on fedora:43-gcc-minsize
>   - Fixed various AI reported issues:
> 	- Release notes updated for all new devargs
> 	- enect4.ini features doc updated for scattered RX.
> 	- removed Not required RTE_PTYPE_UNKNOWN.
> 	- Fixed mid-frame mbuf leak in SG case.
> 	- Enabled SG for enetc4 PF also.
> 	- move to calloc from rte_zmalloc in parse_txq_prior().
> 	- added vaidation checks on strdup, strtoul.
> 	- added NC devargs to use cacheable ops conditionally.
> 	- removed dead code like bd_base_p etc.
> 	- Fixed rte_cpu_to_le_16() conversion on flags and combined
> 	  all flags related patches in one patch.
> 	- Fixed memory leak issue due to TXQ priority patch.
>    - There were some false positives, I have ignored them:
> 	Race condition on flags field:
> 		clean_tx_ring only touches HW-completed BDs (next_to_clean→hwci),
> 		never newly-submitted BDs; doorbell hasn't fired yet.
> 	Missing dcbf in clean_tx_ring:
> 		DPDK is single-threaded per queue; TX path always overwrites
> 		flags completely before dcbf.
> 	TX dcbf granularity with wrap:
> 		Safe (AI admits it).
> 	RX refill flush at wrap:
> 		In-loop dcbf at i & mask == 0 already flushes aligned groups;
> 		trailing flush only needed for partial groups.
> 	RX reading before invalidate:
> 		dccivac precedes the read for every group in the loop
> 
> Gagandeep Singh (7):
>   net/enetc: fix TX BD structure
>   net/enetc: fix queue initialization
>   net/enetc: support ESP packet type in packet parsing
>   net/enetc: update random MAC generation code
>   net/enetc: add option to disable VSI messaging
>   net/enetc: add devargs to control VSI-PSI timeout and delay
>   net/enetc4: add cacheable BD ring support with SW cache maintenance
> 
> Vanshika Shukla (2):
>   net/enetc: support scatter-gather
>   net/enetc: set user configurable priority to TX rings
> 
>  doc/guides/nics/features/enetc4.ini    |   1 +
>  doc/guides/rel_notes/release_26_07.rst |  10 +
>  drivers/net/enetc/base/enetc_hw.h      |  13 +-
>  drivers/net/enetc/enetc.h              |  31 +-
>  drivers/net/enetc/enetc4_ethdev.c      | 172 ++++++++--
>  drivers/net/enetc/enetc4_vf.c          | 204 ++++++++++--
>  drivers/net/enetc/enetc_ethdev.c       |  25 +-
>  drivers/net/enetc/enetc_rxtx.c         | 430 ++++++++++++++++++++++---
>  8 files changed, 768 insertions(+), 118 deletions(-)
> 

Better but still had some AI feedback if I asked it for more complete review.
Agree that putting new devargs in doc is needed.

Error
=====

[PATCH v2 7/9] net/enetc: add devargs to control VSI-PSI timeout and delay

drivers/net/enetc/enetc4_vf.c, enetc4_vf_dev_init()

  kvlist is leaked on the two invalid-value error paths. It is
  allocated by rte_kvargs_parse() (line 1347) and only freed at
  line 1385, but both

      return -1;   /* invalid VSI Timeout, line 1367 */
      return -1;   /* invalid VSI Delay,   line 1380 */

  return before that free. A malformed enetc4_vsi_timeout= or
  enetc4_vsi_delay= leaks the kvargs structure on every probe.

  Free before returning, e.g.:

      if (errno != 0 || hw->vsi_timeout == 0) {
              ENETC_PMD_ERR("Invalid VSI Timeout value = %u",
                              hw->vsi_timeout);
              rte_kvargs_free(kvlist);
              return -1;
      }

  (same for the delay path), or restructure with a goto.


Warning
=======

Series (patches 6-9)

  The new runtime devargs - enetc4_vsi_disable, enetc4_vsi_timeout,
  enetc4_vsi_delay, enetc4_txq_prior, and nc - are registered via
  RTE_PMD_REGISTER_PARAM_STRING and noted in the release notes, but
  doc/guides/nics/enetc4.rst has no Runtime Configuration section
  describing them. Convention is to document devargs in the NIC guide
  so users can find the syntax (e.g. the nc=1 / 'a|b|c' priority list
  formats are non-obvious).

Info
====

[PATCH v2 5/9] and [PATCH v2 9/9] - RX multi-segment reassembly

  In enetc_clean_rx_ring_nc() and enetc_clean_rx_ring_cacheable(),
  on the frame-last BD:

      first_seg->pkt_len -= rx_ring->crc_len;

  reduces pkt_len but leaves the final segment's data_len unchanged,
  so pkt_len != sum(data_len) when crc_len is non-zero. The old
  single-segment path kept them equal (pkt_len = data_len = buf_len
  - crc_len).

  This is currently unreachable: enetc4 does not advertise
  RTE_ETH_RX_OFFLOAD_KEEP_CRC, so crc_len is always 0 and the
  subtraction is a no-op. Flagging only so the asymmetry is on record
  if KEEP_CRC is ever added - at that point the last segment's
  data_len would need the same adjustment (and the CRC may straddle
  the last two segments).

^ permalink raw reply

* Re: [PATCH 2/6] ip_frag: discard datagrams with overlapping fragments
From: Stephen Hemminger @ 2026-06-22 15:03 UTC (permalink / raw)
  To: Morten Brørup; +Cc: dev, stable, Konstantin Ananyev
In-Reply-To: <98CBD80474FA8B44BF855DF32C47DC35F65934@smartserver.smartshare.dk>

On Mon, 22 Jun 2026 17:01:18 +0200
Morten Brørup <mb@smartsharesystems.com> wrote:

> > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > Sent: Friday, 19 June 2026 19.01
> > 
> > On Fri, 19 Jun 2026 15:12:21 +0200
> > Morten Brørup <mb@smartsharesystems.com> wrote:
> >   
> > > > +		/*
> > > > +		 * Overlap with an existing fragment. Per RFC 8200 section
> > > > 4.5
> > > > +		 * (and RFC 5722) the datagram must be discarded; the same
> > > > is
> > > > +		 * applied to IPv4. Free all collected fragments, drop this
> > > > one,
> > > > +		 * and invalidate the entry.
> > > > +		 */
> > > > +		if (ofs < fp->frags[i].ofs + fp->frags[i].len &&
> > > > +				fp->frags[i].ofs < ofs + len) {  
> > >
> > > This only catches fragments that are smaller than existing fragments,  
> > i.e. fit within one of the existing fragments.  
> > > It should be:
> > > if ((ofs >= fp->frags[i].ofs &&
> > > 		ofs < fp->frags[i].ofs + fp->frags[i].len) ||
> > > 		(ofs + len >= fp->frags[i].ofs &&
> > > 		ofs + len < fp->frags[i].ofs + fp->frags[i].len)) {
> > >  
> > > > +			ip_frag_free(fp, dr);  
> > 
> > The code here is comparing an incoming fragment N against existing
> > fragment E,
> > using half-open ranges [start, end).
> > 
> > The test in the patch is symmetric in N and E.
> >        ofs < e.ofs + e.len && e.ofs < ofs + len
> > 
> > The one you propose tests that either endpoint of N lands inside E.
> > 
> > Take a fixed stored fragment E = [200, 400) and run several incoming
> > fragments through both.
> >  N0 = ofs, N1 = ofs+len.
> > 
> > N inside E: N = [250, 300)
> > 
> > E:        |=========|        (200..400)
> > N:           |===|           (250..300)
> > 
> > Patch: 250 < 400 && 200 < 300 → T && T → overlap.
> > Proposed: (250≥200 && 250<400) → T → overlap.
> > Both agree.
> > 
> > N encloses E: N = [100, 500)
> > 
> > E:        |=========|        (200..400)
> > N:      |=============|      (100..500)
> > 
> > Patch: 100 < 400 && 200 < 500 → T && T → overlap.
> > Proposed: (100≥200 && …) → F, (500≥200 && 500<400) → T && F → F, so F
> > || F → no overlap, MISSED.
> > 
> > This is the case the new version version drops. Neither endpoint of N
> > (100 or 500) sits inside [200,400),
> > because N straddles E completely, so new version endpoint-in-E check
> > fails even though the ranges clearly overlap.
> > Patch version catches it because the interval test doesn't care which
> > range is larger.
> > 
> > N partial on the left: N = [100, 300)
> > 
> > E:        |=========|        (200..400)
> > N:      |======|             (100..300)
> > 
> > Patch: 100 < 400 && 200 < 300 → T → overlap.
> > Proposed: (300≥200 && 300<400) → T → overlap.
> > Agree.
> > 
> > N partial on the right: N = [300, 500) — symmetric to the above, both
> > catch it.
> > 
> > So on the four genuine-overlap geometries, your suggestion catches all
> > four and his misses the enclosing one.
> > That is not right since the enclosing overlap is a legitimate attack
> > shape (a big fragment overwriting a smaller stored one).
> > 
> > There is another issue.
> > The >= on the exclusive end produces a false positive on fragments that
> > merely abut, which is the normal case.
> > Take E already stored as [1400, 2800) and an in-order-but-late fragment
> > N = [0, 1400) arriving after it (ordinary out-of-order delivery):
> > 
> > N:      |======|             (0..1400)
> > E:             |======|      (1400..2800)
> > 
> > These share no bytes; byte 1400 belongs only to E.
> > Patch: 0 < 2800 && 1400 < 1400 → T && F → no overlap, correct.
> > Proposed: (1400≥1400 && 1400<2800) → T && T → overlap, wrong.
> > This test would discard a perfectly valid datagram whenever a left-
> > abutting fragment arrives after its neighbor.
> > Adjacent fragments abutting is what fragmentation produces by design,
> > so this would fire constantly under reordering.
> > 
> > Bottom line: the patch was correct as far as I can tell.  
> 
> Thank you for the detailed explanation, Stephen.
> Agreed, and sorry about the noise. :-)
> 

I will give credit to Claude for the detail. I reviewed the general
code here; but had to prod it into giving a more detailed explaination
because it was confusing..

^ permalink raw reply

* RE: [PATCH 0/6] ip_frag: fix reassembly defects and add test
From: Morten Brørup @ 2026-06-22 15:03 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger
In-Reply-To: <20260616210656.464062-1-stephen@networkplumber.org>

> With patch 2/6 fixed,
> Series-acked-by: Morten Brørup <mb@smartsharesystems.com>

No bug in patch 2/6, so no fix required.
Series-acked-by: Morten Brørup <mb@smartsharesystems.com>

Ref: https://inbox.dpdk.org/dev/98CBD80474FA8B44BF855DF32C47DC35F65934@smartserver.smartshare.dk/T/#u


^ permalink raw reply

* RE: [PATCH 2/6] ip_frag: discard datagrams with overlapping fragments
From: Morten Brørup @ 2026-06-22 15:01 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev, stable, Konstantin Ananyev
In-Reply-To: <20260619100124.655e5540@phoenix.local>

> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Friday, 19 June 2026 19.01
> 
> On Fri, 19 Jun 2026 15:12:21 +0200
> Morten Brørup <mb@smartsharesystems.com> wrote:
> 
> > > +		/*
> > > +		 * Overlap with an existing fragment. Per RFC 8200 section
> > > 4.5
> > > +		 * (and RFC 5722) the datagram must be discarded; the same
> > > is
> > > +		 * applied to IPv4. Free all collected fragments, drop this
> > > one,
> > > +		 * and invalidate the entry.
> > > +		 */
> > > +		if (ofs < fp->frags[i].ofs + fp->frags[i].len &&
> > > +				fp->frags[i].ofs < ofs + len) {
> >
> > This only catches fragments that are smaller than existing fragments,
> i.e. fit within one of the existing fragments.
> > It should be:
> > if ((ofs >= fp->frags[i].ofs &&
> > 		ofs < fp->frags[i].ofs + fp->frags[i].len) ||
> > 		(ofs + len >= fp->frags[i].ofs &&
> > 		ofs + len < fp->frags[i].ofs + fp->frags[i].len)) {
> >
> > > +			ip_frag_free(fp, dr);
> 
> The code here is comparing an incoming fragment N against existing
> fragment E,
> using half-open ranges [start, end).
> 
> The test in the patch is symmetric in N and E.
>        ofs < e.ofs + e.len && e.ofs < ofs + len
> 
> The one you propose tests that either endpoint of N lands inside E.
> 
> Take a fixed stored fragment E = [200, 400) and run several incoming
> fragments through both.
>  N0 = ofs, N1 = ofs+len.
> 
> N inside E: N = [250, 300)
> 
> E:        |=========|        (200..400)
> N:           |===|           (250..300)
> 
> Patch: 250 < 400 && 200 < 300 → T && T → overlap.
> Proposed: (250≥200 && 250<400) → T → overlap.
> Both agree.
> 
> N encloses E: N = [100, 500)
> 
> E:        |=========|        (200..400)
> N:      |=============|      (100..500)
> 
> Patch: 100 < 400 && 200 < 500 → T && T → overlap.
> Proposed: (100≥200 && …) → F, (500≥200 && 500<400) → T && F → F, so F
> || F → no overlap, MISSED.
> 
> This is the case the new version version drops. Neither endpoint of N
> (100 or 500) sits inside [200,400),
> because N straddles E completely, so new version endpoint-in-E check
> fails even though the ranges clearly overlap.
> Patch version catches it because the interval test doesn't care which
> range is larger.
> 
> N partial on the left: N = [100, 300)
> 
> E:        |=========|        (200..400)
> N:      |======|             (100..300)
> 
> Patch: 100 < 400 && 200 < 300 → T → overlap.
> Proposed: (300≥200 && 300<400) → T → overlap.
> Agree.
> 
> N partial on the right: N = [300, 500) — symmetric to the above, both
> catch it.
> 
> So on the four genuine-overlap geometries, your suggestion catches all
> four and his misses the enclosing one.
> That is not right since the enclosing overlap is a legitimate attack
> shape (a big fragment overwriting a smaller stored one).
> 
> There is another issue.
> The >= on the exclusive end produces a false positive on fragments that
> merely abut, which is the normal case.
> Take E already stored as [1400, 2800) and an in-order-but-late fragment
> N = [0, 1400) arriving after it (ordinary out-of-order delivery):
> 
> N:      |======|             (0..1400)
> E:             |======|      (1400..2800)
> 
> These share no bytes; byte 1400 belongs only to E.
> Patch: 0 < 2800 && 1400 < 1400 → T && F → no overlap, correct.
> Proposed: (1400≥1400 && 1400<2800) → T && T → overlap, wrong.
> This test would discard a perfectly valid datagram whenever a left-
> abutting fragment arrives after its neighbor.
> Adjacent fragments abutting is what fragmentation produces by design,
> so this would fire constantly under reordering.
> 
> Bottom line: the patch was correct as far as I can tell.

Thank you for the detailed explanation, Stephen.
Agreed, and sorry about the noise. :-)


^ permalink raw reply

* Re: [PATCH v8 12/21] net/txgbe: fix link stability for 25G NIC
From: Stephen Hemminger @ 2026-06-22 14:53 UTC (permalink / raw)
  To: Zaiyu Wang; +Cc: dev
In-Reply-To: <006c01dd0237$9a737e60$cf5a7b20$@trustnetic.com>

On Mon, 22 Jun 2026 19:09:32 +0800
Zaiyu Wang <zaiyuwang@trustnetic.com> wrote:

> > > +void
> > > +set_fields_e56(unsigned int *src_data, unsigned int bit_high,
> > > +	       unsigned int bit_low, unsigned int set_value) {  
> > 
> > Function could be static here?  
> 
> Hi Stephen,
> Thanks for your time. This function is used in both txgbe_e56.c (for general PHY
> configuration) and txgbe_e56_bp.c (for backplane mode configuration). Therefore, making it
> static would not be feasible?
> I have also fixed the other issues you pointed out, including the spelling corrections,
> replacing tabs with spaces in log messages, and removing the term "master" from comments.
> 
> Best regards,
> Zaiyu


Why I noticed was that it is a global function not following naming conventions.
Either make it inline in a header or rename.

^ permalink raw reply

* Re: [PATCH v5 11/24] drivers: replace rte_atomic16 with stdatomic
From: saeed bishara @ 2026-06-22 14:46 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev, Hemant Agrawal, Sachin Saxena
In-Reply-To: <20260620023134.42877-12-stephen@networkplumber.org>

On Sat, Jun 20, 2026 at 5:41 AM Stephen Hemminger
<stephen@networkplumber.org> wrote:

> @@ -84,7 +84,7 @@ dpaa2_create_dpbp_device(int vdev_fd __rte_unused,
>         }
>
>         dpbp_node->dpbp_id = dpbp_id;
> -       rte_atomic16_init(&dpbp_node->in_use);
> +       dpbp_node->in_use = 0;
The previous code implies an ordering barrier, so it guarantees that
dpbp_node->dpbp_id is visible before in_use, while the new code
doesn't. isn't the a problem?
>
>         TAILQ_INSERT_TAIL(&dpbp_dev_list, dpbp_node, next);
>
> @@ -103,7 +103,10 @@ struct dpaa2_dpbp_dev *dpaa2_alloc_dpbp_dev(void)
>
>         /* Get DPBP dev handle from list using index */
>         TAILQ_FOREACH(dpbp_dev, &dpbp_dev_list, next) {
> -               if (dpbp_dev && rte_atomic16_test_and_set(&dpbp_dev->in_use))
> +               uint16_t expected = 0;
> +               if (rte_atomic_compare_exchange_strong_explicit(
> +                           &dpbp_dev->in_use, &expected, 1,
> +                           rte_memory_order_acquire, rte_memory_order_relaxed))

aren't rte_atomic_flag_test_and_set_explicit/rte_atomic_flag_clear_explicit
a better candidates instead of
rte_atomic_compare_exchange_strong_explicit/rte_atomic_store_explicit
?

^ permalink raw reply

* Re: [PATCH v2 2/2] test/dma: add functions to verify zero and one fill
From: Bruce Richardson @ 2026-06-22 13:58 UTC (permalink / raw)
  To: Tejasree Kondoj
  Cc: Akhil Goyal, Chengwen Feng, Kevin Laatz, Vidya Sagar Velumuri,
	Anoob Joseph, dev
In-Reply-To: <20260622135208.87697-3-ktejasree@marvell.com>

On Mon, Jun 22, 2026 at 07:22:08PM +0530, Tejasree Kondoj wrote:
> Add test cases to verify zero fill and one fill
> 
> Signed-off-by: Vidya Sagar Velumuri <vvelumuri@marvell.com>
> Signed-off-by: Tejasree Kondoj <ktejasree@marvell.com>
> ---
>  app/test/test.h        |  4 +++
>  app/test/test_dmadev.c | 57 ++++++++++++++++++++++++------------------
>  2 files changed, 37 insertions(+), 24 deletions(-)
> 
Feedback on v1 of this patch is still relevant, please check my comments
there.
Additional comments inline below here too.

Thanks,
/Bruce

> diff --git a/app/test/test.h b/app/test/test.h
> index b29233bb32..d313300056 100644
> --- a/app/test/test.h
> +++ b/app/test/test.h
> @@ -34,6 +34,10 @@
>  
>  #include <rte_test.h>
>  
> +#ifndef ARRAY_SIZE
> +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

This is the same as RTE_DIM.

> +#endif
> +
>  #define TEST_ASSERT RTE_TEST_ASSERT
>  
>  #define TEST_ASSERT_EQUAL RTE_TEST_ASSERT_EQUAL
> diff --git a/app/test/test_dmadev.c b/app/test/test_dmadev.c
> index b30f2214e5..d4299e501d 100644
> --- a/app/test/test_dmadev.c
> +++ b/app/test/test_dmadev.c
> @@ -931,42 +931,51 @@ test_completion_handling(int16_t dev_id, uint16_t vchan)
>  static int
>  test_enqueue_fill(int16_t dev_id, uint16_t vchan)
>  {
> +	uint64_t pattern[3] = {0x0, 0xfedcba9876543210, 0xffffffffffffffff};

You don't need to hard-code the 3, since you always compute the size. Copy
what is done with "lengths" below.

>  	const unsigned int lengths[] = {8, 64, 1024, 50, 100, 89};
> +	unsigned int i, j, k;
>  	struct rte_mbuf *dst;
>  	char *dst_data;
> -	uint64_t pattern = 0xfedcba9876543210;
> -	unsigned int i, j;
>  
>  	dst = rte_pktmbuf_alloc(pool);
>  	if (dst == NULL)
>  		ERR_RETURN("Failed to allocate mbuf\n");
>  	dst_data = rte_pktmbuf_mtod(dst, char *);
>  
> -	for (i = 0; i < RTE_DIM(lengths); i++) {
> -		/* reset dst_data */
> -		memset(dst_data, 0, rte_pktmbuf_data_len(dst));
> +	for (k = 0; k < ARRAY_SIZE(pattern); k++) {
> +		for (i = 0; i < RTE_DIM(lengths); i++) {
> +			/* reset dst_data */
> +			memset(dst_data, 0, rte_pktmbuf_data_len(dst));
> +
> +			/* perform the fill operation */
> +			int id = rte_dma_fill(dev_id, vchan, pattern[k],
> +					rte_pktmbuf_iova(dst), lengths[i], RTE_DMA_OP_FLAG_SUBMIT);
> +			if (id < 0) {
> +				if (id == -ENOTSUP) {
> +					rte_pktmbuf_free(dst);
> +					return 0;
> +				}
> +				ERR_RETURN("Error with rte_dma_fill\n");
> +			}
> +			await_hw(dev_id, vchan);
>  
> -		/* perform the fill operation */
> -		int id = rte_dma_fill(dev_id, vchan, pattern,
> -				rte_pktmbuf_iova(dst), lengths[i], RTE_DMA_OP_FLAG_SUBMIT);
> -		if (id < 0)
> -			ERR_RETURN("Error with rte_dma_fill\n");
> -		await_hw(dev_id, vchan);
> +			if (rte_dma_completed(dev_id, vchan, 1, NULL, NULL) != 1)
> +				ERR_RETURN("Error: fill operation failed (length: %u)\n",
> +					   lengths[i]);
> +			/* check the data from the fill operation is correct */
> +			for (j = 0; j < lengths[i]; j++) {
> +				char pat_byte = ((char *)&pattern[k])[j % 8];
>  
> -		if (rte_dma_completed(dev_id, vchan, 1, NULL, NULL) != 1)
> -			ERR_RETURN("Error: fill operation failed (length: %u)\n", lengths[i]);
> -		/* check the data from the fill operation is correct */
> -		for (j = 0; j < lengths[i]; j++) {
> -			char pat_byte = ((char *)&pattern)[j % 8];
> -			if (dst_data[j] != pat_byte)
> -				ERR_RETURN("Error with fill operation (lengths = %u): got (%x), not (%x)\n",
> -						lengths[i], dst_data[j], pat_byte);
> +				if (dst_data[j] != pat_byte)
> +					ERR_RETURN("Error with fill operation (lengths = %u): got (%x), not (%x)\n",
> +							lengths[i], dst_data[j], pat_byte);
> +			}
> +			/* check that the data after the fill operation was not written to */
> +			for (; j < rte_pktmbuf_data_len(dst); j++)
> +				if (dst_data[j] != 0)
> +					ERR_RETURN("Error, fill operation wrote too far (lengths = %u): got (%x), not (%x)\n",
> +							lengths[i], dst_data[j], 0);
>  		}
> -		/* check that the data after the fill operation was not written to */
> -		for (; j < rte_pktmbuf_data_len(dst); j++)
> -			if (dst_data[j] != 0)
> -				ERR_RETURN("Error, fill operation wrote too far (lengths = %u): got (%x), not (%x)\n",
> -						lengths[i], dst_data[j], 0);
>  	}
>  
>  	rte_pktmbuf_free(dst);
> -- 
> 2.34.1
> 

^ permalink raw reply


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