* Re: [PATCH v4 00/25] Consolidate bus driver infrastructure
From: David Marchand @ 2026-05-29 11:53 UTC (permalink / raw)
To: fengchengwen; +Cc: dev, thomas, stephen, bruce.richardson
In-Reply-To: <8fe9d77c-9ade-4cbe-ac99-582f95531cb4@huawei.com>
Hello Chengwen,
On Fri, 29 May 2026 at 09:47, fengchengwen <fengchengwen@huawei.com> wrote:
>
> Hi David,
>
> First, this is a great refactoring, thank you very much.
>
> I have tested this patchset on the UACCE bus and it passes. Two issues were
> found during testing and review:
>
> 1. Patch 25/25 fails to apply to the current main branch.
Yes, I am aware: next-net-intel got pulled in main after my rebase for v4.
> 2. Patch 15/25 (bus: support multiple probing) has issues with directly
> enabling multiple probing. I suggest merging this patch into Patch 17/25.
I am not sure I understand the issue, but I will have a look asap and post a v5.
> The UACCE bus part has passed testing. Please add my Acked-by tag to the
> related commits.
>
Thanks a lot for your reviews and testing!
--
David Marchand
^ permalink raw reply
* RE: [PATCH v6] mempool: improve cache behaviour and performance
From: Morten Brørup @ 2026-05-29 11:43 UTC (permalink / raw)
To: fengchengwen, dev, Andrew Rybchenko, Bruce Richardson,
Jingjing Wu, Praveen Shetty, Hemant Agrawal, Sachin Saxena
In-Reply-To: <9b627380-0fc4-40b8-b927-c443a7bbba1b@huawei.com>
> From: fengchengwen [mailto:fengchengwen@huawei.com]
> Sent: Friday, 29 May 2026 10.54
>
> On 5/26/2026 10:00 PM, Morten Brørup wrote:
> > This patch refactors the mempool cache to eliminate some unexpected
> > behaviour and reduce the mempool cache miss rate.
> >
> > 1.
> > The actual cache size was 1.5 times the cache size specified at run-
> time
> > mempool creation.
> > This was obviously not expected by application developers.
> >
> > 2.
> > In get operations, the check for when to use the cache as bounce
> buffer
> > did not respect the run-time configured cache size,
> > but compared to the build time maximum possible cache size
> > (RTE_MEMPOOL_CACHE_MAX_SIZE, default 512).
> > E.g. with a configured cache size of 32 objects, getting 256 objects
> > would first fetch 32 + 256 = 288 objects into the cache,
> > and then move the 256 objects from the cache to the destination
> memory,
> > instead of fetching the 256 objects directly to the destination
> memory.
> > This had a performance cost.
> > However, this is unlikely to occur in real applications, so it is not
> > important in itself.
> >
> > 3.
> > When putting objects into a mempool, and the mempool cache did not
> have
> > free space for so many objects,
> > the cache was flushed completely, and the new objects were then put
> into
> > the cache.
> > I.e. the cache drain level was zero.
> > This (complete cache flush) meant that a subsequent get operation
> (with
> > the same number of objects) completely emptied the cache,
> > so another subsequent get operation required replenishing the cache.
> >
> > Similarly,
> > When getting objects from a mempool, and the mempool cache did not
> hold so
> > many objects,
> > the cache was replenished to cache->size + remaining objects,
> > and then (the remaining part of) the requested objects were fetched
> via
> > the cache,
> > which left the cache filled (to cache->size) at completion.
> > I.e. the cache refill level was cache->size (plus some, depending on
> > request size).
> >
> > (1) was improved by generally comparing to cache->size instead of
> > cache->flushthresh, when considering the capacity of the cache.
> > The cache->flushthresh field is kept for API/ABI compatibility
> purposes,
> > and initialized to cache->size instead of cache->size * 1.5.
> >
> > (2) was improved by generally comparing to cache->size / 2 instead of
> > RTE_MEMPOOL_CACHE_MAX_SIZE, when checking the bounce buffer limit.
> >
> > (3) was improved by flushing and replenishing the cache by half its
> size,
> > so a flush/refill can be followed randomly by get or put requests.
> > This also reduced the number of objects in each flush/refill
> operation.
> >
> > As a consequence of these changes, the size of the array holding the
> > objects in the cache (cache->objs[]) no longer needs to be
> > 2 * RTE_MEMPOOL_CACHE_MAX_SIZE, and can be reduced to
> > RTE_MEMPOOL_CACHE_MAX_SIZE at an API/ABI breaking release.
> >
> > Performance data:
> > With a real WAN Optimization application, where the number of
> allocated
> > packets varies (as they are held in e.g. shaper queues), the mempool
> > cache miss rate dropped from ca. 1/20 objects to ca. 1/48 objects.
> > This was deployed in production at an ISP, and using an effective
> cache
> > size of 384 objects.
>
> Does the application run as a RTC (run-to-complete) mode?
Yes, the application runs as RTC mode.
> How about pipeline model which NIC recv packets and enqueue ring,
> another
> work thread dequeue packets, process packets and then free packets
> mbuf?
>
If one thread only receives packets (mempool get) and another thread only transmits/frees (mempool put), their cache miss rate roughly doubles.
But the number of objects copied to/from the backend per cache miss roughly halves to exactly size/2.
And the backend copy operations become CPU cache aligned (assuming all transactions with the backend go via the mempool cache).
The release notes mention that such pipelined applications should double their configured mempool cache size.
^ permalink raw reply
* Re: [PATCH] net/sxe2: fix 32-bit SSE build
From: Thomas Monjalon @ 2026-05-29 10:24 UTC (permalink / raw)
To: Jie Liu; +Cc: dev, David Marchand
In-Reply-To: <CAJFAV8xY0uM=RbcR64ZMc-eOTVkzZc0PFTCBCaQkNNE7uuvZeg@mail.gmail.com>
28/05/2026 11:47, David Marchand:
> On Thu, 28 May 2026 at 10:47, Thomas Monjalon <thomas@monjalon.net> wrote:
> >
> > Seen in OBS on i586 Debian:
> >
> > from ../drivers/net/sxe2/sxe2_txrx_vec_sse.c:5:
> > In function ‘_mm_loadu_si128’,
> > inlined from ‘rte_memcpy’
> > inlined from ‘sxe2_rx_pkts_refactor’
> > at ../drivers/net/sxe2/sxe2_txrx_vec_common.h:233:2:
> > /usr/lib/gcc/i686-linux-gnu/12/include/emmintrin.h:703:10: error:
> > array subscript 8 is outside array bounds of ‘struct rte_mbuf *[32]’
> >
> > The important options to reproduce are "-m32 -O2 -march=corei7".
> >
> > In 32-bit build the pointer array done_pkts[32] is smaller:
> > 32 * 4 = 128 bytes
> > so an SSE access would be outside the bound.
> >
> > The libc memcpy does not trigger such warning
> > and is a good choice to copy an array of pointers.
> >
> > Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
>
> I reproduced and checked Debian 13 32 bits build with OBS.
> Tested-by: David Marchand <david.marchand@redhat.com>
Fixes: ac60f302cbef ("net/sxe2: add vectorized Rx and Tx")
Applied
^ permalink raw reply
* Re: [PATCH 0/2] ip_frag: TAILQ and hash fixes
From: Thomas Monjalon @ 2026-05-29 10:21 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev
In-Reply-To: <20260408161947.285185-1-stephen@networkplumber.org>
08/04/2026 18:16, Stephen Hemminger:
> The ip_frag library had a couple of issues found during review.
> The use of TAILQ made assumptions about TAILQ_REMOVE,
> and the hash function usage could be abused by attacker.
>
> Stephen Hemminger (2):
> ip_frag: fix unsafe TAILQ usage
> ip_frag: randomize hash seed
Applied, thanks.
^ permalink raw reply
* [v1] crypto/cnxk: add ML crypto support
From: Gowrishankar Muthukrishnan @ 2026-05-29 9:13 UTC (permalink / raw)
To: dev, Akhil Goyal, Nithin Dabilpuram, Kiran Kumar K,
Sunil Kumar Kori, Satha Rao, Harman Kalra, Ankur Dwivedi,
Anoob Joseph, Tejasree Kondoj
Cc: Gowrishankar Muthukrishnan
Add ML-KEM and ML-DSA support.
Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
doc/guides/cryptodevs/features/cn20k.ini | 3 +
doc/guides/cryptodevs/features/default.ini | 1 +
doc/guides/rel_notes/release_26_07.rst | 3 +
drivers/common/cnxk/hw/cpt.h | 1 +
drivers/common/cnxk/meson.build | 1 +
drivers/common/cnxk/roc_cpt.c | 4 +
drivers/common/cnxk/roc_platform.h | 5 +
.../common/cnxk/roc_platform_base_symbols.c | 2 +
drivers/common/cnxk/roc_re.h | 31 ++
drivers/common/cnxk/roc_re_ml_tables.c | 248 +++++++++++
drivers/common/cnxk/roc_re_ml_tables.h | 19 +
drivers/crypto/cnxk/cnxk_ae.h | 399 +++++++++++++++++-
drivers/crypto/cnxk/cnxk_cryptodev.c | 11 +
drivers/crypto/cnxk/cnxk_cryptodev.h | 4 +-
.../crypto/cnxk/cnxk_cryptodev_capabilities.c | 62 ++-
drivers/crypto/cnxk/cnxk_cryptodev_ops.c | 45 +-
16 files changed, 817 insertions(+), 22 deletions(-)
create mode 100644 drivers/common/cnxk/roc_re.h
create mode 100644 drivers/common/cnxk/roc_re_ml_tables.c
create mode 100644 drivers/common/cnxk/roc_re_ml_tables.h
diff --git a/doc/guides/cryptodevs/features/cn20k.ini b/doc/guides/cryptodevs/features/cn20k.ini
index d4c52082c6..8180128744 100644
--- a/doc/guides/cryptodevs/features/cn20k.ini
+++ b/doc/guides/cryptodevs/features/cn20k.ini
@@ -21,6 +21,7 @@ Asymmetric sessionless = Y
Sym raw data path API = Y
Inner checksum = Y
Rx inject = Y
+ML-DSA sign prehash = Y
;
; Supported crypto algorithms of 'cn20k' crypto driver.
@@ -110,6 +111,8 @@ ECDSA = Y
ECPM = Y
SM2 = Y
EdDSA = Y
+ML-DSA = Y
+ML-KEM = Y
;
; Supported Operating systems of the 'cn20k' crypto driver.
diff --git a/doc/guides/cryptodevs/features/default.ini b/doc/guides/cryptodevs/features/default.ini
index d8026c3750..be4ee777fb 100644
--- a/doc/guides/cryptodevs/features/default.ini
+++ b/doc/guides/cryptodevs/features/default.ini
@@ -35,6 +35,7 @@ Cipher multiple data units =
Cipher wrapped key =
Inner checksum =
Rx inject =
+ML-DSA sign prehash =
;
; Supported crypto algorithms of a default crypto driver.
diff --git a/doc/guides/rel_notes/release_26_07.rst b/doc/guides/rel_notes/release_26_07.rst
index 8b4f8401e2..67c1842afe 100644
--- a/doc/guides/rel_notes/release_26_07.rst
+++ b/doc/guides/rel_notes/release_26_07.rst
@@ -87,6 +87,9 @@ New Features
Added AGENTS.md file for AI review
and supporting scripts to review patches and documentation.
+* **Updated Marvell cnxk crypto driver.**
+
+ * Added support for ML-KEM and ML-DSA on CN20K platform.
Removed Items
-------------
diff --git a/drivers/common/cnxk/hw/cpt.h b/drivers/common/cnxk/hw/cpt.h
index eb795f61ac..12aeb4d054 100644
--- a/drivers/common/cnxk/hw/cpt.h
+++ b/drivers/common/cnxk/hw/cpt.h
@@ -58,6 +58,7 @@ enum cpt_eng_type {
CPT_ENG_TYPE_AE = 1,
CPT_ENG_TYPE_SE = 2,
CPT_ENG_TYPE_IE = 3,
+ CPT_ENG_TYPE_RE = 4,
CPT_MAX_ENG_TYPES,
};
diff --git a/drivers/common/cnxk/meson.build b/drivers/common/cnxk/meson.build
index 9db77a9702..3303ad9354 100644
--- a/drivers/common/cnxk/meson.build
+++ b/drivers/common/cnxk/meson.build
@@ -65,6 +65,7 @@ sources = files(
'roc_npc_utils.c',
'roc_platform.c',
'roc_platform_base_symbols.c',
+ 'roc_re_ml_tables.c',
'roc_se.c',
'roc_sso.c',
'roc_sso_debug.c',
diff --git a/drivers/common/cnxk/roc_cpt.c b/drivers/common/cnxk/roc_cpt.c
index 21d5e7f2ba..686c9eae7e 100644
--- a/drivers/common/cnxk/roc_cpt.c
+++ b/drivers/common/cnxk/roc_cpt.c
@@ -632,6 +632,9 @@ roc_cpt_dev_configure(struct roc_cpt *roc_cpt, int nb_lf, bool rxc_ena, uint16_t
eng_grpmsk = (1 << roc_cpt->eng_grp[CPT_ENG_TYPE_AE]) |
(1 << roc_cpt->eng_grp[CPT_ENG_TYPE_SE]);
+ if (roc_model_is_cn20k())
+ eng_grpmsk |= (1 << roc_cpt->eng_grp[CPT_ENG_TYPE_RE]);
+
if (roc_errata_cpt_has_ctx_fetch_issue()) {
ctx_ilen_valid = true;
/* Inbound SA size is max context size */
@@ -1097,6 +1100,7 @@ roc_cpt_eng_grp_add(struct roc_cpt *roc_cpt, enum cpt_eng_type eng_type)
case CPT_ENG_TYPE_AE:
case CPT_ENG_TYPE_SE:
case CPT_ENG_TYPE_IE:
+ case CPT_ENG_TYPE_RE:
break;
default:
ret = -EINVAL;
diff --git a/drivers/common/cnxk/roc_platform.h b/drivers/common/cnxk/roc_platform.h
index e22a50d47a..19f1d6005b 100644
--- a/drivers/common/cnxk/roc_platform.h
+++ b/drivers/common/cnxk/roc_platform.h
@@ -41,6 +41,7 @@
".arch_extension lse\n"
#endif
+#define PLT_ATOMIC RTE_ATOMIC
#define PLT_ASSERT RTE_ASSERT
#define PLT_VERIFY RTE_VERIFY
#define PLT_MEMZONE_NAMESIZE RTE_MEMZONE_NAMESIZE
@@ -217,6 +218,10 @@ plt_thread_is_valid(plt_thread_t thr)
#define plt_memory_order_release rte_memory_order_release
#define plt_memory_order_acquire rte_memory_order_acquire
#define plt_memory_order_relaxed rte_memory_order_relaxed
+#define plt_memory_order_seq_cst rte_memory_order_seq_cst
+
+#define plt_atomic_fetch_add_explicit rte_atomic_fetch_add_explicit
+#define plt_atomic_fetch_sub_explicit rte_atomic_fetch_sub_explicit
#define plt_bit_relaxed_get32 rte_bit_relaxed_get32
#define plt_bit_relaxed_set32 rte_bit_relaxed_set32
diff --git a/drivers/common/cnxk/roc_platform_base_symbols.c b/drivers/common/cnxk/roc_platform_base_symbols.c
index cf080b1bdc..75775fbe09 100644
--- a/drivers/common/cnxk/roc_platform_base_symbols.c
+++ b/drivers/common/cnxk/roc_platform_base_symbols.c
@@ -497,6 +497,8 @@ RTE_EXPORT_INTERNAL_SYMBOL(roc_npc_aged_flow_ctx_get)
RTE_EXPORT_INTERNAL_SYMBOL(roc_npc_defrag_mcam_banks)
RTE_EXPORT_INTERNAL_SYMBOL(roc_npc_get_key_type)
RTE_EXPORT_INTERNAL_SYMBOL(roc_npc_flow_mcam_dump)
+RTE_EXPORT_INTERNAL_SYMBOL(roc_re_ml_zeta_get)
+RTE_EXPORT_INTERNAL_SYMBOL(roc_re_ml_zeta_put)
RTE_EXPORT_INTERNAL_SYMBOL(roc_ree_queues_attach)
RTE_EXPORT_INTERNAL_SYMBOL(roc_ree_queues_detach)
RTE_EXPORT_INTERNAL_SYMBOL(roc_ree_msix_offsets_get)
diff --git a/drivers/common/cnxk/roc_re.h b/drivers/common/cnxk/roc_re.h
new file mode 100644
index 0000000000..a8cbda41c0
--- /dev/null
+++ b/drivers/common/cnxk/roc_re.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2026 Marvell.
+ */
+
+#ifndef __ROC_RE_H__
+#define __ROC_RE_H__
+
+/* RE ML opcodes */
+#define ROC_RE_MAJOR_OP_MLKEM 0x1A
+#define ROC_RE_MAJOR_OP_MLDSA 0x1B
+#define ROC_RE_MINOR_OP_MLKEM_KEYGEN 0x00
+#define ROC_RE_MINOR_OP_MLKEM_ENCAP 0x01
+#define ROC_RE_MINOR_OP_MLKEM_DECAP 0x02
+#define ROC_RE_MINOR_OP_MLDSA_KEYGEN 0x00
+#define ROC_RE_MINOR_OP_MLDSA_SIGN 0x01
+#define ROC_RE_MINOR_OP_MLDSA_VERIFY 0x02
+
+/* ML-KEM param2 fields */
+#define ROC_RE_ML_KEM_PARAM2_INMSG_BIT 4
+#define ROC_RE_ML_KEM_PARAM2_INSEED_BIT 5
+
+/* ML-DSA param2 fields */
+#define ROC_RE_ML_DSA_PARAM2_SIGN_BIT 4
+#define ROC_RE_ML_DSA_PARAM2_SEED_BIT 5
+#define ROC_RE_ML_DSA_PARAM2_CTXN_BIT 8
+
+/* ML-DSA minor op fields */
+#define ROC_RE_ML_DSA_MINOR_SIGN_TYPE_BIT 2
+#define ROC_RE_ML_DSA_MINOR_MSG_TYPE_BIT 4
+
+#endif /* __ROC_RE_H__ */
diff --git a/drivers/common/cnxk/roc_re_ml_tables.c b/drivers/common/cnxk/roc_re_ml_tables.c
new file mode 100644
index 0000000000..933e35e3c9
--- /dev/null
+++ b/drivers/common/cnxk/roc_re_ml_tables.c
@@ -0,0 +1,248 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2026 Marvell.
+ */
+
+#include "roc_re_ml_tables.h"
+
+#define RE_ML_TBL_NAME "re_ml_tbl"
+#define RE_MLKEM_ZETA_LEN 256
+#define RE_MLDSA_ZETA_LEN 1024
+
+/* ML table address and length */
+struct re_ml_entry {
+ const uint8_t *data;
+ int len;
+};
+
+struct re_ml_tbl {
+ PLT_ATOMIC(uint64_t) refcount;
+ uint8_t ml_tbl[];
+};
+
+const uint8_t re_mlkem_zeta_tbl[RE_MLKEM_ZETA_LEN] = {
+ 0x01, 0x00, 0xc1, 0x06, 0x14, 0x0a, 0xd9, 0x0c,
+ 0x52, 0x0a, 0x76, 0x02, 0x69, 0x07, 0x50, 0x03,
+ 0x26, 0x04, 0x7f, 0x07, 0xc1, 0x00, 0x1d, 0x03,
+ 0xe2, 0x0a, 0xbc, 0x0c, 0x39, 0x02, 0xd2, 0x06,
+ 0x28, 0x01, 0x8f, 0x09, 0x3b, 0x05, 0xc4, 0x05,
+ 0xe6, 0x0b, 0x38, 0x00, 0xc0, 0x08, 0x35, 0x05,
+ 0x92, 0x05, 0x2e, 0x08, 0x17, 0x02, 0x42, 0x0b,
+ 0x59, 0x09, 0x3f, 0x0b, 0xb6, 0x07, 0x35, 0x03,
+ 0x21, 0x01, 0x4b, 0x01, 0xb5, 0x0c, 0xdc, 0x06,
+ 0xad, 0x04, 0x00, 0x09, 0xe5, 0x08, 0x07, 0x08,
+ 0x8a, 0x02, 0xb9, 0x07, 0xd1, 0x09, 0x78, 0x02,
+ 0x31, 0x0b, 0x21, 0x00, 0x28, 0x05, 0x7b, 0x07,
+ 0x0f, 0x09, 0x9b, 0x05, 0x27, 0x03, 0xc4, 0x01,
+ 0x9e, 0x05, 0x34, 0x0b, 0xfe, 0x05, 0x62, 0x09,
+ 0x57, 0x0a, 0x39, 0x0a, 0xc9, 0x05, 0x88, 0x02,
+ 0xaa, 0x09, 0x26, 0x0c, 0xcb, 0x04, 0x8e, 0x03,
+ 0x11, 0x00, 0xc9, 0x0a, 0x47, 0x02, 0x59, 0x0a,
+ 0x65, 0x06, 0xd3, 0x02, 0xf0, 0x08, 0x4c, 0x04,
+ 0x81, 0x05, 0x66, 0x0a, 0xd1, 0x0c, 0xe9, 0x00,
+ 0xf4, 0x02, 0x6c, 0x08, 0xc7, 0x0b, 0xea, 0x0b,
+ 0xa7, 0x06, 0x73, 0x06, 0xe5, 0x0a, 0xfd, 0x06,
+ 0x37, 0x07, 0xb8, 0x03, 0xb5, 0x05, 0x7f, 0x0a,
+ 0xab, 0x03, 0x04, 0x09, 0x85, 0x09, 0x54, 0x09,
+ 0xdd, 0x02, 0x21, 0x09, 0x0c, 0x01, 0x81, 0x02,
+ 0x30, 0x06, 0xfa, 0x08, 0xf5, 0x07, 0x94, 0x0c,
+ 0x77, 0x01, 0xf5, 0x09, 0x2a, 0x08, 0x6d, 0x06,
+ 0x27, 0x04, 0x3f, 0x01, 0xd5, 0x0a, 0xf5, 0x02,
+ 0x33, 0x08, 0x31, 0x02, 0xa2, 0x09, 0x22, 0x0a,
+ 0xf4, 0x0a, 0x44, 0x04, 0x93, 0x01, 0x02, 0x04,
+ 0x77, 0x04, 0x66, 0x08, 0xd7, 0x0a, 0x76, 0x03,
+ 0xba, 0x06, 0xbc, 0x04, 0x52, 0x07, 0x05, 0x04,
+ 0x3e, 0x08, 0x77, 0x0b, 0x75, 0x03, 0x6a, 0x08,
+};
+
+const uint8_t re_mldsa_zeta_tbl[RE_MLDSA_ZETA_LEN] = {
+ 0x01, 0x00, 0x00, 0x00, 0x02, 0x5e, 0x49, 0x00,
+ 0x67, 0x75, 0x39, 0x00, 0x69, 0x65, 0x39, 0x00,
+ 0x2b, 0x06, 0x4f, 0x00, 0x73, 0xdf, 0x53, 0x00,
+ 0x33, 0xe0, 0x4f, 0x00, 0x6b, 0x06, 0x4f, 0x00,
+ 0xae, 0xb1, 0x76, 0x00, 0xd5, 0x0d, 0x36, 0x00,
+ 0xb0, 0xed, 0x28, 0x00, 0xe4, 0x7f, 0x20, 0x00,
+ 0x83, 0x72, 0x39, 0x00, 0x4a, 0x89, 0x70, 0x00,
+ 0x92, 0x81, 0x08, 0x00, 0xc8, 0x3d, 0x6d, 0x00,
+ 0x94, 0x72, 0x4c, 0x00, 0xb4, 0xe0, 0x41, 0x00,
+ 0xd2, 0xa3, 0x28, 0x00, 0x8a, 0x52, 0x66, 0x00,
+ 0xa7, 0x18, 0x4a, 0x00, 0x34, 0x40, 0x79, 0x00,
+ 0xee, 0x52, 0x0a, 0x00, 0x81, 0x7d, 0x6b, 0x00,
+ 0x1d, 0x9f, 0x4e, 0x00, 0x77, 0x28, 0x1a, 0x00,
+ 0xdf, 0x71, 0x25, 0x00, 0xee, 0x49, 0x16, 0x00,
+ 0xbd, 0x11, 0x76, 0x00, 0xb7, 0x2b, 0x49, 0x00,
+ 0x97, 0xf6, 0x2a, 0x00, 0xd5, 0xd8, 0x22, 0x00,
+ 0x2a, 0xf7, 0x36, 0x00, 0x1e, 0x91, 0x30, 0x00,
+ 0x3f, 0xd1, 0x29, 0x00, 0x73, 0x26, 0x49, 0x00,
+ 0x5f, 0x68, 0x50, 0x00, 0xa2, 0x10, 0x20, 0x00,
+ 0xf7, 0x87, 0x38, 0x00, 0xc3, 0xb2, 0x11, 0x00,
+ 0xa4, 0x03, 0x06, 0x00, 0xed, 0x2b, 0x0e, 0x00,
+ 0x2c, 0xb7, 0x10, 0x00, 0x35, 0x5f, 0x4a, 0x00,
+ 0x15, 0x9d, 0x1f, 0x00, 0xd4, 0x8c, 0x42, 0x00,
+ 0xf4, 0x77, 0x31, 0x00, 0x12, 0xe6, 0x20, 0x00,
+ 0x1d, 0x1c, 0x34, 0x00, 0x73, 0xd8, 0x1a, 0x00,
+ 0x81, 0x66, 0x73, 0x00, 0x3f, 0x55, 0x49, 0x00,
+ 0xf6, 0x52, 0x39, 0x00, 0x4a, 0x56, 0x62, 0x00,
+ 0x05, 0xad, 0x65, 0x00, 0x1c, 0x9a, 0x43, 0x00,
+ 0x5f, 0xaa, 0x53, 0x00, 0x22, 0xb6, 0x30, 0x00,
+ 0x38, 0x7f, 0x08, 0x00, 0x6d, 0x0e, 0x3b, 0x00,
+ 0xda, 0x83, 0x2c, 0x00, 0x6e, 0x49, 0x1c, 0x00,
+ 0x2b, 0x0e, 0x33, 0x00, 0x70, 0x5b, 0x1c, 0x00,
+ 0xf1, 0xe3, 0x2e, 0x00, 0xb9, 0x7e, 0x13, 0x00,
+ 0x30, 0xa9, 0x57, 0x00, 0xef, 0xc6, 0x3a, 0x00,
+ 0x4c, 0xd5, 0x3f, 0x00, 0xea, 0xb2, 0x4e, 0x00,
+ 0xe1, 0x3e, 0x50, 0x00, 0x75, 0xb1, 0x7b, 0x00,
+ 0xb4, 0x48, 0x26, 0x00, 0x56, 0xf2, 0x1e, 0x00,
+ 0xa2, 0x90, 0x1d, 0x00, 0xd4, 0xa6, 0x45, 0x00,
+ 0x9b, 0xe5, 0x2a, 0x00, 0x9c, 0x58, 0x52, 0x00,
+ 0xf5, 0xf1, 0x6e, 0x00, 0x88, 0x72, 0x3f, 0x00,
+ 0x02, 0x51, 0x17, 0x00, 0x59, 0x5d, 0x07, 0x00,
+ 0xba, 0x87, 0x11, 0x00, 0xa9, 0xac, 0x52, 0x00,
+ 0x9e, 0x3e, 0x77, 0x00, 0xd8, 0x96, 0x02, 0x00,
+ 0xec, 0x92, 0x25, 0x00, 0x12, 0xff, 0x4c, 0x00,
+ 0xe8, 0x4c, 0x40, 0x00, 0x82, 0xa5, 0x4a, 0x00,
+ 0xe6, 0x54, 0x1e, 0x00, 0xc1, 0x16, 0x4f, 0x00,
+ 0x79, 0x7e, 0x1a, 0x00, 0x8f, 0x97, 0x03, 0x00,
+ 0x17, 0x48, 0x4e, 0x00, 0x59, 0xb8, 0x31, 0x00,
+ 0xcc, 0x84, 0x58, 0x00, 0x27, 0x48, 0x1b, 0x00,
+ 0xd0, 0x63, 0x5b, 0x00, 0x7a, 0x78, 0x5d, 0x00,
+ 0x5e, 0x22, 0x35, 0x00, 0x7e, 0x0c, 0x40, 0x00,
+ 0xd1, 0x09, 0x6c, 0x00, 0x32, 0xd5, 0x5b, 0x00,
+ 0xd3, 0xc4, 0x6b, 0x00, 0xcb, 0x8e, 0x25, 0x00,
+ 0x4c, 0x53, 0x2e, 0x00, 0x6c, 0x7a, 0x09, 0x00,
+ 0x20, 0x88, 0x3b, 0x00, 0x5c, 0x28, 0x6d, 0x00,
+ 0xf8, 0xa4, 0x2c, 0x00, 0xaa, 0x7c, 0x33, 0x00,
+ 0xa0, 0xb2, 0x14, 0x00, 0x36, 0x85, 0x55, 0x00,
+ 0x86, 0xf1, 0x28, 0x00, 0x5d, 0x79, 0x55, 0x00,
+ 0x70, 0xf6, 0x4a, 0x00, 0x86, 0x4a, 0x23, 0x00,
+ 0x26, 0xe8, 0x75, 0x00, 0x66, 0xde, 0x78, 0x00,
+ 0x8c, 0x52, 0x05, 0x00, 0x59, 0xdf, 0x7a, 0x00,
+ 0x17, 0x6e, 0x0f, 0x00, 0xda, 0xf3, 0x5b, 0x00,
+ 0x7e, 0x9b, 0x45, 0x00, 0x34, 0x8b, 0x62, 0x00,
+ 0xcb, 0xbe, 0x5d, 0x00, 0x7b, 0x9e, 0x1a, 0x00,
+ 0xd9, 0x06, 0x00, 0x00, 0xc5, 0x57, 0x62, 0x00,
+ 0x3c, 0x4b, 0x57, 0x00, 0xef, 0xa8, 0x69, 0x00,
+ 0x38, 0x98, 0x28, 0x00, 0xfe, 0xb5, 0x64, 0x00,
+ 0xf5, 0xf8, 0x7e, 0x00, 0x78, 0x4e, 0x2a, 0x00,
+ 0x23, 0x0a, 0x12, 0x00, 0xa8, 0x54, 0x01, 0x00,
+ 0xff, 0xb7, 0x09, 0x00, 0x87, 0x5e, 0x43, 0x00,
+ 0xf8, 0x7f, 0x43, 0x00, 0xb4, 0xd5, 0x5c, 0x00,
+ 0x4e, 0xc0, 0x4d, 0x00, 0xaf, 0x28, 0x47, 0x00,
+ 0x5d, 0x73, 0x7f, 0x00, 0x0d, 0x8d, 0x0c, 0x00,
+ 0xd5, 0x66, 0x0f, 0x00, 0x80, 0x6d, 0x5a, 0x00,
+ 0x98, 0xab, 0x61, 0x00, 0x96, 0x5d, 0x18, 0x00,
+ 0x31, 0x7f, 0x43, 0x00, 0x98, 0x82, 0x46, 0x00,
+ 0x60, 0x29, 0x66, 0x00, 0x79, 0xd5, 0x4b, 0x00,
+ 0x06, 0xde, 0x28, 0x00, 0x8d, 0x5d, 0x46, 0x00,
+ 0xe3, 0xb0, 0x49, 0x00, 0x34, 0xb4, 0x09, 0x00,
+ 0xb3, 0x0d, 0x7c, 0x00, 0xb0, 0x68, 0x5a, 0x00,
+ 0xa9, 0x9b, 0x40, 0x00, 0xd5, 0xd3, 0x64, 0x00,
+ 0x2a, 0x76, 0x21, 0x00, 0x91, 0x85, 0x65, 0x00,
+ 0x39, 0x6e, 0x24, 0x00, 0x9b, 0xc3, 0x48, 0x00,
+ 0x59, 0xc7, 0x7b, 0x00, 0x59, 0x58, 0x4f, 0x00,
+ 0xb2, 0x2d, 0x39, 0x00, 0x23, 0x09, 0x23, 0x00,
+ 0x67, 0xeb, 0x12, 0x00, 0xf2, 0x4d, 0x45, 0x00,
+ 0x1c, 0xc3, 0x30, 0x00, 0x24, 0x54, 0x28, 0x00,
+ 0x2e, 0x23, 0x13, 0x00, 0x80, 0xaf, 0x7f, 0x00,
+ 0xcb, 0xbf, 0x2d, 0x00, 0x0b, 0x2a, 0x02, 0x00,
+ 0x2c, 0x83, 0x7e, 0x00, 0x7a, 0x58, 0x26, 0x00,
+ 0x75, 0x33, 0x6b, 0x00, 0x76, 0x5b, 0x09, 0x00,
+ 0xcc, 0xe1, 0x6b, 0x00, 0x1e, 0x06, 0x5e, 0x00,
+ 0x0d, 0xe0, 0x78, 0x00, 0x37, 0x8c, 0x62, 0x00,
+ 0x04, 0xa6, 0x3d, 0x00, 0x3c, 0xe5, 0x4a, 0x00,
+ 0x68, 0x1d, 0x1f, 0x00, 0xbb, 0x30, 0x63, 0x00,
+ 0xb8, 0x61, 0x73, 0x00, 0x6c, 0xa0, 0x5e, 0x00,
+ 0xc7, 0x1a, 0x67, 0x00, 0xc6, 0x1f, 0x20, 0x00,
+ 0xff, 0xa4, 0x5b, 0x00, 0x72, 0xd7, 0x60, 0x00,
+ 0x01, 0xf2, 0x08, 0x00, 0x24, 0xe0, 0x6d, 0x00,
+ 0x6d, 0x0e, 0x08, 0x00, 0x8e, 0x03, 0x56, 0x00,
+ 0x88, 0x56, 0x69, 0x00, 0x3e, 0x6d, 0x1e, 0x00,
+ 0xbd, 0x03, 0x26, 0x00, 0xfa, 0x9d, 0x6a, 0x00,
+ 0x17, 0xc0, 0x07, 0x00, 0xd4, 0xbf, 0x6d, 0x00,
+ 0xbd, 0xd0, 0x74, 0x00, 0xe3, 0xe1, 0x63, 0x00,
+ 0x73, 0x95, 0x51, 0x00, 0x0d, 0xb6, 0x7a, 0x00,
+ 0xba, 0x67, 0x28, 0x00, 0xd4, 0xec, 0x2d, 0x00,
+ 0x8c, 0x01, 0x58, 0x00, 0xf5, 0x4c, 0x3f, 0x00,
+ 0x09, 0x70, 0x0b, 0x00, 0x23, 0x7e, 0x42, 0x00,
+ 0x37, 0xbd, 0x3c, 0x00, 0x33, 0x33, 0x27, 0x00,
+ 0x57, 0x39, 0x67, 0x00, 0x5d, 0x4b, 0x1a, 0x00,
+ 0x26, 0x69, 0x19, 0x00, 0x06, 0xf2, 0x1e, 0x00,
+ 0x4e, 0xc1, 0x11, 0x00, 0xc8, 0x76, 0x4c, 0x00,
+ 0x2f, 0xf4, 0x3c, 0x00, 0x9a, 0xb1, 0x7f, 0x00,
+ 0x6c, 0xf6, 0x6a, 0x00, 0x69, 0x16, 0x2e, 0x00,
+ 0xd6, 0x52, 0x33, 0x00, 0x60, 0x47, 0x03, 0x00,
+ 0x60, 0x52, 0x08, 0x00, 0x78, 0x1e, 0x74, 0x00,
+ 0x16, 0x63, 0x2f, 0x00, 0x11, 0x0a, 0x6f, 0x00,
+ 0xf1, 0xc0, 0x07, 0x00, 0x0b, 0x6d, 0x77, 0x00,
+ 0xf0, 0x1f, 0x0d, 0x00, 0x24, 0x58, 0x34, 0x00,
+ 0xd4, 0x23, 0x02, 0x00, 0x59, 0xc5, 0x68, 0x00,
+ 0x85, 0x88, 0x5e, 0x00, 0x32, 0xaa, 0x2f, 0x00,
+ 0x65, 0xfc, 0x23, 0x00, 0x42, 0x69, 0x5e, 0x00,
+ 0xed, 0xe0, 0x51, 0x00, 0xb3, 0xad, 0x65, 0x00,
+ 0xe6, 0xa5, 0x2c, 0x00, 0xfe, 0xe1, 0x79, 0x00,
+ 0x64, 0x40, 0x7b, 0x00, 0xdd, 0xe1, 0x35, 0x00,
+ 0xac, 0x3a, 0x43, 0x00, 0xde, 0x4a, 0x46, 0x00,
+ 0x14, 0xfe, 0x1c, 0x00, 0xce, 0xf1, 0x73, 0x00,
+ 0x0e, 0x17, 0x10, 0x00, 0xd7, 0xb6, 0x74, 0x00,
+};
+
+const struct re_ml_entry re_ml_zeta_tbl[2] = {
+ {
+ .data = re_mlkem_zeta_tbl,
+ .len = sizeof(re_mlkem_zeta_tbl)
+ },
+ {
+ .data = re_mldsa_zeta_tbl,
+ .len = sizeof(re_mldsa_zeta_tbl)
+ }
+};
+
+int
+roc_re_ml_zeta_get(uint64_t *tbl)
+{
+ int len = (RE_MLKEM_ZETA_LEN + RE_MLDSA_ZETA_LEN);
+ const char name[] = RE_ML_TBL_NAME;
+ const struct plt_memzone *mz;
+ struct re_ml_tbl *ml;
+ uint8_t *data;
+
+ if (tbl == NULL)
+ return -EINVAL;
+
+ mz = plt_memzone_lookup(name);
+ if (mz == NULL) {
+ /* Create memzone first time */
+ mz = plt_memzone_reserve_cache_align(name, sizeof(struct re_ml_tbl) + len);
+ if (mz == NULL)
+ return -ENOMEM;
+ }
+
+ ml = (struct re_ml_tbl *)mz->addr;
+ if (plt_atomic_fetch_add_explicit(&ml->refcount, 1, plt_memory_order_seq_cst) != 0)
+ return 0;
+
+ data = PLT_PTR_ADD(mz->addr, sizeof(uint64_t));
+ memcpy(data, re_ml_zeta_tbl[0].data, re_ml_zeta_tbl[0].len);
+ tbl[0] = plt_cpu_to_be_64((uintptr_t)data);
+
+ data = PLT_PTR_ADD(data, re_ml_zeta_tbl[0].len);
+ memcpy(data, re_ml_zeta_tbl[1].data, re_ml_zeta_tbl[1].len);
+ tbl[1] = plt_cpu_to_be_64((uintptr_t)data);
+
+ return 0;
+}
+
+void
+roc_re_ml_zeta_put(void)
+{
+ const char name[] = RE_ML_TBL_NAME;
+ const struct plt_memzone *mz;
+ struct re_ml_tbl *ml;
+
+ mz = plt_memzone_lookup(name);
+ if (mz == NULL)
+ return;
+
+ ml = (struct re_ml_tbl *)mz->addr;
+ if (plt_atomic_fetch_sub_explicit(&ml->refcount, 1, plt_memory_order_seq_cst) == 1)
+ plt_memzone_free(mz);
+}
diff --git a/drivers/common/cnxk/roc_re_ml_tables.h b/drivers/common/cnxk/roc_re_ml_tables.h
new file mode 100644
index 0000000000..0a425f711d
--- /dev/null
+++ b/drivers/common/cnxk/roc_re_ml_tables.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2026 Marvell.
+ */
+
+#ifndef _ROC_RE_ML_TABLES_H_
+#define _ROC_RE_ML_TABLES_H_
+
+#include "roc_platform.h"
+
+enum roc_re_ml_zeta_idx {
+ ROC_RE_ML_ZETA_IDX_KEM = 0,
+ ROC_RE_ML_ZETA_IDX_DSA,
+ ROC_RE_ML_ZETA_IDX_MAX
+};
+
+int __roc_api roc_re_ml_zeta_get(uint64_t *tbl);
+void __roc_api roc_re_ml_zeta_put(void);
+
+#endif /* _ROC_RE_ML_TABLES_H_ */
diff --git a/drivers/crypto/cnxk/cnxk_ae.h b/drivers/crypto/cnxk/cnxk_ae.h
index 21a0c8068a..691f9bfce5 100644
--- a/drivers/crypto/cnxk/cnxk_ae.h
+++ b/drivers/crypto/cnxk/cnxk_ae.h
@@ -10,6 +10,7 @@
#include <rte_malloc.h>
#include "roc_ae.h"
+#include "roc_re.h"
#include "cnxk_cryptodev_ops.h"
@@ -24,8 +25,11 @@ struct cnxk_ae_sess {
struct rte_crypto_rsa_xform rsa_ctx;
struct rte_crypto_modex_xform mod_ctx;
struct roc_ae_ec_ctx ec_ctx;
+ struct rte_crypto_ml_kem_xform ml_kem_ctx;
+ struct rte_crypto_ml_dsa_xform ml_dsa_ctx;
};
uint64_t *cnxk_fpm_iova;
+ uint64_t *cnxk_ml_iova;
struct roc_ae_ec_group **ec_grp;
uint64_t cpt_inst_w4;
uint64_t cpt_inst_w7;
@@ -52,6 +56,15 @@ struct cnxk_ae_sess {
} hw_ctx __plt_aligned(ROC_ALIGN);
};
+static const uint8_t mldsa_hash_algo[] = {
+ [RTE_CRYPTO_AUTH_SHA3_224] = 0xA,
+ [RTE_CRYPTO_AUTH_SHA3_256] = 0xB,
+ [RTE_CRYPTO_AUTH_SHA3_384] = 0xC,
+ [RTE_CRYPTO_AUTH_SHA3_512] = 0xD,
+ [RTE_CRYPTO_AUTH_SHAKE_128] = 0xE,
+ [RTE_CRYPTO_AUTH_SHAKE_256] = 0xF,
+};
+
static __rte_always_inline void
cnxk_ae_modex_param_normalize(uint8_t **data, size_t *len, size_t max)
{
@@ -259,6 +272,32 @@ cnxk_ae_fill_ec_params(struct cnxk_ae_sess *sess, struct rte_crypto_asym_xform *
return 0;
}
+static __rte_always_inline int
+cnxk_ae_fill_ml_kem_params(struct cnxk_ae_sess *sess,
+ struct rte_crypto_asym_xform *xform)
+{
+ struct rte_crypto_ml_kem_xform *ml_kem = &sess->ml_kem_ctx;
+ if (xform->mlkem.type == RTE_CRYPTO_ML_KEM_NONE)
+ return -EINVAL;
+
+ ml_kem->type = xform->mlkem.type;
+ return 0;
+}
+
+static __rte_always_inline int
+cnxk_ae_fill_ml_dsa_params(struct cnxk_ae_sess *sess,
+ struct rte_crypto_asym_xform *xform)
+{
+ struct rte_crypto_ml_dsa_xform *ml_dsa = &sess->ml_dsa_ctx;
+ if (xform->mldsa.type == RTE_CRYPTO_ML_DSA_NONE)
+ return -EINVAL;
+
+ ml_dsa->type = xform->mldsa.type;
+ ml_dsa->sign_deterministic = xform->mldsa.sign_deterministic;
+ ml_dsa->sign_prehash = xform->mldsa.sign_prehash;
+ return 0;
+}
+
static __rte_always_inline int
cnxk_ae_fill_session_parameters(struct cnxk_ae_sess *sess,
struct rte_crypto_asym_xform *xform)
@@ -284,6 +323,12 @@ cnxk_ae_fill_session_parameters(struct cnxk_ae_sess *sess,
case RTE_CRYPTO_ASYM_XFORM_EDDSA:
ret = cnxk_ae_fill_ec_params(sess, xform);
break;
+ case RTE_CRYPTO_ASYM_XFORM_ML_KEM:
+ ret = cnxk_ae_fill_ml_kem_params(sess, xform);
+ break;
+ case RTE_CRYPTO_ASYM_XFORM_ML_DSA:
+ ret = cnxk_ae_fill_ml_dsa_params(sess, xform);
+ break;
default:
return -ENOTSUP;
}
@@ -563,6 +608,280 @@ cnxk_ae_enqueue_rsa_op(struct rte_crypto_op *op, struct roc_ae_buf_ptr *meta_buf
return 0;
}
+static __rte_always_inline int __rte_hot
+cnxk_ae_enqueue_ml_kem_op(struct rte_crypto_op *op, struct roc_ae_buf_ptr *meta_buf,
+ struct cnxk_ae_sess *sess, struct cpt_inst_s *inst)
+{
+ size_t metabuf_len = cnxk_cpt_asym_get_mlen(), reqbuf_len;
+ struct rte_crypto_ml_kem_op *mlkem = &op->asym->mlkem;
+ union cpt_inst_w4 w4;
+ uint32_t dlen = 0;
+ uint16_t param2;
+ uint8_t *dptr;
+
+ /* Input buffer */
+ dptr = meta_buf->vaddr;
+ inst->dptr = (uintptr_t)dptr;
+
+ switch (mlkem->op) {
+ case RTE_CRYPTO_ML_KEM_OP_KEYGEN:
+ reqbuf_len = mlkem->keygen.d.length + mlkem->keygen.z.length;
+ if (reqbuf_len > (metabuf_len - dlen)) {
+ op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+ return -ENOMEM;
+ }
+
+ memcpy(dptr, mlkem->keygen.d.data, mlkem->keygen.d.length);
+ dptr += mlkem->keygen.d.length;
+ memcpy(dptr, mlkem->keygen.z.data, mlkem->keygen.z.length);
+ dptr += mlkem->keygen.z.length;
+
+ dlen = mlkem->keygen.d.length + mlkem->keygen.z.length;
+ w4.s.opcode_major = ROC_RE_MAJOR_OP_MLKEM;
+ w4.s.opcode_minor = ROC_RE_MINOR_OP_MLKEM_KEYGEN;
+ param2 = sess->ml_kem_ctx.type;
+ param2 |= (!!dlen << ROC_RE_ML_KEM_PARAM2_INSEED_BIT);
+ break;
+ case RTE_CRYPTO_ML_KEM_OP_ENCAP:
+ reqbuf_len = mlkem->encap.message.length + mlkem->encap.ek.length;
+ if (reqbuf_len > (metabuf_len - dlen)) {
+ op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+ return -ENOMEM;
+ }
+
+ memcpy(dptr, mlkem->encap.message.data, mlkem->encap.message.length);
+ dptr += mlkem->encap.message.length;
+ memcpy(dptr, mlkem->encap.ek.data, mlkem->encap.ek.length);
+ dptr += mlkem->encap.ek.length;
+
+ dlen = mlkem->encap.message.length + mlkem->encap.ek.length;
+ w4.s.opcode_major = ROC_RE_MAJOR_OP_MLKEM;
+ w4.s.opcode_minor = ROC_RE_MINOR_OP_MLKEM_ENCAP;
+ param2 = sess->ml_kem_ctx.type;
+ param2 |= (!!mlkem->encap.message.length << ROC_RE_ML_KEM_PARAM2_INMSG_BIT);
+ break;
+ case RTE_CRYPTO_ML_KEM_OP_DECAP:
+ reqbuf_len = mlkem->decap.dk.length + mlkem->decap.cipher.length;
+ if (reqbuf_len > (metabuf_len - dlen)) {
+ op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+ return -ENOMEM;
+ }
+
+ memcpy(dptr, mlkem->decap.dk.data, mlkem->decap.dk.length);
+ dptr += mlkem->decap.dk.length;
+ memcpy(dptr, mlkem->decap.cipher.data, mlkem->decap.cipher.length);
+ dptr += mlkem->decap.cipher.length;
+
+ dlen = mlkem->decap.cipher.length + mlkem->decap.dk.length;
+ w4.s.opcode_major = ROC_RE_MAJOR_OP_MLKEM;
+ w4.s.opcode_minor = ROC_RE_MINOR_OP_MLKEM_DECAP;
+ param2 = sess->ml_kem_ctx.type;
+ break;
+ default:
+ op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+ return -EINVAL;
+ }
+
+ w4.s.param1 = 0;
+ w4.s.param2 = param2;
+ w4.s.dlen = dlen;
+
+ inst->w4.u64 = w4.u64;
+
+ /* Reuse entire space of meta buffer as output is large in PQC */
+ inst->rptr = (uintptr_t)meta_buf->vaddr;
+
+ return 0;
+}
+
+static __rte_always_inline int __rte_hot
+cnxk_ae_enqueue_ml_dsa_op(struct rte_crypto_op *op, struct roc_ae_buf_ptr *meta_buf,
+ struct cnxk_ae_sess *sess, struct cpt_inst_s *inst)
+{
+ size_t metabuf_len = cnxk_cpt_asym_get_mlen(), reqbuf_len;
+ struct rte_crypto_ml_dsa_op *mldsa = &op->asym->mldsa;
+ enum rte_crypto_auth_algorithm hash;
+ bool sign_deterministic;
+ union cpt_inst_w4 w4;
+ uint16_t param1 = 0;
+ uint32_t dlen = 0;
+ uint16_t param2;
+ uint8_t *dptr;
+ uint8_t minor;
+
+ /* Input buffer */
+ dptr = meta_buf->vaddr;
+ inst->dptr = (uintptr_t)dptr;
+
+ switch (mldsa->op) {
+ case RTE_CRYPTO_ML_DSA_OP_KEYGEN:
+ reqbuf_len = mldsa->keygen.seed.length;
+ if (reqbuf_len > (metabuf_len - dlen)) {
+ op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+ return -ENOMEM;
+ }
+
+ param2 = sess->ml_dsa_ctx.type;
+
+ memcpy(dptr, mldsa->keygen.seed.data, mldsa->keygen.seed.length);
+ dptr += mldsa->keygen.seed.length;
+ param2 |= (!!mldsa->keygen.seed.length << ROC_RE_ML_DSA_PARAM2_SEED_BIT);
+
+ dlen += mldsa->keygen.seed.length;
+ w4.s.opcode_major = ROC_RE_MAJOR_OP_MLDSA;
+ w4.s.opcode_minor = ROC_RE_MINOR_OP_MLDSA_KEYGEN;
+ break;
+ case RTE_CRYPTO_ML_DSA_OP_SIGN:
+ reqbuf_len = mldsa->siggen.message.length + mldsa->siggen.privkey.length +
+ mldsa->siggen.ctx.length + mldsa->siggen.mu.length +
+ mldsa->siggen.seed.length;
+
+ if (reqbuf_len > (metabuf_len - dlen)) {
+ op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+ return -ENOMEM;
+ }
+
+ sign_deterministic = sess->ml_dsa_ctx.sign_deterministic;
+ hash = op->asym->mldsa.siggen.hash;
+ minor = ROC_RE_MINOR_OP_MLDSA_SIGN;
+
+ param1 = mldsa->siggen.message.length;
+ param2 = sess->ml_dsa_ctx.type;
+ if (hash == 0) {
+ minor |= (0 << ROC_RE_ML_DSA_MINOR_MSG_TYPE_BIT);
+ } else if (mldsa->siggen.mu.length != 0) {
+ minor |= (3 << ROC_RE_ML_DSA_MINOR_MSG_TYPE_BIT);
+ } else {
+ if (!sess->ml_dsa_ctx.sign_prehash ||
+ hash >= RTE_DIM(mldsa_hash_algo) || mldsa_hash_algo[hash] == 0) {
+ op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+ return -EINVAL;
+ }
+
+ minor |= (1 << ROC_RE_ML_DSA_MINOR_MSG_TYPE_BIT);
+ param2 |= (mldsa_hash_algo[hash] << ROC_RE_ML_DSA_PARAM2_SIGN_BIT);
+ }
+
+ minor |= ((sign_deterministic ? 0 : 2) << ROC_RE_ML_DSA_MINOR_SIGN_TYPE_BIT);
+
+ if (!sign_deterministic) {
+ if (!mldsa->siggen.seed.length) {
+ op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+ return -EINVAL;
+ }
+
+ memcpy(dptr, mldsa->siggen.seed.data, mldsa->siggen.seed.length);
+ dptr += mldsa->siggen.seed.length;
+ dlen += mldsa->siggen.seed.length;
+ }
+
+ memcpy(dptr, mldsa->siggen.privkey.data, mldsa->siggen.privkey.length);
+ dptr += mldsa->siggen.privkey.length;
+ dlen += mldsa->siggen.privkey.length;
+
+ memcpy(dptr, mldsa->siggen.ctx.data, mldsa->siggen.ctx.length);
+ dptr += mldsa->siggen.ctx.length;
+ dlen += mldsa->siggen.ctx.length;
+ if (mldsa->siggen.ctx.length > (UINT16_MAX >> ROC_RE_ML_DSA_PARAM2_CTXN_BIT)) {
+ op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+ return -EINVAL;
+ }
+ param2 |= ((uint16_t)mldsa->siggen.ctx.length
+ << ROC_RE_ML_DSA_PARAM2_CTXN_BIT);
+
+ if (mldsa->siggen.mu.length != 0) {
+ memcpy(dptr, mldsa->siggen.mu.data, mldsa->siggen.mu.length);
+ dptr += mldsa->siggen.mu.length;
+ dlen += mldsa->siggen.mu.length;
+ param1 = mldsa->siggen.mu.length;
+ } else if (mldsa->siggen.message.length != 0) {
+ memcpy(dptr, mldsa->siggen.message.data, mldsa->siggen.message.length);
+ dptr += mldsa->siggen.message.length;
+ dlen += mldsa->siggen.message.length;
+ }
+
+ w4.s.opcode_major = ROC_RE_MAJOR_OP_MLDSA;
+ w4.s.opcode_minor = minor;
+ break;
+ case RTE_CRYPTO_ML_DSA_OP_VERIFY:
+ reqbuf_len = mldsa->sigver.message.length + mldsa->sigver.pubkey.length +
+ mldsa->sigver.ctx.length + mldsa->sigver.mu.length +
+ mldsa->sigver.sign.length;
+
+ if (reqbuf_len > (metabuf_len - dlen)) {
+ op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+ return -ENOMEM;
+ }
+
+ hash = op->asym->mldsa.sigver.hash;
+ minor = ROC_RE_MINOR_OP_MLDSA_VERIFY;
+
+ param1 = mldsa->sigver.message.length;
+ param2 = sess->ml_dsa_ctx.type;
+ if (hash == 0) {
+ minor |= (0 << ROC_RE_ML_DSA_MINOR_MSG_TYPE_BIT);
+ } else if (mldsa->sigver.mu.length != 0) {
+ minor |= (3 << ROC_RE_ML_DSA_MINOR_MSG_TYPE_BIT);
+ } else {
+ if (!sess->ml_dsa_ctx.sign_prehash ||
+ hash >= RTE_DIM(mldsa_hash_algo) || mldsa_hash_algo[hash] == 0) {
+ op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+ return -EINVAL;
+ }
+
+ minor |= (1 << ROC_RE_ML_DSA_MINOR_MSG_TYPE_BIT);
+ param2 |= (mldsa_hash_algo[hash] << ROC_RE_ML_DSA_PARAM2_SIGN_BIT);
+ }
+
+ memcpy(dptr, mldsa->sigver.pubkey.data, mldsa->sigver.pubkey.length);
+ dptr += mldsa->sigver.pubkey.length;
+ dlen += mldsa->sigver.pubkey.length;
+
+ memcpy(dptr, mldsa->sigver.ctx.data, mldsa->sigver.ctx.length);
+ dptr += mldsa->sigver.ctx.length;
+ dlen += mldsa->sigver.ctx.length;
+ if (mldsa->sigver.ctx.length > (UINT16_MAX >> ROC_RE_ML_DSA_PARAM2_CTXN_BIT)) {
+ op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+ return -EINVAL;
+ }
+ param2 |= ((uint16_t)mldsa->sigver.ctx.length
+ << ROC_RE_ML_DSA_PARAM2_CTXN_BIT);
+
+ if (mldsa->sigver.mu.length != 0) {
+ memcpy(dptr, mldsa->sigver.mu.data, mldsa->sigver.mu.length);
+ dptr += mldsa->sigver.mu.length;
+ dlen += mldsa->sigver.mu.length;
+ param1 = mldsa->sigver.mu.length;
+ } else if (mldsa->sigver.message.length != 0) {
+ memcpy(dptr, mldsa->sigver.message.data, mldsa->sigver.message.length);
+ dptr += mldsa->sigver.message.length;
+ dlen += mldsa->sigver.message.length;
+ }
+
+ memcpy(dptr, mldsa->sigver.sign.data, mldsa->sigver.sign.length);
+ dptr += mldsa->sigver.sign.length;
+ dlen += mldsa->sigver.sign.length;
+
+ w4.s.opcode_major = ROC_RE_MAJOR_OP_MLDSA;
+ w4.s.opcode_minor = minor;
+ break;
+ default:
+ op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+ return -EINVAL;
+ }
+
+ w4.s.param1 = param1;
+ w4.s.param2 = param2;
+ w4.s.dlen = dlen;
+
+ inst->w4.u64 = w4.u64;
+
+ /* Reuse entire space of meta buffer as output is large in PQC */
+ inst->rptr = (uintptr_t)meta_buf->vaddr;
+
+ return 0;
+}
+
static __rte_always_inline void
cnxk_ae_ecdsa_sign_prep(struct rte_crypto_ecdsa_op_param *ecdsa,
struct roc_ae_buf_ptr *meta_buf,
@@ -1712,6 +2031,55 @@ cnxk_ae_dequeue_ecdh_op(struct rte_crypto_ecdh_op_param *ecdh, uint8_t *rptr,
}
}
+static __rte_always_inline void
+cnxk_ae_dequeue_mlkem_op(struct rte_crypto_ml_kem_op *mlkem, uint8_t *rptr,
+ enum rte_crypto_ml_kem_type type)
+{
+ switch (mlkem->op) {
+ case RTE_CRYPTO_ML_KEM_OP_KEYGEN:
+ mlkem->keygen.dk.length = rte_crypto_ml_kem_privkey_size[type];
+ memcpy(mlkem->keygen.dk.data, rptr, mlkem->keygen.dk.length);
+ mlkem->keygen.ek.length = rte_crypto_ml_kem_pubkey_size[type];
+ memcpy(mlkem->keygen.ek.data, rptr + 384 * (type + 1), mlkem->keygen.ek.length);
+ break;
+ case RTE_CRYPTO_ML_KEM_OP_ENCAP:
+ mlkem->encap.sk.length = 32;
+ memcpy(mlkem->encap.sk.data, rptr, mlkem->encap.sk.length);
+ mlkem->encap.cipher.length = rte_crypto_ml_kem_cipher_size[type];
+ memcpy(mlkem->encap.cipher.data, rptr + 32, mlkem->encap.cipher.length);
+ break;
+ case RTE_CRYPTO_ML_KEM_OP_DECAP:
+ mlkem->decap.sk.length = 32;
+ memcpy(mlkem->decap.sk.data, rptr, mlkem->decap.sk.length);
+ break;
+ default:
+ break;
+ }
+}
+
+static __rte_always_inline void
+cnxk_ae_dequeue_mldsa_op(struct rte_crypto_ml_dsa_op *mldsa, uint8_t *rptr,
+ enum rte_crypto_ml_dsa_type type)
+{
+ switch (mldsa->op) {
+ case RTE_CRYPTO_ML_DSA_OP_KEYGEN:
+ mldsa->keygen.pubkey.length = rte_crypto_ml_dsa_pubkey_size[type];
+ memcpy(mldsa->keygen.pubkey.data, rptr, mldsa->keygen.pubkey.length);
+ mldsa->keygen.privkey.length = rte_crypto_ml_dsa_privkey_size[type];
+ memcpy(mldsa->keygen.privkey.data, rptr + mldsa->keygen.pubkey.length,
+ mldsa->keygen.privkey.length);
+ break;
+ case RTE_CRYPTO_ML_DSA_OP_SIGN:
+ mldsa->siggen.sign.length = rte_crypto_ml_dsa_sign_size[type];
+ memcpy(mldsa->siggen.sign.data, rptr, mldsa->siggen.sign.length);
+ break;
+ case RTE_CRYPTO_ML_DSA_OP_VERIFY:
+ break;
+ default:
+ break;
+ }
+}
+
static __rte_always_inline void *
cnxk_ae_alloc_meta(struct roc_ae_buf_ptr *buf,
struct rte_mempool *cpt_meta_pool,
@@ -1752,56 +2120,46 @@ cnxk_ae_enqueue(struct cnxk_cpt_qp *qp, struct rte_crypto_op *op,
switch (sess->xfrm_type) {
case RTE_CRYPTO_ASYM_XFORM_MODEX:
ret = cnxk_ae_modex_prep(op, &meta_buf, &sess->mod_ctx, inst);
- if (unlikely(ret))
- goto req_fail;
break;
case RTE_CRYPTO_ASYM_XFORM_RSA:
ret = cnxk_ae_enqueue_rsa_op(op, &meta_buf, sess, inst);
- if (unlikely(ret))
- goto req_fail;
break;
case RTE_CRYPTO_ASYM_XFORM_ECDSA:
ret = cnxk_ae_enqueue_ecdsa_op(op, &meta_buf, sess,
sess->cnxk_fpm_iova,
sess->ec_grp, inst);
- if (unlikely(ret))
- goto req_fail;
break;
case RTE_CRYPTO_ASYM_XFORM_EDDSA:
ret = cnxk_ae_enqueue_eddsa_op(op, &meta_buf, sess,
sess->cnxk_fpm_iova,
sess->ec_grp, inst);
- if (unlikely(ret))
- goto req_fail;
break;
case RTE_CRYPTO_ASYM_XFORM_SM2:
ret = cnxk_ae_enqueue_sm2_op(op, &meta_buf, sess,
sess->cnxk_fpm_iova,
sess->ec_grp, inst);
- if (unlikely(ret))
- goto req_fail;
break;
case RTE_CRYPTO_ASYM_XFORM_ECPM:
ret = cnxk_ae_ecpm_prep(&asym_op->ecpm.scalar, &asym_op->ecpm.p, &meta_buf,
sess->ec_grp[sess->ec_ctx.curveid],
sess->ec_ctx.curveid, inst);
- if (unlikely(ret))
- goto req_fail;
break;
case RTE_CRYPTO_ASYM_XFORM_ECFPM:
ret = cnxk_ae_ecfpm_prep(&asym_op->ecpm.scalar, &meta_buf,
sess->cnxk_fpm_iova,
sess->ec_grp[sess->ec_ctx.curveid],
sess->ec_ctx.curveid, inst);
- if (unlikely(ret))
- goto req_fail;
break;
case RTE_CRYPTO_ASYM_XFORM_ECDH:
ret = cnxk_ae_enqueue_ecdh_op(op, &meta_buf, sess,
sess->cnxk_fpm_iova,
sess->ec_grp, inst);
- if (unlikely(ret))
- goto req_fail;
+ break;
+ case RTE_CRYPTO_ASYM_XFORM_ML_KEM:
+ ret = cnxk_ae_enqueue_ml_kem_op(op, &meta_buf, sess, inst);
+ break;
+ case RTE_CRYPTO_ASYM_XFORM_ML_DSA:
+ ret = cnxk_ae_enqueue_ml_dsa_op(op, &meta_buf, sess, inst);
break;
default:
op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
@@ -1809,6 +2167,9 @@ cnxk_ae_enqueue(struct cnxk_cpt_qp *qp, struct rte_crypto_op *op,
goto req_fail;
}
+ if (unlikely(ret))
+ goto req_fail;
+
mop = mdata;
mop[0] = inst->rptr;
return 0;
@@ -1852,6 +2213,12 @@ cnxk_ae_post_process(struct rte_crypto_op *cop, struct cnxk_ae_sess *sess,
cnxk_ae_dequeue_ecdh_op(&op->ecdh, rptr, &sess->ec_ctx,
sess->ec_grp, op->flags);
break;
+ case RTE_CRYPTO_ASYM_XFORM_ML_KEM:
+ cnxk_ae_dequeue_mlkem_op(&op->mlkem, rptr, sess->ml_kem_ctx.type);
+ break;
+ case RTE_CRYPTO_ASYM_XFORM_ML_DSA:
+ cnxk_ae_dequeue_mldsa_op(&op->mldsa, rptr, sess->ml_dsa_ctx.type);
+ break;
default:
cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
break;
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev.c b/drivers/crypto/cnxk/cnxk_cryptodev.c
index 5828a502e4..de27c4a580 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev.c
+++ b/drivers/crypto/cnxk/cnxk_cryptodev.c
@@ -28,6 +28,9 @@ cnxk_cpt_default_ff_get(void)
if (roc_model_is_cn10ka_b0() || roc_model_is_cn10kb() || roc_model_is_cn20k())
ff |= RTE_CRYPTODEV_FF_SECURITY_RX_INJECT;
+ if (roc_model_is_cn20k())
+ ff |= RTE_CRYPTODEV_FF_MLDSA_SIGN_PREHASH;
+
return ff;
}
@@ -56,6 +59,14 @@ cnxk_cpt_eng_grp_add(struct roc_cpt *roc_cpt)
return -ENOTSUP;
}
+ if (roc_model_is_cn20k()) {
+ ret = roc_cpt_eng_grp_add(roc_cpt, CPT_ENG_TYPE_RE);
+ if (ret < 0) {
+ plt_err("Could not add CPT RE engines");
+ return ret;
+ }
+ }
+
return 0;
}
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev.h b/drivers/crypto/cnxk/cnxk_cryptodev.h
index f88162ad3c..bdc5752905 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev.h
+++ b/drivers/crypto/cnxk/cnxk_cryptodev.h
@@ -10,8 +10,9 @@
#include "roc_ae.h"
#include "roc_cpt.h"
+#include "roc_re_ml_tables.h"
-#define CNXK_CPT_MAX_CAPS 60
+#define CNXK_CPT_MAX_CAPS 62
#define CNXK_SEC_IPSEC_CRYPTO_MAX_CAPS 16
#define CNXK_SEC_TLS_1_3_CRYPTO_MAX_CAPS 3
#define CNXK_SEC_TLS_1_2_CRYPTO_MAX_CAPS 7
@@ -33,6 +34,7 @@ struct cnxk_cpt_vf {
sec_dtls_1_2_crypto_caps[CNXK_SEC_TLS_1_2_CRYPTO_MAX_CAPS];
struct rte_security_capability sec_caps[CNXK_SEC_MAX_CAPS];
uint64_t cnxk_fpm_iova[ROC_AE_EC_ID_PMAX];
+ uint64_t cnxk_ml_iova[ROC_RE_ML_ZETA_IDX_MAX];
struct roc_ae_ec_group *ec_grp[ROC_AE_EC_ID_PMAX];
uint16_t max_qps_limit;
uint16_t rx_inject_qp;
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c b/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
index be6d383717..736d588bde 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
+++ b/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
@@ -129,6 +129,63 @@ static const struct rte_cryptodev_capabilities caps_mul[] = {
},
};
+static const struct rte_cryptodev_capabilities caps_pqc[] = {
+ {
+ /* ML-KEM */
+ .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+ .asym = {
+ .xform_capa = {
+ .xform_type = RTE_CRYPTO_ASYM_XFORM_ML_KEM,
+ .op_types =
+ ((1 << RTE_CRYPTO_ML_KEM_OP_KEYGEN) |
+ (1 << RTE_CRYPTO_ML_KEM_OP_ENCAP) |
+ (1 << RTE_CRYPTO_ML_KEM_OP_DECAP)),
+ .mlkem_capa = {
+ [RTE_CRYPTO_ML_KEM_OP_KEYGEN] =
+ (1 << RTE_CRYPTO_ML_KEM_512) |
+ (1 << RTE_CRYPTO_ML_KEM_768) |
+ (1 << RTE_CRYPTO_ML_KEM_1024),
+ [RTE_CRYPTO_ML_KEM_OP_ENCAP] =
+ (1 << RTE_CRYPTO_ML_KEM_512) |
+ (1 << RTE_CRYPTO_ML_KEM_768) |
+ (1 << RTE_CRYPTO_ML_KEM_1024),
+ [RTE_CRYPTO_ML_KEM_OP_DECAP] =
+ (1 << RTE_CRYPTO_ML_KEM_512) |
+ (1 << RTE_CRYPTO_ML_KEM_768) |
+ (1 << RTE_CRYPTO_ML_KEM_1024)
+ }
+ }
+ }
+ },
+ {
+ /* ML-DSA */
+ .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+ .asym = {
+ .xform_capa = {
+ .xform_type = RTE_CRYPTO_ASYM_XFORM_ML_DSA,
+ .op_types =
+ ((1 << RTE_CRYPTO_ML_DSA_OP_SIGN) |
+ (1 << RTE_CRYPTO_ML_DSA_OP_KEYGEN) |
+ (1 << RTE_CRYPTO_ML_DSA_OP_VERIFY)),
+ .mldsa_capa = {
+ [RTE_CRYPTO_ML_DSA_OP_KEYGEN] =
+ (1 << RTE_CRYPTO_ML_DSA_44) |
+ (1 << RTE_CRYPTO_ML_DSA_65) |
+ (1 << RTE_CRYPTO_ML_DSA_87),
+ [RTE_CRYPTO_ML_DSA_OP_SIGN] =
+ (1 << RTE_CRYPTO_ML_DSA_44) |
+ (1 << RTE_CRYPTO_ML_DSA_65) |
+ (1 << RTE_CRYPTO_ML_DSA_87),
+ [RTE_CRYPTO_ML_DSA_OP_VERIFY] =
+ (1 << RTE_CRYPTO_ML_DSA_44) |
+ (1 << RTE_CRYPTO_ML_DSA_65) |
+ (1 << RTE_CRYPTO_ML_DSA_87)
+ }
+ }
+ }
+ },
+};
+
static const struct rte_cryptodev_capabilities caps_sha1_sha2[] = {
{ /* SHA1 */
.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
@@ -2079,10 +2136,13 @@ crypto_caps_populate(struct rte_cryptodev_capabilities cnxk_caps[],
if (roc_model_is_cn10k() || roc_model_is_cn20k())
cn10k_20k_crypto_caps_add(cnxk_caps, hw_caps, &cur_pos);
- if (roc_model_is_cn20k())
+ if (roc_model_is_cn20k()) {
CPT_CAPS_ADD(cnxk_caps, &cur_pos, hw_caps, zuc256_snow5g);
+ cpt_caps_add(cnxk_caps, &cur_pos, caps_pqc, RTE_DIM(caps_pqc));
+ }
cpt_caps_add(cnxk_caps, &cur_pos, caps_null, RTE_DIM(caps_null));
+
cpt_caps_add(cnxk_caps, &cur_pos, caps_end, RTE_DIM(caps_end));
if (roc_model_is_cn10k() || roc_model_is_cn20k())
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_ops.c b/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
index 2f9eb322dc..0f44a393db 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
+++ b/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
@@ -23,6 +23,7 @@
#else
#include "roc_io_generic.h"
#endif
+#include "roc_re_ml_tables.h"
#include "cnxk_ae.h"
#include "cnxk_cryptodev.h"
@@ -41,6 +42,14 @@
#define CNXK_CPT_MAX_ASYM_OP_NUM_PARAMS 5
#define CNXK_CPT_MAX_ASYM_OP_MOD_LEN 1024
+
+/*
+ * PQC requests currently use a shared metabuf region for concatenated input
+ * and output. ML-DSA-87 SIGN requires at least 9523 bytes for private key
+ * input plus signature output, along with additional space for message and
+ * context parameters, so set it for the possible max.
+ */
+#define CNXK_CPT_MAX_ASYM_OP_PQC_LEN 16384
#define CNXK_CPT_META_BUF_MAX_CACHE_SIZE 128
static_assert((uint16_t)RTE_PMD_CNXK_AE_EC_ID_P192 == (uint16_t)ROC_AE_EC_ID_P192,
@@ -107,7 +116,10 @@ cnxk_cpt_asym_get_mlen(void)
len = sizeof(uint64_t);
/* Get meta len for asymmetric operations */
- len += CNXK_CPT_MAX_ASYM_OP_NUM_PARAMS * CNXK_CPT_MAX_ASYM_OP_MOD_LEN;
+ if (roc_model_is_cn20k())
+ len += CNXK_CPT_MAX_ASYM_OP_PQC_LEN;
+ else
+ len += CNXK_CPT_MAX_ASYM_OP_NUM_PARAMS * CNXK_CPT_MAX_ASYM_OP_MOD_LEN;
return len;
}
@@ -121,6 +133,8 @@ cnxk_cpt_dev_clear(struct rte_cryptodev *dev)
if (dev->feature_flags & RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO) {
roc_ae_fpm_put();
roc_ae_ec_grp_put();
+ if (roc_model_is_cn20k())
+ roc_re_ml_zeta_put();
}
ret = roc_cpt_int_misc_cb_unregister(cnxk_cpt_int_misc_cb, NULL);
@@ -182,8 +196,15 @@ cnxk_cpt_dev_config(struct rte_cryptodev *dev, struct rte_cryptodev_config *conf
ret = roc_ae_ec_grp_get(vf->ec_grp);
if (ret) {
plt_err("Could not get EC grp table");
- roc_ae_fpm_put();
- return ret;
+ goto fpm_put;
+ }
+
+ if (roc_model_is_cn20k()) {
+ ret = roc_re_ml_zeta_get(vf->cnxk_ml_iova);
+ if (ret) {
+ plt_err("Could not initialize RE ML lookup table");
+ goto ec_grp_put;
+ }
}
}
roc_cpt->opaque = dev;
@@ -191,6 +212,12 @@ cnxk_cpt_dev_config(struct rte_cryptodev *dev, struct rte_cryptodev_config *conf
roc_cpt_int_misc_cb_register(cnxk_cpt_int_misc_cb, NULL);
return 0;
+
+ec_grp_put:
+ roc_ae_ec_grp_put();
+fpm_put:
+ roc_ae_fpm_put();
+ return ret;
}
int
@@ -992,7 +1019,16 @@ cnxk_ae_session_cfg(struct rte_cryptodev *dev, struct rte_crypto_asym_xform *xfo
priv->lf = roc_cpt->lf[0];
w7.u64 = 0;
- w7.s.egrp = roc_cpt->eng_grp[CPT_ENG_TYPE_AE];
+ if (xform->xform_type == RTE_CRYPTO_ASYM_XFORM_ML_KEM) {
+ w7.s.egrp = roc_cpt->eng_grp[CPT_ENG_TYPE_RE];
+ w7.s.cptr = rte_cpu_to_be_64(vf->cnxk_ml_iova[ROC_RE_ML_ZETA_IDX_KEM]);
+ } else if (xform->xform_type == RTE_CRYPTO_ASYM_XFORM_ML_DSA) {
+ w7.s.egrp = roc_cpt->eng_grp[CPT_ENG_TYPE_RE];
+ w7.s.cptr = rte_cpu_to_be_64(vf->cnxk_ml_iova[ROC_RE_ML_ZETA_IDX_DSA]);
+ } else {
+ w7.s.egrp = roc_cpt->eng_grp[CPT_ENG_TYPE_AE];
+ w7.s.cptr = 0;
+ }
if (roc_errata_cpt_hang_on_mixed_ctx_val()) {
hwc = &priv->hw_ctx;
@@ -1007,6 +1043,7 @@ cnxk_ae_session_cfg(struct rte_cryptodev *dev, struct rte_crypto_asym_xform *xfo
priv->cpt_inst_w7 = w7.u64;
priv->cnxk_fpm_iova = vf->cnxk_fpm_iova;
+ priv->cnxk_ml_iova = vf->cnxk_ml_iova;
priv->ec_grp = vf->ec_grp;
return 0;
--
2.37.1
^ permalink raw reply related
* Re: [PATCH v6] mempool: improve cache behaviour and performance
From: fengchengwen @ 2026-05-29 8:53 UTC (permalink / raw)
To: Morten Brørup, dev, Andrew Rybchenko, Bruce Richardson,
Jingjing Wu, Praveen Shetty, Hemant Agrawal, Sachin Saxena
In-Reply-To: <20260526140000.175092-1-mb@smartsharesystems.com>
On 5/26/2026 10:00 PM, Morten Brørup wrote:
> This patch refactors the mempool cache to eliminate some unexpected
> behaviour and reduce the mempool cache miss rate.
>
> 1.
> The actual cache size was 1.5 times the cache size specified at run-time
> mempool creation.
> This was obviously not expected by application developers.
>
> 2.
> In get operations, the check for when to use the cache as bounce buffer
> did not respect the run-time configured cache size,
> but compared to the build time maximum possible cache size
> (RTE_MEMPOOL_CACHE_MAX_SIZE, default 512).
> E.g. with a configured cache size of 32 objects, getting 256 objects
> would first fetch 32 + 256 = 288 objects into the cache,
> and then move the 256 objects from the cache to the destination memory,
> instead of fetching the 256 objects directly to the destination memory.
> This had a performance cost.
> However, this is unlikely to occur in real applications, so it is not
> important in itself.
>
> 3.
> When putting objects into a mempool, and the mempool cache did not have
> free space for so many objects,
> the cache was flushed completely, and the new objects were then put into
> the cache.
> I.e. the cache drain level was zero.
> This (complete cache flush) meant that a subsequent get operation (with
> the same number of objects) completely emptied the cache,
> so another subsequent get operation required replenishing the cache.
>
> Similarly,
> When getting objects from a mempool, and the mempool cache did not hold so
> many objects,
> the cache was replenished to cache->size + remaining objects,
> and then (the remaining part of) the requested objects were fetched via
> the cache,
> which left the cache filled (to cache->size) at completion.
> I.e. the cache refill level was cache->size (plus some, depending on
> request size).
>
> (1) was improved by generally comparing to cache->size instead of
> cache->flushthresh, when considering the capacity of the cache.
> The cache->flushthresh field is kept for API/ABI compatibility purposes,
> and initialized to cache->size instead of cache->size * 1.5.
>
> (2) was improved by generally comparing to cache->size / 2 instead of
> RTE_MEMPOOL_CACHE_MAX_SIZE, when checking the bounce buffer limit.
>
> (3) was improved by flushing and replenishing the cache by half its size,
> so a flush/refill can be followed randomly by get or put requests.
> This also reduced the number of objects in each flush/refill operation.
>
> As a consequence of these changes, the size of the array holding the
> objects in the cache (cache->objs[]) no longer needs to be
> 2 * RTE_MEMPOOL_CACHE_MAX_SIZE, and can be reduced to
> RTE_MEMPOOL_CACHE_MAX_SIZE at an API/ABI breaking release.
>
> Performance data:
> With a real WAN Optimization application, where the number of allocated
> packets varies (as they are held in e.g. shaper queues), the mempool
> cache miss rate dropped from ca. 1/20 objects to ca. 1/48 objects.
> This was deployed in production at an ISP, and using an effective cache
> size of 384 objects.
Does the application run as a RTC (run-to-complete) mode?
How about pipeline model which NIC recv packets and enqueue ring, another
work thread dequeue packets, process packets and then free packets mbuf?
^ permalink raw reply
* Re: [PATCH v5] net/mlx5: prepend implicit items in sync flow creation path
From: Dariusz Sosnowski @ 2026-05-29 8:44 UTC (permalink / raw)
To: Maxime Peim; +Cc: dev, viacheslavo, bingz, orika, suanmingm, matan
In-Reply-To: <20260527103531.1266488-1-maxime.peim@gmail.com>
On Wed, May 27, 2026 at 12:35:31PM +0200, Maxime Peim wrote:
> In eSwitch mode, the async (template) flow creation path automatically
> prepends implicit match items to scope flow rules to the correct
> representor port:
> - Ingress: REPRESENTED_PORT item matching dev->data->port_id
> - Egress: REG_C_0 TAG item matching the port's tx tag value
>
> The sync path (flow_hw_list_create) was missing this logic, causing all
> flow rules created via the non-template API to match traffic from all
> ports rather than being scoped to the specific representor.
>
> Add the same implicit item prepending to flow_hw_list_create, right
> after pattern validation and before any branching (sample/RSS/single/
> prefix), mirroring the behavior of flow_hw_pattern_template_create
> and flow_hw_get_rule_items. The ingress case prepends
> REPRESENTED_PORT with the current port_id; the egress case prepends
> MLX5_RTE_FLOW_ITEM_TYPE_TAG with REG_C_0 value/mask (skipped when
> user provides an explicit SQ item).
>
> Also fix a pre-existing bug where 'return split' on metadata split
> failure returned a negative int cast to uintptr_t, which callers
> would treat as a valid flow handle instead of an error.
>
> Fixes: e38776c36c8a ("net/mlx5: introduce HWS for non-template flow API")
> Fixes: 821a6a5cc495 ("net/mlx5: add metadata split for compatibility")
> Signed-off-by: Maxime Peim <maxime.peim@gmail.com>
Acked-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
^ permalink raw reply
* Re: [PATCH] examples: Fix vm_power_manager scratch area to /run/dpdk/powermanager
From: Bruce Richardson @ 2026-05-29 8:01 UTC (permalink / raw)
To: Sudheendra Sampath; +Cc: dev, Anatoly Burakov, Sivaprasad Tummala
In-Reply-To: <20260528190449.66254-1-giveback4fun@gmail.com>
On Thu, May 28, 2026 at 07:04:48PM +0000, Sudheendra Sampath wrote:
> This patch for bug 1832 will do the following:
> 1. If /run/dpdk is not present, it will create it first with and
> then create powermanager directory underneath it.
> 2. If /run/dpdk is present, it will verify it is actually a directory
> before creating subdirectory, powermanager.
>
I would suggest using $XDG_RUNTIME_DIR for the directory path, rather than
hardcoding it by default. If XDG_RUNTIME_DIR is not set, then maybe
consider using /run/dpdk. However, rather than /run/dpdk, I'd suggest using
the normal runtime dir path on most distros as the default:
/run/user/<uid>.
/Bruce
^ permalink raw reply
* Re: [PATCH v4 00/25] Consolidate bus driver infrastructure
From: fengchengwen @ 2026-05-29 7:47 UTC (permalink / raw)
To: David Marchand, dev; +Cc: thomas, stephen, bruce.richardson
In-Reply-To: <20260527075654.3780732-1-david.marchand@redhat.com>
Hi David,
First, this is a great refactoring, thank you very much.
I have tested this patchset on the UACCE bus and it passes. Two issues were
found during testing and review:
1. Patch 25/25 fails to apply to the current main branch.
2. Patch 15/25 (bus: support multiple probing) has issues with directly
enabling multiple probing. I suggest merging this patch into Patch 17/25.
The UACCE bus part has passed testing. Please add my Acked-by tag to the
related commits.
Thanks.
On 5/27/2026 3:56 PM, David Marchand wrote:
> This is a continuation of the work I started on the bus infrastructure,
> but this time, a lot of the changes were done by a AI "friend".
> It is still an unfinished topic as the current series focuses on probing
> only. The detaching/cleanup aspect is postponed to another release/time.
>
> My AI "friend" really *sucked* at git and at separating unrelated changes,
> so it required quite a lot of massage/polishing afterwards.
> But it seems good enough now for upstream submission.
>
> I would like to see this series merged in 26.07, so that we have enough
> time to stabilize it before the next LTS.
> And seeing how it affects drivers, it is probably better to merge it
> the sooner possible (so Thomas does not have to solve too many conflicts
> when pulling next-* subtrees after, especially wrt the last patch).
>
>
> This series refactors the DPDK bus infrastructure to consolidate common
> operations and reduce code duplication across all bus drivers.
> Currently, each bus implements its own specific device/driver lists,
> probe logic, and lookup functions.
> This series moves these common patterns into the EAL bus layer,
> providing generic helpers that all buses can use.
>
> The refactoring removes approximately 1,400 lines of duplicated code across
> the codebase while maintaining full functional equivalence.
>
> Key changes:
> - Factorize device and driver lists into struct rte_bus
> - Implement generic probe, device/driver lookup, and iteration helpers in EAL
> - Introduce conversion macros (RTE_BUS_DEVICE, RTE_BUS_DRIVER, RTE_CLASS_TO_BUS_DEVICE)
> to safely convert between generic and bus-specific types
> - Remove bus-specific device/driver types from most driver code
> - Move probe logic from individual buses to rte_bus_generic_probe()
> - Separate NXP-specific metadata from generic bus structures
>
> Benefits:
> - Significant code reduction (~1,400 lines removed)
> - Consistent behavior across all bus types
> - Simplified bus driver implementation
> - Easier maintenance and future enhancements
>
> The series is structured as a progressive refactoring:
> - Remove redundant checks and helpers (patches 1-5)
> - Add conversion macros and factorize lists (patches 6-8)
> - Consolidate device/driver lookup and iteration (patches 9-11)
> - Refactor probe logic (patches 12-15)
> - Remove bus-specific types from drivers (patches 16-23)
>
> Note on ABI:
> This series breaks the ABI for drivers (changes to rte_pci_device,
> rte_pci_driver, and similar structures for other buses). However, the DPDK
> ABI policy does not provide guarantees for driver-level interfaces.
>
>
^ permalink raw reply
* [PATCH v2] net/mlx5: promote private API to stable
From: Dariusz Sosnowski @ 2026-05-29 7:32 UTC (permalink / raw)
To: Viacheslav Ovsiienko, Bing Zhao, Ori Kam, Suanming Mou,
Matan Azrad; +Cc: dev
In-Reply-To: <20260527103357.633429-1-dsosnowski@nvidia.com>
Following experimental functions are exposed by mlx5 PMD
since 25.11 release:
- rte_pmd_mlx5_driver_event_cb_register
- rte_pmd_mlx5_driver_event_cb_unregister
- rte_pmd_mlx5_enable_steering
- rte_pmd_mlx5_disable_steering
First two are used to register callbacks for driver events
(when Rx/Tx queues are created or destroyed).
Other two are used to enable/disable flow steering in mlx5 PMD.
No changes were made and no changes are planned to these symbols.
These are currently used by NVIDIA DOCA SDK since version 3.3,
which started depending on upstream DPDK releases [1].
Purpose of their use is to:
- expose HW identifiers of Rx/Tx mlx5 queues managed by DPDK and
- allow flow steering to happen outside of DPDK.
Also, some of these symbols will be used by netdev-doca backend
in Open vSwitch [2].
Whenever a DOCA netdev would be added/removed in Open vSwitch,
it will have to disable/enable steering for mlx5 driver.
Stabilizing these symbols is required by current OVS policy
to remove the need for ALLOW_EXPERIMENTAL_API [3].
This patch promotes aforementioned symbols to stable.
[1]: https://docs.nvidia.com/doca/sdk/customer-affecting-changes/index.html
[2]: https://patchwork.ozlabs.org/project/openvswitch/list/?series=504726&state=%2A&archive=both
[3]: https://mail.openvswitch.org/pipermail/ovs-dev/2026-May/432066.html
Signed-off-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
---
v2:
- Updated 26.07 release notes.
doc/guides/rel_notes/release_26_07.rst | 9 +++++++++
drivers/net/mlx5/mlx5_driver_event.c | 4 ++--
drivers/net/mlx5/mlx5_flow.c | 4 ++--
drivers/net/mlx5/rte_pmd_mlx5.h | 4 ----
4 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/doc/guides/rel_notes/release_26_07.rst b/doc/guides/rel_notes/release_26_07.rst
index 6eba91a5e9..2af24d40a0 100644
--- a/doc/guides/rel_notes/release_26_07.rst
+++ b/doc/guides/rel_notes/release_26_07.rst
@@ -127,6 +127,15 @@ API Changes
- ``rte_flow_dynf_metadata_get``
- ``rte_flow_dynf_metadata_set``
+* **mlx5: promoted driver event and steering management APIs from experimental to stable.**
+
+ The following mlx5 APIs are no longer marked experimental:
+
+ - ``rte_pmd_mlx5_driver_event_cb_register``
+ - ``rte_pmd_mlx5_driver_event_cb_unregister``
+ - ``rte_pmd_mlx5_enable_steering``
+ - ``rte_pmd_mlx5_disable_steering``
+
ABI Changes
-----------
diff --git a/drivers/net/mlx5/mlx5_driver_event.c b/drivers/net/mlx5/mlx5_driver_event.c
index 1dc8029ee5..89e49331c8 100644
--- a/drivers/net/mlx5/mlx5_driver_event.c
+++ b/drivers/net/mlx5/mlx5_driver_event.c
@@ -236,7 +236,7 @@ notify_existing_devices(rte_pmd_mlx5_driver_event_callback_t cb, void *opaque)
notify_existing_queues(port_id, cb, opaque);
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_pmd_mlx5_driver_event_cb_register, 25.11)
+RTE_EXPORT_SYMBOL(rte_pmd_mlx5_driver_event_cb_register)
int
rte_pmd_mlx5_driver_event_cb_register(rte_pmd_mlx5_driver_event_callback_t cb, void *opaque)
{
@@ -264,7 +264,7 @@ rte_pmd_mlx5_driver_event_cb_register(rte_pmd_mlx5_driver_event_callback_t cb, v
return 0;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_pmd_mlx5_driver_event_cb_unregister, 25.11)
+RTE_EXPORT_SYMBOL(rte_pmd_mlx5_driver_event_cb_unregister)
int
rte_pmd_mlx5_driver_event_cb_unregister(rte_pmd_mlx5_driver_event_callback_t cb)
{
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 915ea29a5a..a95dd9dc94 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -12506,7 +12506,7 @@ flow_disable_steering_run_on_related(struct rte_eth_dev *dev,
}
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_pmd_mlx5_disable_steering, 25.11)
+RTE_EXPORT_SYMBOL(rte_pmd_mlx5_disable_steering)
void
rte_pmd_mlx5_disable_steering(void)
{
@@ -12532,7 +12532,7 @@ rte_pmd_mlx5_disable_steering(void)
mlx5_steering_disabled = true;
}
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_pmd_mlx5_enable_steering, 25.11)
+RTE_EXPORT_SYMBOL(rte_pmd_mlx5_enable_steering)
int
rte_pmd_mlx5_enable_steering(void)
{
diff --git a/drivers/net/mlx5/rte_pmd_mlx5.h b/drivers/net/mlx5/rte_pmd_mlx5.h
index 55a26cb067..f482875434 100644
--- a/drivers/net/mlx5/rte_pmd_mlx5.h
+++ b/drivers/net/mlx5/rte_pmd_mlx5.h
@@ -620,7 +620,6 @@ int rte_pmd_mlx5_external_sq_disable(uint16_t port_id, uint32_t sq_num);
* - (-EEXIST) if @p cb was already registered.
* - (-ENOMEM) if failed to allocate memory for callback entry.
*/
-__rte_experimental
int
rte_pmd_mlx5_driver_event_cb_register(rte_pmd_mlx5_driver_event_callback_t cb, void *opaque);
@@ -641,7 +640,6 @@ rte_pmd_mlx5_driver_event_cb_register(rte_pmd_mlx5_driver_event_callback_t cb, v
* - 0 if callback was successfully unregistered or if no such callback was registered.
* - (-EINVAL) if @p cb is NULL.
*/
-__rte_experimental
int
rte_pmd_mlx5_driver_event_cb_unregister(rte_pmd_mlx5_driver_event_callback_t cb);
@@ -679,7 +677,6 @@ rte_pmd_mlx5_driver_event_cb_unregister(rte_pmd_mlx5_driver_event_callback_t cb)
* with other functions from ethdev API used to configure any of the mlx5 ports.
* It is the responsibility of the application to enforce this.
*/
-__rte_experimental
void
rte_pmd_mlx5_disable_steering(void);
@@ -697,7 +694,6 @@ rte_pmd_mlx5_disable_steering(void);
* - 0 - Flow steering was successfully enabled or it flow steering was never disabled.
* - (-EBUSY) - There are mlx5 ports probed and re-enabling steering cannot be done safely.
*/
-__rte_experimental
int
rte_pmd_mlx5_enable_steering(void);
--
2.47.3
^ permalink raw reply related
* [PATCH v2] ethdev: promote flow metadata APIs to stable
From: Dariusz Sosnowski @ 2026-05-29 7:28 UTC (permalink / raw)
To: Ori Kam, Thomas Monjalon, Andrew Rybchenko; +Cc: dev
In-Reply-To: <20260527103246.633327-1-dsosnowski@nvidia.com>
Following experimental symbols related to flow metadata
were added in v19.11:
- rte_flow_dynf_metadata_register
- rte_flow_dynf_metadata_offs
- rte_flow_dynf_metadata_mask
Type of rte_flow_dynf_metadata_offs was changed from int to int32_t
in v20.05 release.
There were no changes to these symbols since then.
This patch promotes these symbols and removes __rte_experimental
from the following inline functions:
- rte_flow_dynf_metadata_avail
- rte_flow_dynf_metadata_get
- rte_flow_dynf_metadata_set
All these symbols and functions will be used by netdev-doca
backend in Open vSwitch [1].
Stabilizing these symbols is required by current OVS policy
to remove the need for ALLOW_EXPERIMENTAL_API [2].
[1]: https://patchwork.ozlabs.org/project/openvswitch/list/?series=504726&state=%2A&archive=both
[2]: https://mail.openvswitch.org/pipermail/ovs-dev/2026-May/432066.html
Signed-off-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
---
v2:
- Updated 26.07 release notes.
doc/guides/rel_notes/release_26_07.rst | 11 +++++++++++
lib/ethdev/rte_flow.c | 6 +++---
lib/ethdev/rte_flow.h | 4 ----
3 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/doc/guides/rel_notes/release_26_07.rst b/doc/guides/rel_notes/release_26_07.rst
index 8b4f8401e2..6eba91a5e9 100644
--- a/doc/guides/rel_notes/release_26_07.rst
+++ b/doc/guides/rel_notes/release_26_07.rst
@@ -116,6 +116,17 @@ API Changes
Also, make sure to start the actual text at the margin.
=======================================================
+* **ethdev: promoted flow metadata APIs from experimental to stable.**
+
+ The following ethdev APIs and symbols are no longer marked experimental:
+
+ - ``rte_flow_dynf_metadata_register``
+ - ``rte_flow_dynf_metadata_offs``
+ - ``rte_flow_dynf_metadata_mask``
+ - ``rte_flow_dynf_metadata_avail``
+ - ``rte_flow_dynf_metadata_get``
+ - ``rte_flow_dynf_metadata_set``
+
ABI Changes
-----------
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 7a51b667cf..ec0fe08355 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -23,11 +23,11 @@
#define FLOW_LOG RTE_ETHDEV_LOG_LINE
/* Mbuf dynamic field name for metadata. */
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_dynf_metadata_offs, 19.11)
+RTE_EXPORT_SYMBOL(rte_flow_dynf_metadata_offs)
int32_t rte_flow_dynf_metadata_offs = -1;
/* Mbuf dynamic field flag bit number for metadata. */
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_dynf_metadata_mask, 19.11)
+RTE_EXPORT_SYMBOL(rte_flow_dynf_metadata_mask)
uint64_t rte_flow_dynf_metadata_mask;
/**
@@ -281,7 +281,7 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {
MK_FLOW_ACTION(JUMP_TO_TABLE_INDEX, sizeof(struct rte_flow_action_jump_to_table_index)),
};
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_dynf_metadata_register, 19.11)
+RTE_EXPORT_SYMBOL(rte_flow_dynf_metadata_register)
int
rte_flow_dynf_metadata_register(void)
{
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index ba3bcc89a3..0c6d42c0d8 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -4253,14 +4253,12 @@ extern uint64_t rte_flow_dynf_metadata_mask;
#define RTE_MBUF_DYNFLAG_RX_METADATA (rte_flow_dynf_metadata_mask)
#define RTE_MBUF_DYNFLAG_TX_METADATA (rte_flow_dynf_metadata_mask)
-__rte_experimental
static inline uint32_t
rte_flow_dynf_metadata_get(struct rte_mbuf *m)
{
return *RTE_FLOW_DYNF_METADATA(m);
}
-__rte_experimental
static inline void
rte_flow_dynf_metadata_set(struct rte_mbuf *m, uint32_t v)
{
@@ -4590,7 +4588,6 @@ rte_flow_dev_dump(uint16_t port_id, struct rte_flow *flow,
* @return
* True if registered, false otherwise.
*/
-__rte_experimental
static inline int
rte_flow_dynf_metadata_avail(void)
{
@@ -4607,7 +4604,6 @@ rte_flow_dynf_metadata_avail(void)
* @return
* 0 on success, a negative errno value otherwise and rte_errno is set.
*/
-__rte_experimental
int
rte_flow_dynf_metadata_register(void);
--
2.47.3
^ permalink raw reply related
* RE: [RFC 8/8] net/txgbe: privatize legacy flow director types
From: Jiawen Wu @ 2026-05-29 7:29 UTC (permalink / raw)
To: 'Stephen Hemminger', dev; +Cc: 'Zaiyu Wang'
In-Reply-To: <20260528213816.562910-9-stephen@networkplumber.org>
> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Friday, May 29, 2026 5:37 AM
> To: dev@dpdk.org
> Cc: Stephen Hemminger <stephen@networkplumber.org>; Jiawen Wu <jiawenwu@trustnetic.com>; Zaiyu Wang
> <zaiyuwang@trustnetic.com>
> Subject: [RFC 8/8] net/txgbe: privatize legacy flow director types
>
> The txgbe driver inherited its flow director representation from
> ixgbe (it derives from the same hardware lineage) and uses the
> same legacy ethdev types (struct rte_eth_fdir_conf, enum
> rte_fdir_mode, and related) as its internal IR for translating
> rte_flow rules into hardware programming state. These types are
> scheduled for removal from ethdev in DPDK 26.11.
>
> Clone the relevant types into txgbe_ethdev.h with a txgbe-private
> prefix so the driver no longer depends on the legacy ABI. The
> embedded rte_eth_ipv4_flow / rte_eth_ipv6_flow types are cloned
> too since they live in the same removal candidate set.
>
> Unlike ixgbe, txgbe base/ does not pre-declare an
> enum txgbe_fdir_pballoc_type, so the cloned one is defined here.
> txgbe uses the integer value of pballoc directly in the table-
> size calculation
>
> (1024 << (fdir_conf->pballoc + 1)) - 2
>
> so the enum values match the original ethdev numbering
> (64K=0, 128K=1, 256K=2). pballoc is set explicitly from devargs
> in txgbe_handle_devarg(), so no extra initialization is required.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
> drivers/net/txgbe/txgbe_ethdev.c | 6 +-
> drivers/net/txgbe/txgbe_ethdev.h | 101 +++++++++++++++++++++-
> drivers/net/txgbe/txgbe_fdir.c | 78 ++++++++---------
> drivers/net/txgbe/txgbe_flow.c | 24 ++---
> drivers/net/txgbe/txgbe_rxtx_vec_common.h | 4 +-
> 5 files changed, 155 insertions(+), 58 deletions(-)
LGTM, thanks.
> diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
> index 5d360f8305..258ec4d97c 100644
> --- a/drivers/net/txgbe/txgbe_ethdev.c
> +++ b/drivers/net/txgbe/txgbe_ethdev.c
> @@ -524,7 +524,7 @@ txgbe_handle_devarg(__rte_unused const char *key, const char *value,
> static void
> txgbe_parse_devargs(struct rte_eth_dev *dev)
> {
> - struct rte_eth_fdir_conf *fdir_conf = TXGBE_DEV_FDIR_CONF(dev);
> + struct txgbe_fdir_conf *fdir_conf = TXGBE_DEV_FDIR_CONF(dev);
> struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
> struct rte_devargs *devargs = pci_dev->device.devargs;
> struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
> @@ -934,7 +934,7 @@ static int txgbe_l2_tn_filter_uninit(struct rte_eth_dev *eth_dev)
>
> int txgbe_fdir_filter_init(struct rte_eth_dev *eth_dev)
> {
> - struct rte_eth_fdir_conf *fdir_conf = TXGBE_DEV_FDIR_CONF(eth_dev);
> + struct txgbe_fdir_conf *fdir_conf = TXGBE_DEV_FDIR_CONF(eth_dev);
> struct txgbe_hw_fdir_info *fdir_info = TXGBE_DEV_FDIR(eth_dev);
> char fdir_hash_name[RTE_HASH_NAMESIZE];
> u16 max_fdir_num = (1024 << (fdir_conf->pballoc + 1)) - 2;
> @@ -1834,7 +1834,7 @@ txgbe_dev_start(struct rte_eth_dev *dev)
> txgbe_configure_port(dev);
> txgbe_configure_dcb(dev);
>
> - if (TXGBE_DEV_FDIR_CONF(dev)->mode != RTE_FDIR_MODE_NONE) {
> + if (TXGBE_DEV_FDIR_CONF(dev)->mode != TXGBE_FDIR_MODE_NONE) {
> err = txgbe_fdir_configure(dev);
> if (err)
> goto error;
> diff --git a/drivers/net/txgbe/txgbe_ethdev.h b/drivers/net/txgbe/txgbe_ethdev.h
> index 189fbac541..1f4ce4f3b8 100644
> --- a/drivers/net/txgbe/txgbe_ethdev.h
> +++ b/drivers/net/txgbe/txgbe_ethdev.h
> @@ -83,6 +83,103 @@
> /*
> * Information about the fdir mode.
> */
> +/*
> + * Privatized flow director configuration types.
> + *
> + * Cloned from <rte_eth_ctrl.h> and <ethdev_driver.h> so that txgbe no
> + * longer depends on the legacy ethdev flow director ABI, which is
> + * scheduled for removal in DPDK 26.11. Semantics unchanged; only the
> + * names are txgbe-private.
> + *
> + * NB: txgbe uses the integer value of pballoc directly in
> + * (1024 << (fdir_conf->pballoc + 1)) - 2
> + * to size the HW filter table. The enum values therefore match the
> + * original ethdev numbering (64K=0, 128K=1, 256K=2).
> + */
> +#define TXGBE_FDIR_MAX_FLEXLEN 16 /**< Max length of flexbytes. */
> +
> +struct txgbe_ipv4_flow {
> + uint32_t src_ip;
> + uint32_t dst_ip;
> + uint8_t tos;
> + uint8_t ttl;
> + uint8_t proto;
> +};
> +
> +struct txgbe_ipv6_flow {
> + uint32_t src_ip[4];
> + uint32_t dst_ip[4];
> + uint8_t tc;
> + uint8_t proto;
> + uint8_t hop_limits;
> +};
> +
> +struct txgbe_fdir_masks {
> + uint16_t vlan_tci_mask;
> + struct txgbe_ipv4_flow ipv4_mask;
> + struct txgbe_ipv6_flow ipv6_mask;
> + uint16_t src_port_mask;
> + uint16_t dst_port_mask;
> + uint8_t mac_addr_byte_mask;
> + uint32_t tunnel_id_mask;
> + uint8_t tunnel_type_mask;
> +};
> +
> +enum txgbe_payload_type {
> + TXGBE_PAYLOAD_UNKNOWN = 0,
> + TXGBE_RAW_PAYLOAD,
> + TXGBE_L2_PAYLOAD,
> + TXGBE_L3_PAYLOAD,
> + TXGBE_L4_PAYLOAD,
> + TXGBE_PAYLOAD_MAX = 8,
> +};
> +
> +struct txgbe_flex_payload_cfg {
> + enum txgbe_payload_type type;
> + uint16_t src_offset[TXGBE_FDIR_MAX_FLEXLEN];
> +};
> +
> +struct txgbe_fdir_flex_mask {
> + uint16_t flow_type;
> + uint8_t mask[TXGBE_FDIR_MAX_FLEXLEN];
> +};
> +
> +struct txgbe_fdir_flex_conf {
> + uint16_t nb_payloads;
> + uint16_t nb_flexmasks;
> + struct txgbe_flex_payload_cfg flex_set[TXGBE_PAYLOAD_MAX];
> + struct txgbe_fdir_flex_mask flex_mask[RTE_ETH_FLOW_MAX];
> +};
> +
> +enum txgbe_fdir_mode {
> + TXGBE_FDIR_MODE_NONE = 0,
> + TXGBE_FDIR_MODE_SIGNATURE,
> + TXGBE_FDIR_MODE_PERFECT,
> + TXGBE_FDIR_MODE_PERFECT_MAC_VLAN,
> + TXGBE_FDIR_MODE_PERFECT_TUNNEL,
> +};
> +
> +enum txgbe_fdir_pballoc_type {
> + TXGBE_FDIR_PBALLOC_64K = 0,
> + TXGBE_FDIR_PBALLOC_128K,
> + TXGBE_FDIR_PBALLOC_256K,
> +};
> +
> +enum txgbe_fdir_status_mode {
> + TXGBE_FDIR_NO_REPORT_STATUS = 0,
> + TXGBE_FDIR_REPORT_STATUS,
> + TXGBE_FDIR_REPORT_STATUS_ALWAYS,
> +};
> +
> +struct txgbe_fdir_conf {
> + enum txgbe_fdir_mode mode;
> + enum txgbe_fdir_pballoc_type pballoc;
> + enum txgbe_fdir_status_mode status;
> + uint8_t drop_queue;
> + struct txgbe_fdir_masks mask;
> + struct txgbe_fdir_flex_conf flex_conf;
> +};
> +
> struct txgbe_hw_fdir_mask {
> uint16_t vlan_tci_mask;
> uint32_t src_ipv4_mask;
> @@ -111,7 +208,7 @@ struct txgbe_fdir_rule {
> struct txgbe_atr_input input; /* key of fdir filter */
> bool b_spec; /* If TRUE, input, fdirflags, queue have meaning. */
> bool b_mask; /* If TRUE, mask has meaning. */
> - enum rte_fdir_mode mode; /* IP, MAC VLAN, Tunnel */
> + enum txgbe_fdir_mode mode; /* IP, MAC VLAN, Tunnel */
> uint32_t fdirflags; /* drop or forward */
> uint32_t soft_id; /* an unique value for this rule */
> uint8_t queue; /* assigned rx queue */
> @@ -352,7 +449,7 @@ struct txgbe_tm_conf {
> struct txgbe_adapter {
> struct txgbe_hw hw;
> struct txgbe_hw_stats stats;
> - struct rte_eth_fdir_conf fdir_conf;
> + struct txgbe_fdir_conf fdir_conf;
> struct txgbe_hw_fdir_info fdir;
> struct txgbe_interrupt intr;
> struct txgbe_stat_mappings stat_mappings;
> diff --git a/drivers/net/txgbe/txgbe_fdir.c b/drivers/net/txgbe/txgbe_fdir.c
> index 67f586ffc7..ded01341a4 100644
> --- a/drivers/net/txgbe/txgbe_fdir.c
> +++ b/drivers/net/txgbe/txgbe_fdir.c
> @@ -102,22 +102,22 @@ txgbe_fdir_enable(struct txgbe_hw *hw, uint32_t fdirctrl)
> * flexbytes matching field, and drop queue (only for perfect matching mode).
> */
> static inline int
> -configure_fdir_flags(const struct rte_eth_fdir_conf *conf,
> +configure_fdir_flags(const struct txgbe_fdir_conf *conf,
> uint32_t *fdirctrl, uint32_t *flex)
> {
> *fdirctrl = 0;
> *flex = 0;
>
> switch (conf->pballoc) {
> - case RTE_ETH_FDIR_PBALLOC_64K:
> + case TXGBE_FDIR_PBALLOC_64K:
> /* 8k - 1 signature filters */
> *fdirctrl |= TXGBE_FDIRCTL_BUF_64K;
> break;
> - case RTE_ETH_FDIR_PBALLOC_128K:
> + case TXGBE_FDIR_PBALLOC_128K:
> /* 16k - 1 signature filters */
> *fdirctrl |= TXGBE_FDIRCTL_BUF_128K;
> break;
> - case RTE_ETH_FDIR_PBALLOC_256K:
> + case TXGBE_FDIR_PBALLOC_256K:
> /* 32k - 1 signature filters */
> *fdirctrl |= TXGBE_FDIRCTL_BUF_256K;
> break;
> @@ -129,14 +129,14 @@ configure_fdir_flags(const struct rte_eth_fdir_conf *conf,
>
> /* status flags: write hash & swindex in the rx descriptor */
> switch (conf->status) {
> - case RTE_FDIR_NO_REPORT_STATUS:
> + case TXGBE_FDIR_NO_REPORT_STATUS:
> /* do nothing, default mode */
> break;
> - case RTE_FDIR_REPORT_STATUS:
> + case TXGBE_FDIR_REPORT_STATUS:
> /* report status when the packet matches a fdir rule */
> *fdirctrl |= TXGBE_FDIRCTL_REPORT_MATCH;
> break;
> - case RTE_FDIR_REPORT_STATUS_ALWAYS:
> + case TXGBE_FDIR_REPORT_STATUS_ALWAYS:
> /* always report status */
> *fdirctrl |= TXGBE_FDIRCTL_REPORT_ALWAYS;
> break;
> @@ -150,9 +150,9 @@ configure_fdir_flags(const struct rte_eth_fdir_conf *conf,
> *flex |= TXGBE_FDIRFLEXCFG_OFST(TXGBE_DEFAULT_FLEXBYTES_OFFSET / 2);
>
> switch (conf->mode) {
> - case RTE_FDIR_MODE_SIGNATURE:
> + case TXGBE_FDIR_MODE_SIGNATURE:
> break;
> - case RTE_FDIR_MODE_PERFECT:
> + case TXGBE_FDIR_MODE_PERFECT:
> *fdirctrl |= TXGBE_FDIRCTL_PERFECT;
> *fdirctrl |= TXGBE_FDIRCTL_DROPQP(conf->drop_queue);
> break;
> @@ -179,7 +179,7 @@ txgbe_fdir_set_input_mask(struct rte_eth_dev *dev)
> {
> struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
> struct txgbe_hw_fdir_info *info = TXGBE_DEV_FDIR(dev);
> - enum rte_fdir_mode mode = TXGBE_DEV_FDIR_CONF(dev)->mode;
> + enum txgbe_fdir_mode mode = TXGBE_DEV_FDIR_CONF(dev)->mode;
> /*
> * mask VM pool and DIPv6 since there are currently not supported
> * mask FLEX byte, it will be set in flex_conf
> @@ -190,8 +190,8 @@ txgbe_fdir_set_input_mask(struct rte_eth_dev *dev)
>
> PMD_INIT_FUNC_TRACE();
>
> - if (mode != RTE_FDIR_MODE_SIGNATURE &&
> - mode != RTE_FDIR_MODE_PERFECT) {
> + if (mode != TXGBE_FDIR_MODE_SIGNATURE &&
> + mode != TXGBE_FDIR_MODE_PERFECT) {
> PMD_DRV_LOG(ERR, "Not supported fdir mode - %d!", mode);
> return -ENOTSUP;
> }
> @@ -232,14 +232,14 @@ txgbe_fdir_set_input_mask(struct rte_eth_dev *dev)
> static int
> txgbe_fdir_store_input_mask(struct rte_eth_dev *dev)
> {
> - struct rte_eth_fdir_masks *input_mask = &TXGBE_DEV_FDIR_CONF(dev)->mask;
> - enum rte_fdir_mode mode = TXGBE_DEV_FDIR_CONF(dev)->mode;
> + struct txgbe_fdir_masks *input_mask = &TXGBE_DEV_FDIR_CONF(dev)->mask;
> + enum txgbe_fdir_mode mode = TXGBE_DEV_FDIR_CONF(dev)->mode;
> struct txgbe_hw_fdir_info *info = TXGBE_DEV_FDIR(dev);
> uint16_t dst_ipv6m = 0;
> uint16_t src_ipv6m = 0;
>
> - if (mode != RTE_FDIR_MODE_SIGNATURE &&
> - mode != RTE_FDIR_MODE_PERFECT) {
> + if (mode != TXGBE_FDIR_MODE_SIGNATURE &&
> + mode != TXGBE_FDIR_MODE_PERFECT) {
> PMD_DRV_LOG(ERR, "Not supported fdir mode - %d!", mode);
> return -ENOTSUP;
> }
> @@ -304,12 +304,12 @@ txgbe_fdir_set_flexbytes_offset(struct rte_eth_dev *dev,
> static int
> txgbe_set_fdir_flex_conf(struct rte_eth_dev *dev, uint32_t flex)
> {
> - const struct rte_eth_fdir_flex_conf *conf =
> + const struct txgbe_fdir_flex_conf *conf =
> &TXGBE_DEV_FDIR_CONF(dev)->flex_conf;
> struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
> struct txgbe_hw_fdir_info *info = TXGBE_DEV_FDIR(dev);
> - const struct rte_eth_flex_payload_cfg *flex_cfg;
> - const struct rte_eth_fdir_flex_mask *flex_mask;
> + const struct txgbe_flex_payload_cfg *flex_cfg;
> + const struct txgbe_fdir_flex_mask *flex_mask;
> uint16_t flexbytes = 0;
> uint16_t i;
>
> @@ -322,7 +322,7 @@ txgbe_set_fdir_flex_conf(struct rte_eth_dev *dev, uint32_t flex)
>
> for (i = 0; i < conf->nb_payloads; i++) {
> flex_cfg = &conf->flex_set[i];
> - if (flex_cfg->type != RTE_ETH_RAW_PAYLOAD) {
> + if (flex_cfg->type != TXGBE_RAW_PAYLOAD) {
> PMD_DRV_LOG(ERR, "unsupported payload type.");
> return -EINVAL;
> }
> @@ -375,13 +375,13 @@ txgbe_fdir_configure(struct rte_eth_dev *dev)
> int err;
> uint32_t fdirctrl, flex, pbsize;
> int i;
> - enum rte_fdir_mode mode = TXGBE_DEV_FDIR_CONF(dev)->mode;
> + enum txgbe_fdir_mode mode = TXGBE_DEV_FDIR_CONF(dev)->mode;
>
> PMD_INIT_FUNC_TRACE();
>
> /* supports mac-vlan and tunnel mode */
> - if (mode != RTE_FDIR_MODE_SIGNATURE &&
> - mode != RTE_FDIR_MODE_PERFECT)
> + if (mode != TXGBE_FDIR_MODE_SIGNATURE &&
> + mode != TXGBE_FDIR_MODE_PERFECT)
> return -ENOSYS;
>
> err = configure_fdir_flags(TXGBE_DEV_FDIR_CONF(dev), &fdirctrl, &flex);
> @@ -531,15 +531,15 @@ txgbe_atr_compute_hash(struct txgbe_atr_input *atr_input,
>
> static uint32_t
> atr_compute_perfect_hash(struct txgbe_atr_input *input,
> - enum rte_eth_fdir_pballoc_type pballoc)
> + enum txgbe_fdir_pballoc_type pballoc)
> {
> uint32_t bucket_hash;
>
> bucket_hash = txgbe_atr_compute_hash(input,
> TXGBE_ATR_BUCKET_HASH_KEY);
> - if (pballoc == RTE_ETH_FDIR_PBALLOC_256K)
> + if (pballoc == TXGBE_FDIR_PBALLOC_256K)
> bucket_hash &= PERFECT_BUCKET_256KB_HASH_MASK;
> - else if (pballoc == RTE_ETH_FDIR_PBALLOC_128K)
> + else if (pballoc == TXGBE_FDIR_PBALLOC_128K)
> bucket_hash &= PERFECT_BUCKET_128KB_HASH_MASK;
> else
> bucket_hash &= PERFECT_BUCKET_64KB_HASH_MASK;
> @@ -574,15 +574,15 @@ txgbe_fdir_check_cmd_complete(struct txgbe_hw *hw, uint32_t *fdircmd)
> */
> static uint32_t
> atr_compute_signature_hash(struct txgbe_atr_input *input,
> - enum rte_eth_fdir_pballoc_type pballoc)
> + enum txgbe_fdir_pballoc_type pballoc)
> {
> uint32_t bucket_hash, sig_hash;
>
> bucket_hash = txgbe_atr_compute_hash(input,
> TXGBE_ATR_BUCKET_HASH_KEY);
> - if (pballoc == RTE_ETH_FDIR_PBALLOC_256K)
> + if (pballoc == TXGBE_FDIR_PBALLOC_256K)
> bucket_hash &= SIG_BUCKET_256KB_HASH_MASK;
> - else if (pballoc == RTE_ETH_FDIR_PBALLOC_128K)
> + else if (pballoc == TXGBE_FDIR_PBALLOC_128K)
> bucket_hash &= SIG_BUCKET_128KB_HASH_MASK;
> else
> bucket_hash &= SIG_BUCKET_64KB_HASH_MASK;
> @@ -603,7 +603,7 @@ static int
> fdir_write_perfect_filter(struct txgbe_hw *hw,
> struct txgbe_atr_input *input, uint8_t queue,
> uint32_t fdircmd, uint32_t fdirhash,
> - enum rte_fdir_mode mode)
> + enum txgbe_fdir_mode mode)
> {
> uint32_t fdirport, fdirflex;
> int err = 0;
> @@ -830,14 +830,14 @@ txgbe_fdir_filter_program(struct rte_eth_dev *dev,
> bool is_perfect = FALSE;
> int err;
> struct txgbe_hw_fdir_info *info = TXGBE_DEV_FDIR(dev);
> - enum rte_fdir_mode fdir_mode = TXGBE_DEV_FDIR_CONF(dev)->mode;
> + enum txgbe_fdir_mode fdir_mode = TXGBE_DEV_FDIR_CONF(dev)->mode;
> struct txgbe_fdir_filter *node;
>
> - if (fdir_mode == RTE_FDIR_MODE_NONE ||
> + if (fdir_mode == TXGBE_FDIR_MODE_NONE ||
> fdir_mode != rule->mode)
> return -ENOTSUP;
>
> - if (fdir_mode >= RTE_FDIR_MODE_PERFECT)
> + if (fdir_mode >= TXGBE_FDIR_MODE_PERFECT)
> is_perfect = TRUE;
>
> txgbe_fdir_mask_input(&info->mask, &rule->input);
> @@ -1021,7 +1021,7 @@ txgbevf_fdir_filter_program(struct rte_eth_dev *dev,
> uint32_t fdirhash;
> int ret;
>
> - if (rule->mode != RTE_FDIR_MODE_PERFECT ||
> + if (rule->mode != TXGBE_FDIR_MODE_PERFECT ||
> rule->fdirflags == TXGBE_FDIRPICMD_DROP)
> return -ENOTSUP;
>
> @@ -1109,10 +1109,10 @@ txgbe_fdir_filter_restore(struct rte_eth_dev *dev)
> struct txgbe_hw_fdir_info *fdir_info = TXGBE_DEV_FDIR(dev);
> struct txgbe_fdir_filter *node;
> bool is_perfect = FALSE;
> - enum rte_fdir_mode fdir_mode = TXGBE_DEV_FDIR_CONF(dev)->mode;
> + enum txgbe_fdir_mode fdir_mode = TXGBE_DEV_FDIR_CONF(dev)->mode;
>
> - if (fdir_mode >= RTE_FDIR_MODE_PERFECT &&
> - fdir_mode <= RTE_FDIR_MODE_PERFECT_TUNNEL)
> + if (fdir_mode >= TXGBE_FDIR_MODE_PERFECT &&
> + fdir_mode <= TXGBE_FDIR_MODE_PERFECT_TUNNEL)
> is_perfect = TRUE;
>
> if (is_perfect) {
> @@ -1139,7 +1139,7 @@ txgbe_fdir_filter_restore(struct rte_eth_dev *dev)
> int
> txgbe_clear_all_fdir_filter(struct rte_eth_dev *dev)
> {
> - struct rte_eth_fdir_conf *fdir_conf = TXGBE_DEV_FDIR_CONF(dev);
> + struct txgbe_fdir_conf *fdir_conf = TXGBE_DEV_FDIR_CONF(dev);
> struct txgbe_hw_fdir_info *fdir_info = TXGBE_DEV_FDIR(dev);
> struct txgbe_fdir_filter *fdir_filter;
> struct txgbe_fdir_filter *filter_flag;
> @@ -1150,7 +1150,7 @@ txgbe_clear_all_fdir_filter(struct rte_eth_dev *dev)
> memset(fdir_info->hash_map, 0,
> sizeof(struct txgbe_fdir_filter *) *
> ((1024 << (fdir_conf->pballoc + 1)) - 2));
> - fdir_conf->mode = RTE_FDIR_MODE_NONE;
> + fdir_conf->mode = TXGBE_FDIR_MODE_NONE;
> filter_flag = TAILQ_FIRST(&fdir_info->fdir_list);
> while ((fdir_filter = TAILQ_FIRST(&fdir_info->fdir_list))) {
> TAILQ_REMOVE(&fdir_info->fdir_list,
> diff --git a/drivers/net/txgbe/txgbe_flow.c b/drivers/net/txgbe/txgbe_flow.c
> index a97588e57a..8470bf78af 100644
> --- a/drivers/net/txgbe/txgbe_flow.c
> +++ b/drivers/net/txgbe/txgbe_flow.c
> @@ -1412,7 +1412,7 @@ txgbe_parse_fdir_act_attr(const struct rte_flow_attr *attr,
> rule->queue = act_q->index;
> } else { /* drop */
> /* signature mode does not support drop action. */
> - if (rule->mode == RTE_FDIR_MODE_SIGNATURE) {
> + if (rule->mode == TXGBE_FDIR_MODE_SIGNATURE) {
> memset(rule, 0, sizeof(struct txgbe_fdir_rule));
> rte_flow_error_set(error, EINVAL,
> RTE_FLOW_ERROR_TYPE_ACTION,
> @@ -1646,9 +1646,9 @@ txgbe_parse_fdir_filter_normal(struct rte_eth_dev *dev __rte_unused,
> }
>
> if (signature_match(pattern))
> - rule->mode = RTE_FDIR_MODE_SIGNATURE;
> + rule->mode = TXGBE_FDIR_MODE_SIGNATURE;
> else
> - rule->mode = RTE_FDIR_MODE_PERFECT;
> + rule->mode = TXGBE_FDIR_MODE_PERFECT;
>
> /*Not supported last point for range*/
> if (item->last) {
> @@ -1678,7 +1678,7 @@ txgbe_parse_fdir_filter_normal(struct rte_eth_dev *dev __rte_unused,
>
> /* Ether type should be masked. */
> if (eth_mask->hdr.ether_type ||
> - rule->mode == RTE_FDIR_MODE_SIGNATURE) {
> + rule->mode == TXGBE_FDIR_MODE_SIGNATURE) {
> memset(rule, 0, sizeof(struct txgbe_fdir_rule));
> rte_flow_error_set(error, EINVAL,
> RTE_FLOW_ERROR_TYPE_ITEM,
> @@ -1687,7 +1687,7 @@ txgbe_parse_fdir_filter_normal(struct rte_eth_dev *dev __rte_unused,
> }
>
> /* If ethernet has meaning, it means MAC VLAN mode. */
> - rule->mode = RTE_FDIR_MODE_PERFECT_MAC_VLAN;
> + rule->mode = TXGBE_FDIR_MODE_PERFECT_MAC_VLAN;
>
> /**
> * src MAC address must be masked,
> @@ -1718,7 +1718,7 @@ txgbe_parse_fdir_filter_normal(struct rte_eth_dev *dev __rte_unused,
> * IPv6 is not supported.
> */
> item = next_no_fuzzy_pattern(pattern, item);
> - if (rule->mode == RTE_FDIR_MODE_PERFECT_MAC_VLAN) {
> + if (rule->mode == TXGBE_FDIR_MODE_PERFECT_MAC_VLAN) {
> if (item->type != RTE_FLOW_ITEM_TYPE_VLAN) {
> memset(rule, 0, sizeof(struct txgbe_fdir_rule));
> rte_flow_error_set(error, EINVAL,
> @@ -2282,7 +2282,7 @@ txgbe_parse_fdir_filter_tunnel(const struct rte_flow_attr *attr,
> return -rte_errno;
> }
>
> - rule->mode = RTE_FDIR_MODE_PERFECT;
> + rule->mode = TXGBE_FDIR_MODE_PERFECT;
> ptid = TXGBE_PTID_PKT_TUN;
>
> /* Skip MAC. */
> @@ -2949,7 +2949,7 @@ txgbe_parse_fdir_filter(struct rte_eth_dev *dev,
> struct rte_flow_error *error)
> {
> int ret;
> - struct rte_eth_fdir_conf *fdir_conf = TXGBE_DEV_FDIR_CONF(dev);
> + struct txgbe_fdir_conf *fdir_conf = TXGBE_DEV_FDIR_CONF(dev);
>
> ret = txgbe_parse_fdir_filter_normal(dev, attr, pattern,
> actions, rule, error);
> @@ -2965,11 +2965,11 @@ txgbe_parse_fdir_filter(struct rte_eth_dev *dev,
> if (!txgbe_is_pf(TXGBE_DEV_HW(dev)))
> return ret;
>
> - if (fdir_conf->mode == RTE_FDIR_MODE_NONE) {
> + if (fdir_conf->mode == TXGBE_FDIR_MODE_NONE) {
> fdir_conf->mode = rule->mode;
> ret = txgbe_fdir_configure(dev);
> if (ret) {
> - fdir_conf->mode = RTE_FDIR_MODE_NONE;
> + fdir_conf->mode = TXGBE_FDIR_MODE_NONE;
> return ret;
> }
> } else if (fdir_conf->mode != rule->mode) {
> @@ -3562,7 +3562,7 @@ txgbe_flow_destroy(struct rte_eth_dev *dev,
> struct txgbe_fdir_rule_ele *fdir_rule_ptr;
> struct txgbe_flow_mem *txgbe_flow_mem_ptr;
> struct txgbe_hw_fdir_info *fdir_info = TXGBE_DEV_FDIR(dev);
> - struct rte_eth_fdir_conf *fdir_conf = TXGBE_DEV_FDIR_CONF(dev);
> + struct txgbe_fdir_conf *fdir_conf = TXGBE_DEV_FDIR_CONF(dev);
> struct txgbe_rss_conf_ele *rss_filter_ptr;
>
> switch (filter_type) {
> @@ -3625,7 +3625,7 @@ txgbe_flow_destroy(struct rte_eth_dev *dev,
> fdir_info->mask_added = false;
> fdir_info->flex_relative = false;
> fdir_info->flex_bytes_offset = 0;
> - fdir_conf->mode = RTE_FDIR_MODE_NONE;
> + fdir_conf->mode = TXGBE_FDIR_MODE_NONE;
> }
> }
> break;
> diff --git a/drivers/net/txgbe/txgbe_rxtx_vec_common.h b/drivers/net/txgbe/txgbe_rxtx_vec_common.h
> index 00847d087b..c6144cad70 100644
> --- a/drivers/net/txgbe/txgbe_rxtx_vec_common.h
> +++ b/drivers/net/txgbe/txgbe_rxtx_vec_common.h
> @@ -299,10 +299,10 @@ static inline int
> txgbe_rx_vec_dev_conf_condition_check_default(struct rte_eth_dev *dev)
> {
> #ifndef RTE_LIBRTE_IEEE1588
> - struct rte_eth_fdir_conf *fconf = TXGBE_DEV_FDIR_CONF(dev);
> + struct txgbe_fdir_conf *fconf = TXGBE_DEV_FDIR_CONF(dev);
>
> /* no fdir support */
> - if (fconf->mode != RTE_FDIR_MODE_NONE)
> + if (fconf->mode != TXGBE_FDIR_MODE_NONE)
> return -1;
>
> return 0;
> --
> 2.53.0
>
>
^ permalink raw reply
* Re: [PATCH v4 15/25] bus: support multiple probe
From: fengchengwen @ 2026-05-29 7:27 UTC (permalink / raw)
To: David Marchand, dev
Cc: thomas, stephen, bruce.richardson, Parav Pandit, Xueming Li,
Nipun Gupta, Nikhil Agarwal, Hemant Agrawal, Sachin Saxena,
Rosen Xu, Chenbo Xia, Tomasz Duszynski, Long Li, Wei Hu
In-Reply-To: <20260527075654.3780732-16-david.marchand@redhat.com>
Currently, the bus probe is still the specific impl which don't test allow_multi_probe flag.
And local_dev_probe only cover the plug device case.
On 5/27/2026 3:56 PM, David Marchand wrote:
> Add infrastructure to declare support for multiple probe attempts
> on the same device. This prepares for the introduction of
> generic probe_device operation.
>
> The PCI bus enables this feature to support drivers with
> RTE_PCI_DRV_PROBE_AGAIN flag.
>
> Signed-off-by: David Marchand <david.marchand@redhat.com>
> Acked-by: Bruce Richardson <bruce.richardson@intel.com>
> ---
...
^ permalink raw reply
* [PATCH] raw/gdtc : update MAINTAINERS entry
From: Wenqiang Chen @ 2026-05-29 6:20 UTC (permalink / raw)
To: dev; +Cc: ran.ming, 陈文强10327674
[-- Attachment #1.1.1: Type: text/plain, Size: 644 bytes --]
From: 陈文强10327674 <chen.wenqiang2@zte.com.cn>
Change the GDTC rawdev maintainer from Yong Zhang
to Wenqiang Chen.
Signed-off-by: 陈文强10327674 <chen.wenqiang2@zte.com.cn>
---
MAINTAINERS | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index b390446ed3..48c72e1d67 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1612,7 +1612,7 @@ F: drivers/raw/dpaa2_cmdif/
F: doc/guides/rawdevs/dpaa2_cmdif.rst
ZTE GDTC
-M: Yong Zhang <zhang.yong25@zte.com.cn>
+M: Wenqiang Chen <chen.wenqiang2@zte.com.cn>
F: drivers/raw/gdtc/
F: doc/guides/rawdevs/gdtc.rst
--
2.27.0
[-- Attachment #1.1.2: Type: text/html , Size: 1045 bytes --]
^ permalink raw reply related
* [PATCH] net/zxdh : update MAINTAINERS entry
From: Wenqiang Chen @ 2026-05-29 5:55 UTC (permalink / raw)
To: dev; +Cc: ran.ming, 陈文强10327674
[-- Attachment #1.1.1: Type: text/plain, Size: 644 bytes --]
From: 陈文强10327674 <chen.wenqiang2@zte.com.cn>
Change the GDTC rawdev maintainer from Yong Zhang
to Wenqiang Chen.
Signed-off-by: 陈文强10327674 <chen.wenqiang2@zte.com.cn>
---
MAINTAINERS | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index b390446ed3..48c72e1d67 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1612,7 +1612,7 @@ F: drivers/raw/dpaa2_cmdif/
F: doc/guides/rawdevs/dpaa2_cmdif.rst
ZTE GDTC
-M: Yong Zhang <zhang.yong25@zte.com.cn>
+M: Wenqiang Chen <chen.wenqiang2@zte.com.cn>
F: drivers/raw/gdtc/
F: doc/guides/rawdevs/gdtc.rst
--
2.27.0
[-- Attachment #1.1.2: Type: text/html , Size: 1045 bytes --]
^ permalink raw reply related
* Re: [PATCH v4 06/25] drivers/bus: remove device and driver checks in unplug
From: fengchengwen @ 2026-05-29 4:16 UTC (permalink / raw)
To: David Marchand, dev
Cc: thomas, stephen, bruce.richardson, Parav Pandit, Xueming Li,
Nipun Gupta, Nikhil Agarwal, Hemant Agrawal, Sachin Saxena,
Rosen Xu, Chenbo Xia, Tomasz Duszynski, Long Li, Wei Hu
In-Reply-To: <20260527075654.3780732-7-david.marchand@redhat.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
On 5/27/2026 3:56 PM, David Marchand wrote:
> rte_dev_remove() checks if a device is probed before calling the bus
> unplug operation. Individual bus detach/remove functions checking that
> dev->driver is non-NULL are therefore redundant.
>
> However, when the unplug operation is called at bus cleanup, care must
> be taken that devices are in probed state, so some check on
> rte_dev_is_probed() must be added.
>
> The device parameter passed to bus unplug operations cannot be NULL as
> the caller already dereferenced the bus structure to invoke these
> operations.
> The driver reference in the bus-specific device cannot be NULL since
> calling the .unplug is done after dereferencing this pointer.
>
> Signed-off-by: David Marchand <david.marchand@redhat.com>
> Acked-by: Bruce Richardson <bruce.richardson@intel.com>
^ permalink raw reply
* Re: [PATCH v4 05/25] bus: remove device and driver checks in DMA map/unmap
From: fengchengwen @ 2026-05-29 3:57 UTC (permalink / raw)
To: David Marchand, dev
Cc: thomas, stephen, bruce.richardson, Parav Pandit, Xueming Li,
Chenbo Xia, Nipun Gupta, Tomasz Duszynski
In-Reply-To: <20260527075654.3780732-6-david.marchand@redhat.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
On 5/27/2026 3:56 PM, David Marchand wrote:
> Add rte_dev_is_probed() check in rte_dev_dma_map() and
> rte_dev_dma_unmap() before calling bus-specific implementations.
>
> The device parameter passed to bus DMA map/unmap operations cannot be
> NULL as the caller already dereferenced the bus structure to invoke
> these operations.
> The driver reference in the bus-specific device cannot be NULL since
> calling the .dma_map is done after dereferencing this pointer.
>
> Remove redundant checks on probed device, and NULL checks on the
> device/driver parameter and derived device/driver pointers.
>
> Signed-off-by: David Marchand <david.marchand@redhat.com>
> Acked-by: Bruce Richardson <bruce.richardson@intel.com>
^ permalink raw reply
* Re: [PATCH v4 02/25] bus/uacce: set API version during scan
From: fengchengwen @ 2026-05-29 3:50 UTC (permalink / raw)
To: David Marchand, dev; +Cc: thomas, stephen, bruce.richardson
In-Reply-To: <20260527075654.3780732-3-david.marchand@redhat.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
On 5/27/2026 3:56 PM, David Marchand wrote:
> Move API version parsing from the match callback to the time where the
> device object is allocated and filled, since this property is constant.
>
> This avoids any side effect on the device object when calling the match
> callback.
>
> Signed-off-by: David Marchand <david.marchand@redhat.com>
^ permalink raw reply
* Re: [PATCH v2 3/3] usertools/telemetry: add help support
From: fengchengwen @ 2026-05-29 0:27 UTC (permalink / raw)
To: Bruce Richardson, dev
In-Reply-To: <20260522133714.133268-4-bruce.richardson@intel.com>
On 5/22/2026 9:37 PM, Bruce Richardson wrote:
> While the telemetry infrastructure supported using "/help,/<cmd>" to get
> help on specific commands, with the addition of script-specific
> commands, we needed better help support to explain the use of FOREACH,
> and to allow e.g. "help /<cmd>" using space separation, which is more
> intuitive. This patch adds that help support.
>
> Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> ---
> usertools/dpdk-telemetry.py | 61 ++++++++++++++++++++++++++++++++++++-
> 1 file changed, 60 insertions(+), 1 deletion(-)
>
> diff --git a/usertools/dpdk-telemetry.py b/usertools/dpdk-telemetry.py
> index 8b976160e0..2c88b91517 100755
> --- a/usertools/dpdk-telemetry.py
> +++ b/usertools/dpdk-telemetry.py
> @@ -25,6 +25,26 @@
> ALIAS_FILE = ".dpdk_telemetry_aliases"
> MAX_ALIAS_EXPANSIONS = 32
>
> +BASIC_HELP_TEXT = """Basic usage:
> + /<command>[,<params>] Send a telemetry command to the app
> + FOREACH ... Run a compound query over list items
> + help Show this help
> + help /<command> Show app-provided help for a command
> + help FOREACH Show FOREACH usage and examples
> + quit Exit the client
Please add help alias to show ALL loaded command alias
^ permalink raw reply
* Re: [PATCH v2 2/3] usertools/telemetry: support using aliases for long commands
From: fengchengwen @ 2026-05-29 0:25 UTC (permalink / raw)
To: Bruce Richardson, dev
In-Reply-To: <20260522133714.133268-3-bruce.richardson@intel.com>
On 5/22/2026 9:37 PM, Bruce Richardson wrote:
> Similarly to how shell aliases work, allow specifying of short alias
> commands for dpdk-telemetry.py script. The aliases are read from
> "$HOME/.dpdk_telemetry_aliases" at startup.
>
> Some examples of use from the docs. Alias file contents:
>
> # Basic shortcuts
> ls=/ethdev/list
> names=FOREACH i /ethdev/list /ethdev/info,$i .name
> q=quit
>
> Alias use:
>
> --> ls
> {"/ethdev/list": [0, 1]}
>
> --> names
> [{"i": 0, "name": "0000:
>
> Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> ---
> doc/guides/howto/telemetry.rst | 34 +++++++++++++++
> usertools/dpdk-telemetry.py | 75 ++++++++++++++++++++++++++++++++--
> 2 files changed, 105 insertions(+), 4 deletions(-)
>
> diff --git a/doc/guides/howto/telemetry.rst b/doc/guides/howto/telemetry.rst
> index 4bf48c635e..072289aec8 100644
> --- a/doc/guides/howto/telemetry.rst
> +++ b/doc/guides/howto/telemetry.rst
> @@ -130,6 +130,40 @@ and query information using the telemetry client python script.
> - With loop variable: returns an array of objects containing the loop
> variable field and requested value fields.
>
> + * Use command aliases.
> +
> + The telemetry script can load aliases at startup from::
> +
> + $HOME/.dpdk_telemetry_aliases
How about add one parameter to specific aliases file location
> +
> + Each alias entry must be in ``alias=command`` format.
> + Empty lines and lines starting with ``#`` are ignored.
> +
> + Example alias file::
> +
> + # Basic shortcuts
> + ls=/ethdev/list
> + names=FOREACH i /ethdev/list /ethdev/info,$i .name
> + q=quit
> +
> + Alias behavior is intentionally similar to shell aliases:
> +
> + - The first token of the entered input is checked for an alias match.
> + - If matched, that first token is replaced with its expansion.
> + - Alias expansion is recursive (aliases can expand to other aliases).
> + - Expansion has a safety limit to prevent infinite loops.
> +
> + Examples::
> +
> + --> ls
> + {"/ethdev/list": [0, 1]}
> +
> + --> names
> + [{"i": 0, "name": "0000:16:00.0"}, {"i": 1, "name": "0000:16:00.1"}]
> +
> + --> q
> + # exits the client
> +
>
> Connecting to Different DPDK Processes
> --------------------------------------
> diff --git a/usertools/dpdk-telemetry.py b/usertools/dpdk-telemetry.py
> index 2de10cff69..8b976160e0 100755
> --- a/usertools/dpdk-telemetry.py
> +++ b/usertools/dpdk-telemetry.py
> @@ -21,6 +21,70 @@
> SOCKET_NAME = "dpdk_telemetry.{}".format(TELEMETRY_VERSION)
> DEFAULT_PREFIX = "rte"
> CMDS = []
> +ALIASES = {}
> +ALIAS_FILE = ".dpdk_telemetry_aliases"
> +MAX_ALIAS_EXPANSIONS = 32
> +
> +
> +def load_aliases():
> + """Load aliases from $HOME/.dpdk_telemetry_aliases"""
> + aliases = {}
> + home = os.environ.get("HOME")
> + if not home:
> + return aliases
> +
> + alias_path = os.path.join(home, ALIAS_FILE)
> + if not os.path.isfile(alias_path):
> + return aliases
> +
> + try:
> + with open(alias_path) as alias_file:
> + for line_num, line in enumerate(alias_file, start=1):
> + entry = line.strip()
> + if not entry or entry.startswith("#"):
> + continue
> + if "=" not in entry:
> + print(
> + "Warning: ignoring malformed alias at {}:{}".format(alias_path, line_num),
> + file=sys.stderr,
> + )
> + continue
> + name, command = entry.split("=", 1)
> + name = name.strip()
> + command = command.strip()
> + if not name or not command:
> + print(
> + "Warning: ignoring malformed alias at {}:{}".format(alias_path, line_num),
> + file=sys.stderr,
> + )
> + continue
> + aliases[name] = command
> + except OSError as e:
> + print("Warning: failed to read {}: {}".format(alias_path, e), file=sys.stderr)
If load OK, please add one promote at begin:
Loaded xxx command aliases, see `help alias` for detail
> +
> + return aliases
> +
> +
^ permalink raw reply
* Re: [PATCH v2 1/3] usertools/telemetry: add a FOREACH command
From: fengchengwen @ 2026-05-29 0:17 UTC (permalink / raw)
To: Bruce Richardson, dev
In-Reply-To: <20260522133714.133268-2-bruce.richardson@intel.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
On 5/22/2026 9:37 PM, Bruce Richardson wrote:
> To simplify querying data from multiple devices, e.g. across ethdevs, or
> dmadevs, add a FOREACH command to the python script, allowing you to
> run, e.g. /ethdev/list, and then run a second command for each item in
> the list, gathering the relevant output values, optionally including an
> index counter.
>
> Simple examples are given in the documentation:
>
> --> FOREACH /ethdev/list /ethdev/stats .opackets
> [0, 0]
>
> --> FOREACH /ethdev/list /ethdev/stats .ipackets .opackets
> [{"ipackets": 0, "opackets": 0}, {"ipackets": 0, "opackets": 0}]
>
> --> FOREACH i /ethdev/list /ethdev/info,$i .name
> [{"i": 0, "name": "0000:16:00.0"}, {"i": 1, "name": "0000:16:00.1"}]
>
> --> FOREACH i /ethdev/list /ethdev/stats,$i .ipackets .opackets
> [{"i": 0, "ipackets": 0, "opackets": 0}, {"i": 1, "ipackets": 0, "opackets": 0}]
>
> Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
^ permalink raw reply
* [PATCH v2] ethdev: add buffer size parameter to rte_eth_dev_get_name_by_port()
From: Stephen Hemminger @ 2026-05-29 0:07 UTC (permalink / raw)
To: dev
Cc: Stephen Hemminger, Andrew Rybchenko, Reshma Pattan, Aman Singh,
Naga Harish K S V, Bruce Richardson, Kishore Padmanabha,
Ajit Khaparde, Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori,
Satha Rao, Harman Kalra, Anatoly Burakov, Cristian Dumitrescu,
Thomas Monjalon
In-Reply-To: <20260409013658.965613-1-stephen@networkplumber.org>
rte_eth_dev_get_name_by_port() uses strcpy() into a caller-provided
buffer with no bounds checking. A mistaken caller that supplies a
buffer smaller than RTE_ETH_NAME_MAX_LEN can overflow the buffer.
Add a size parameter and replace strcpy() with strlcpy(), returning
-ERANGE if the name is truncated. The copy is now performed under
the ethdev shared data lock so that the name cannot be mutated by
another process between reading and copying.
The previous ABI is preserved via symbol versioning (DPDK_26) with a
thin wrapper that delegates to the new implementation with
RTE_ETH_NAME_MAX_LEN. The versioned symbol will be removed in 26.11.
Update all in-tree callers to pass sizeof(name) as the new parameter.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
app/dumpcap/main.c | 8 ++--
app/pdump/main.c | 8 ++--
app/test-pmd/config.c | 6 +--
app/test/test_event_eth_tx_adapter.c | 4 +-
app/test/test_pmd_ring_perf.c | 4 +-
app/test/test_pmd_tap.c | 6 +--
doc/guides/rel_notes/release_26_07.rst | 4 ++
drivers/net/bnxt/tf_ulp/bnxt_ulp_tf.c | 4 +-
drivers/net/cnxk/cnxk_flow.c | 10 +++--
examples/multi_process/hotplug_mp/commands.c | 2 +-
examples/pipeline/cli.c | 2 +-
lib/ethdev/meson.build | 2 +
lib/ethdev/rte_ethdev.c | 42 +++++++++++++++-----
lib/ethdev/rte_ethdev.h | 10 +++--
lib/pdump/rte_pdump.c | 8 ++--
15 files changed, 78 insertions(+), 42 deletions(-)
diff --git a/app/dumpcap/main.c b/app/dumpcap/main.c
index 46a6cb251e..47483535fc 100644
--- a/app/dumpcap/main.c
+++ b/app/dumpcap/main.c
@@ -244,7 +244,7 @@ static void find_interfaces(void)
/* maybe got passed port number string as name */
intf->port = get_uint(intf->name, "port_number", UINT16_MAX);
- if (rte_eth_dev_get_name_by_port(intf->port, intf->name) < 0)
+ if (rte_eth_dev_get_name_by_port(intf->port, intf->name, sizeof(intf->name)) < 0)
rte_exit(EXIT_FAILURE, "Invalid port number %u\n",
intf->port);
}
@@ -261,7 +261,7 @@ static void set_default_interface(void)
uint16_t p;
RTE_ETH_FOREACH_DEV(p) {
- if (rte_eth_dev_get_name_by_port(p, name) < 0)
+ if (rte_eth_dev_get_name_by_port(p, name, sizeof(name)) < 0)
continue;
intf = add_interface(name);
@@ -278,7 +278,7 @@ static void dump_interfaces(void)
uint16_t p;
RTE_ETH_FOREACH_DEV(p) {
- if (rte_eth_dev_get_name_by_port(p, name) < 0)
+ if (rte_eth_dev_get_name_by_port(p, name, sizeof(name)) < 0)
continue;
printf("%u. %s\n", p, name);
}
@@ -498,7 +498,7 @@ static void statistics_loop(void)
while (!rte_atomic_load_explicit(&quit_signal, rte_memory_order_relaxed)) {
RTE_ETH_FOREACH_DEV(p) {
- if (rte_eth_dev_get_name_by_port(p, name) < 0)
+ if (rte_eth_dev_get_name_by_port(p, name, sizeof(name)) < 0)
continue;
r = rte_eth_stats_get(p, &stats);
diff --git a/app/pdump/main.c b/app/pdump/main.c
index 1e62c8adc1..1f6135b20e 100644
--- a/app/pdump/main.c
+++ b/app/pdump/main.c
@@ -539,16 +539,16 @@ cleanup_pdump_resources(void)
/* Remove the vdev(s) created */
if (pt->dir & RTE_PDUMP_FLAG_RX) {
- rte_eth_dev_get_name_by_port(pt->rx_vdev_id, name);
- rte_eal_hotplug_remove("vdev", name);
+ if (rte_eth_dev_get_name_by_port(pt->rx_vdev_id, name, sizeof(name)) == 0)
+ rte_eal_hotplug_remove("vdev", name);
}
if (pt->single_pdump_dev)
continue;
if (pt->dir & RTE_PDUMP_FLAG_TX) {
- rte_eth_dev_get_name_by_port(pt->tx_vdev_id, name);
- rte_eal_hotplug_remove("vdev", name);
+ if (rte_eth_dev_get_name_by_port(pt->tx_vdev_id, name, sizeof(name)) == 0)
+ rte_eal_hotplug_remove("vdev", name);
}
}
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index c950793aaf..1cf441acf5 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -697,7 +697,7 @@ device_infos_display(const char *identifier)
&mac_addr) == 0)
print_ethaddr("\n\tMAC address: ",
&mac_addr);
- rte_eth_dev_get_name_by_port(port_id, name);
+ rte_eth_dev_get_name_by_port(port_id, name, sizeof(name));
printf("\n\tDevice name: %s", name);
if (rte_eth_dev_info_get(port_id, &dev_info) == 0)
device_infos_display_speeds(dev_info.speed_capa);
@@ -823,7 +823,7 @@ port_infos_display(portid_t port_id)
info_border, port_id, info_border);
if (eth_macaddr_get_print_err(port_id, &mac_addr) == 0)
print_ethaddr("MAC address: ", &mac_addr);
- rte_eth_dev_get_name_by_port(port_id, name);
+ rte_eth_dev_get_name_by_port(port_id, name, sizeof(name));
printf("\nDevice name: %s", name);
printf("\nDriver name: %s", dev_info.driver_name);
@@ -1011,7 +1011,7 @@ port_summary_display(portid_t port_id)
if (ret != 0)
return;
- rte_eth_dev_get_name_by_port(port_id, name);
+ rte_eth_dev_get_name_by_port(port_id, name, sizeof(name));
ret = eth_macaddr_get_print_err(port_id, &mac_addr);
if (ret != 0)
return;
diff --git a/app/test/test_event_eth_tx_adapter.c b/app/test/test_event_eth_tx_adapter.c
index bec298a8b8..a7cbe39367 100644
--- a/app/test/test_event_eth_tx_adapter.c
+++ b/app/test/test_event_eth_tx_adapter.c
@@ -192,8 +192,8 @@ deinit_ports(void)
for (i = 0; i < RTE_DIM(default_params.port); i++) {
rte_eth_dev_stop(default_params.port[i]);
- rte_eth_dev_get_name_by_port(default_params.port[i], name);
- rte_vdev_uninit(name);
+ if (rte_eth_dev_get_name_by_port(default_params.port[i], name, sizeof(name)) == 0)
+ rte_vdev_uninit(name);
for (j = 0; j < RTE_DIM(default_params.r[i]); j++)
rte_ring_free(default_params.r[i][j]);
}
diff --git a/app/test/test_pmd_ring_perf.c b/app/test/test_pmd_ring_perf.c
index 3636df5c73..ac60f506ab 100644
--- a/app/test/test_pmd_ring_perf.c
+++ b/app/test/test_pmd_ring_perf.c
@@ -157,8 +157,8 @@ test_ring_pmd_perf(void)
/* release port and ring resources */
if (rte_eth_dev_stop(ring_ethdev_port) != 0)
return -1;
- rte_eth_dev_get_name_by_port(ring_ethdev_port, name);
- rte_vdev_uninit(name);
+ if (rte_eth_dev_get_name_by_port(ring_ethdev_port, name, sizeof(name)) == 0)
+ rte_vdev_uninit(name);
rte_ring_free(r);
return 0;
}
diff --git a/app/test/test_pmd_tap.c b/app/test/test_pmd_tap.c
index 6d0e8b4f54..ded26bc5e3 100644
--- a/app/test/test_pmd_tap.c
+++ b/app/test/test_pmd_tap.c
@@ -594,7 +594,7 @@ test_tap_multi_queue(void)
uint16_t port;
RTE_ETH_FOREACH_DEV(port) {
char name[RTE_ETH_NAME_MAX_LEN];
- if (rte_eth_dev_get_name_by_port(port, name) == 0 &&
+ if (rte_eth_dev_get_name_by_port(port, name, sizeof(name)) == 0 &&
strstr(name, "net_tap_mq"))
goto found;
}
@@ -739,7 +739,7 @@ test_tap_setup(void)
/* Find the port IDs */
RTE_ETH_FOREACH_DEV(port_id) {
char name[RTE_ETH_NAME_MAX_LEN];
- if (rte_eth_dev_get_name_by_port(port_id, name) != 0)
+ if (rte_eth_dev_get_name_by_port(port_id, name, sizeof(name)) != 0)
continue;
if (strstr(name, "net_tap0"))
@@ -785,7 +785,7 @@ test_tap_rx_queue_setup(void)
port = -1;
RTE_ETH_FOREACH_DEV(port_id) {
char name[RTE_ETH_NAME_MAX_LEN];
- if (rte_eth_dev_get_name_by_port(port_id, name) == 0 &&
+ if (rte_eth_dev_get_name_by_port(port_id, name, sizeof(name)) == 0 &&
strstr(name, "net_tap_neg")) {
port = port_id;
break;
diff --git a/doc/guides/rel_notes/release_26_07.rst b/doc/guides/rel_notes/release_26_07.rst
index 8b4f8401e2..6c91487a11 100644
--- a/doc/guides/rel_notes/release_26_07.rst
+++ b/doc/guides/rel_notes/release_26_07.rst
@@ -116,6 +116,10 @@ API Changes
Also, make sure to start the actual text at the margin.
=======================================================
+* ethdev: Added ``size`` parameter to ``rte_eth_dev_get_name_by_port()``
+ to prevent buffer overflows. The old ABI version without the size parameter
+ is preserved using symbol versioning and will be removed in 26.11.
+
ABI Changes
-----------
diff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp_tf.c b/drivers/net/bnxt/tf_ulp/bnxt_ulp_tf.c
index 6ca9d3309b..e1ffc64c5e 100644
--- a/drivers/net/bnxt/tf_ulp/bnxt_ulp_tf.c
+++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp_tf.c
@@ -608,7 +608,7 @@ ulp_tf_ctx_shared_session_open(struct bnxt *bp,
memset(&parms, 0, sizeof(parms));
rc = rte_eth_dev_get_name_by_port(ethdev->data->port_id,
- parms.ctrl_chan_name);
+ parms.ctrl_chan_name, sizeof(parms.ctrl_chan_name));
if (rc) {
BNXT_DRV_DBG(ERR, "Invalid port %d, rc = %d\n",
ethdev->data->port_id, rc);
@@ -786,7 +786,7 @@ ulp_tf_ctx_session_open(struct bnxt *bp,
memset(¶ms, 0, sizeof(params));
rc = rte_eth_dev_get_name_by_port(ethdev->data->port_id,
- params.ctrl_chan_name);
+ params.ctrl_chan_name, sizeof(params.ctrl_chan_name));
if (rc) {
BNXT_DRV_DBG(ERR, "Invalid port %d, rc = %d\n",
ethdev->data->port_id, rc);
diff --git a/drivers/net/cnxk/cnxk_flow.c b/drivers/net/cnxk/cnxk_flow.c
index c1c48eb7ab..eb51ce37e8 100644
--- a/drivers/net/cnxk/cnxk_flow.c
+++ b/drivers/net/cnxk/cnxk_flow.c
@@ -117,7 +117,7 @@ npc_parse_port_id_action(struct rte_eth_dev *eth_dev, const struct rte_flow_acti
port_act = (const struct rte_flow_action_port_id *)action->conf;
- rc = rte_eth_dev_get_name_by_port(port_act->id, if_name);
+ rc = rte_eth_dev_get_name_by_port(port_act->id, if_name, sizeof(if_name));
if (rc) {
plt_err("Name not found for output port id");
goto err_exit;
@@ -517,7 +517,8 @@ cnxk_map_actions(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR:
in_actions[i].conf = actions->conf;
act_ethdev = (const struct rte_flow_action_ethdev *)actions->conf;
- if (rte_eth_dev_get_name_by_port(act_ethdev->port_id, if_name)) {
+ if (rte_eth_dev_get_name_by_port(act_ethdev->port_id, if_name,
+ sizeof(if_name))) {
plt_err("Name not found for output port id");
goto err_exit;
}
@@ -557,7 +558,7 @@ cnxk_map_actions(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
actions->type != RTE_FLOW_ACTION_TYPE_PORT_ID ?
act_ethdev->port_id :
port_act->id,
- if_name)) {
+ if_name, sizeof(if_name))) {
plt_err("Name not found for output port id");
goto err_exit;
}
@@ -713,7 +714,8 @@ cnxk_map_pattern(struct rte_eth_dev *eth_dev, const struct rte_flow_item pattern
if (pattern->type == RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT ||
pattern->type == RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR) {
rep_eth_dev = (const struct rte_flow_item_ethdev *)pattern->spec;
- if (rte_eth_dev_get_name_by_port(rep_eth_dev->port_id, if_name)) {
+ if (rte_eth_dev_get_name_by_port(rep_eth_dev->port_id, if_name,
+ sizeof(if_name))) {
plt_err("Name not found for output port id");
goto fail;
}
diff --git a/examples/multi_process/hotplug_mp/commands.c b/examples/multi_process/hotplug_mp/commands.c
index 900eb9f774..92a4f0378b 100644
--- a/examples/multi_process/hotplug_mp/commands.c
+++ b/examples/multi_process/hotplug_mp/commands.c
@@ -36,7 +36,7 @@ cmd_list_parsed(__rte_unused void *parsed_result,
cmdline_printf(cl, "list all etherdev\n");
RTE_ETH_FOREACH_DEV(port_id) {
- rte_eth_dev_get_name_by_port(port_id, dev_name);
+ rte_eth_dev_get_name_by_port(port_id, dev_name, sizeof(dev_name));
if (strlen(dev_name) > 0)
cmdline_printf(cl, "%d\t%s\n", port_id, dev_name);
else
diff --git a/examples/pipeline/cli.c b/examples/pipeline/cli.c
index 215b4061d5..51c8864077 100644
--- a/examples/pipeline/cli.c
+++ b/examples/pipeline/cli.c
@@ -396,7 +396,7 @@ ethdev_show(uint16_t port_id, char **out, size_t *out_size)
if (rte_eth_link_get(port_id, &link) != 0)
return;
- rte_eth_dev_get_name_by_port(port_id, name);
+ rte_eth_dev_get_name_by_port(port_id, name, sizeof(name));
rte_eth_stats_get(port_id, &stats);
rte_eth_macaddr_get(port_id, &addr);
rte_eth_dev_get_mtu(port_id, &mtu);
diff --git a/lib/ethdev/meson.build b/lib/ethdev/meson.build
index 8ba6c708a2..b2c4222fe6 100644
--- a/lib/ethdev/meson.build
+++ b/lib/ethdev/meson.build
@@ -62,3 +62,5 @@ endif
if get_option('buildtype').contains('debug')
cflags += ['-DRTE_FLOW_DEBUG']
endif
+
+use_function_versioning = true
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index d0273e3f7b..1638cab231 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -721,12 +721,9 @@ rte_eth_dev_count_total(void)
return count;
}
-RTE_EXPORT_SYMBOL(rte_eth_dev_get_name_by_port)
-int
-rte_eth_dev_get_name_by_port(uint16_t port_id, char *name)
+static int
+eth_dev_get_name_by_port(uint16_t port_id, char *name, size_t size)
{
- char *tmp;
-
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
if (name == NULL) {
@@ -735,19 +732,46 @@ rte_eth_dev_get_name_by_port(uint16_t port_id, char *name)
return -EINVAL;
}
+ if (size == 0) {
+ RTE_ETHDEV_LOG_LINE(ERR,
+ "Cannot get ethdev port %u name with zero-size buffer", port_id);
+ return -EINVAL;
+ }
+
rte_spinlock_lock(rte_mcfg_ethdev_get_lock());
- /* shouldn't check 'rte_eth_devices[i].data',
- * because it might be overwritten by VDEV PMD */
- tmp = eth_dev_shared_data->data[port_id].name;
+ /*
+ * Use the shared data name rather than rte_eth_devices[].data->name
+ * because VDEV PMDs may overwrite the per-process data pointer.
+ */
+ size_t n = strlcpy(name, eth_dev_shared_data->data[port_id].name, size);
rte_spinlock_unlock(rte_mcfg_ethdev_get_lock());
- strcpy(name, tmp);
+ if (n >= size) {
+ RTE_ETHDEV_LOG_LINE(ERR,
+ "ethdev port %u name exceeds buffer size %zu",
+ port_id, size);
+ return -ERANGE;
+ }
rte_ethdev_trace_get_name_by_port(port_id, name);
return 0;
}
+/* new ABI version: bounded copy using caller-provided size */
+RTE_DEFAULT_SYMBOL(27, int, rte_eth_dev_get_name_by_port,
+ (uint16_t port_id, char *name, size_t size))
+{
+ return eth_dev_get_name_by_port(port_id, name, size);
+}
+
+/* old ABI version: delegate to new version with max buffer size */
+RTE_VERSION_SYMBOL(26, int, rte_eth_dev_get_name_by_port,
+ (uint16_t port_id, char *name))
+{
+ return eth_dev_get_name_by_port(port_id, name, RTE_ETH_NAME_MAX_LEN);
+}
+
RTE_EXPORT_SYMBOL(rte_eth_dev_get_port_by_name)
int
rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id)
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index 3f4d2438e4..17c000dbf2 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -5691,14 +5691,18 @@ rte_eth_dev_get_port_by_name(const char *name, uint16_t *port_id);
* @param port_id
* Port identifier of the device.
* @param name
- * Buffer of size RTE_ETH_NAME_MAX_LEN to store the name.
+ * Buffer to store the name.
+ * @param size
+ * Size of the buffer pointed to by @p name. Should be at least
+ * RTE_ETH_NAME_MAX_LEN bytes.
* @return
* - (0) if successful.
* - (-ENODEV) if *port_id* is invalid.
- * - (-EINVAL) on failure.
+ * - (-EINVAL) if *name* is NULL or *size* is 0.
+ * - (-ERANGE) if the buffer is too small for the device name.
*/
int
-rte_eth_dev_get_name_by_port(uint16_t port_id, char *name);
+rte_eth_dev_get_name_by_port(uint16_t port_id, char *name, size_t size);
/**
* Check that numbers of Rx and Tx descriptors satisfy descriptors limits from
diff --git a/lib/pdump/rte_pdump.c b/lib/pdump/rte_pdump.c
index ac94efe7ff..ba36949b01 100644
--- a/lib/pdump/rte_pdump.c
+++ b/lib/pdump/rte_pdump.c
@@ -726,7 +726,7 @@ pdump_validate_flags(uint32_t flags)
}
static int
-pdump_validate_port(uint16_t port, char *name)
+pdump_validate_port(uint16_t port, char *name, size_t name_size)
{
int ret = 0;
@@ -736,7 +736,7 @@ pdump_validate_port(uint16_t port, char *name)
return -1;
}
- ret = rte_eth_dev_get_name_by_port(port, name);
+ ret = rte_eth_dev_get_name_by_port(port, name, name_size);
if (ret < 0) {
PDUMP_LOG_LINE(ERR, "port %u to name mapping failed",
port);
@@ -818,7 +818,7 @@ pdump_enable(uint16_t port, uint16_t queue,
int ret;
char name[RTE_DEV_NAME_MAX_LEN];
- ret = pdump_validate_port(port, name);
+ ret = pdump_validate_port(port, name, sizeof(name));
if (ret < 0)
return ret;
ret = pdump_validate_ring_mp(ring, mp);
@@ -912,7 +912,7 @@ rte_pdump_disable(uint16_t port, uint16_t queue, uint32_t flags)
int ret = 0;
char name[RTE_DEV_NAME_MAX_LEN];
- ret = pdump_validate_port(port, name);
+ ret = pdump_validate_port(port, name, sizeof(name));
if (ret < 0)
return ret;
ret = pdump_validate_flags(flags);
--
2.53.0
^ permalink raw reply related
* [PATCH v2 4/4] net/bonding: remove redundant function names from log
From: Stephen Hemminger @ 2026-05-28 23:59 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Chas Williams, Min Hu (Connor)
In-Reply-To: <20260529000157.235931-1-stephen@networkplumber.org>
The function name is already printed as part of RTE_BOND_LOG().
Fix grammar in log messages.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
drivers/net/bonding/rte_eth_bond_api.c | 4 ++--
drivers/net/bonding/rte_eth_bond_pmd.c | 23 ++++++++++-------------
2 files changed, 12 insertions(+), 15 deletions(-)
diff --git a/drivers/net/bonding/rte_eth_bond_api.c b/drivers/net/bonding/rte_eth_bond_api.c
index 9e5df67c18..d9b6f1c417 100644
--- a/drivers/net/bonding/rte_eth_bond_api.c
+++ b/drivers/net/bonding/rte_eth_bond_api.c
@@ -485,8 +485,8 @@ __eth_bond_member_add_lock_free(uint16_t bonding_port_id, uint16_t member_port_i
ret = rte_eth_dev_info_get(member_port_id, &dev_info);
if (ret != 0) {
RTE_BOND_LOG(ERR,
- "%s: Error during getting device (port %u) info: %s",
- __func__, member_port_id, strerror(-ret));
+ "Error getting device (port %u) info: %s",
+ member_port_id, strerror(-ret));
return ret;
}
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index 8a9c329fb8..6a4f997b5a 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -210,8 +210,8 @@ bond_ethdev_8023ad_flow_verify(struct rte_eth_dev *bond_dev,
int ret = rte_flow_validate(member_port, &flow_attr_8023ad,
flow_item_8023ad, actions, &error);
if (ret < 0) {
- RTE_BOND_LOG(ERR, "%s: %s (member_port=%d queue_id=%d)",
- __func__, error.message, member_port,
+ RTE_BOND_LOG(ERR, "%s (member_port=%u queue_id=%u)",
+ error.message, member_port,
internals->mode4.dedicated_queues.rx_qid);
return -1;
}
@@ -219,8 +219,8 @@ bond_ethdev_8023ad_flow_verify(struct rte_eth_dev *bond_dev,
ret = rte_eth_dev_info_get(member_port, &member_info);
if (ret != 0) {
RTE_BOND_LOG(ERR,
- "%s: Error during getting device (port %u) info: %s",
- __func__, member_port, strerror(-ret));
+ "Error getting device (port %u) info: %s",
+ member_port, strerror(-ret));
return ret;
}
@@ -228,8 +228,8 @@ bond_ethdev_8023ad_flow_verify(struct rte_eth_dev *bond_dev,
if (member_info.max_rx_queues < bond_dev->data->nb_rx_queues ||
member_info.max_tx_queues < bond_dev->data->nb_tx_queues) {
RTE_BOND_LOG(ERR,
- "%s: Member %d capabilities doesn't allow allocating additional queues",
- __func__, member_port);
+ "Member %u capabilities doesn't allow allocating additional queues",
+ member_port);
return -1;
}
@@ -249,9 +249,8 @@ bond_8023ad_slow_pkt_hw_filter_supported(uint16_t port_id) {
ret = rte_eth_dev_info_get(bond_dev->data->port_id, &bond_info);
if (ret != 0) {
RTE_BOND_LOG(ERR,
- "%s: Error during getting device (port %u) info: %s",
- __func__, bond_dev->data->port_id,
- strerror(-ret));
+ "Error getting device (port %u) info: %s",
+ bond_dev->data->port_id, strerror(-ret));
return ret;
}
@@ -2346,10 +2345,8 @@ bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
ret = rte_eth_dev_info_get(member.port_id, &member_info);
if (ret != 0) {
RTE_BOND_LOG(ERR,
- "%s: Error during getting device (port %u) info: %s",
- __func__,
- member.port_id,
- strerror(-ret));
+ "Error getting device (port %u) info: %s",
+ member.port_id, strerror(-ret));
return ret;
}
--
2.53.0
^ permalink raw reply related
* [PATCH v2 3/4] net/bonding: prevent crash on Rx/Tx from secondary process
From: Stephen Hemminger @ 2026-05-28 23:59 UTC (permalink / raw)
To: dev
Cc: Stephen Hemminger, stable, Chas Williams, Min Hu (Connor),
Anatoly Burakov, Qi Zhang
In-Reply-To: <20260529000157.235931-1-stephen@networkplumber.org>
The bonding PMD's secondary process attach path registered the
ethdev but never installed rx_pkt_burst or tx_pkt_burst, leaving
both as NULL. Any rx_burst or tx_burst call from a secondary
process therefore crashed with a NULL pointer dereference.
Fully sharing bonding state across processes would be
overly complex. Instead, install blackhole burst functions
in the secondary so the data path is safe by default. Rx returns 0
and Tx frees the mbufs and reports them as transmitted,
matching /dev/null semantics so applications do not spin
retrying. Each stub logs once at NOTICE level on first use.
Also reject bond mode changes from a secondary process.
rte_eth_bond_mode_set() is callable from secondary, and
without this guard it would overwrite the secondary's safe
burst stubs with real per-mode functions whose internal
state is not valid outside the primary, reintroducing the
crash by another path.
This keeps secondary support available for the more
common use cases of procinfo and packet capture.
Bugzilla ID: 1698
Fixes: 4852aa8f6e21 ("drivers/net: enable hotplug on secondary process")
Cc: stable@dpdk.org
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
drivers/net/bonding/rte_eth_bond_pmd.c | 43 +++++++++++++++++++++++++-
1 file changed, 42 insertions(+), 1 deletion(-)
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index 7fcb3ec7d7..8a9c329fb8 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -56,6 +56,33 @@ get_vlan_offset(struct rte_ether_hdr *eth_hdr, uint16_t *proto)
return vlan_offset;
}
+static uint16_t
+bond_ethdev_rx_secondary(void *queue __rte_unused,
+ struct rte_mbuf **bufs __rte_unused, uint16_t nb_pkts __rte_unused)
+{
+ static bool once = true;
+
+ if (once) {
+ /* once per process is enough of a notice */
+ RTE_BOND_LOG(ERR, "receive not supported in secondary");
+ once = false;
+ }
+ return 0;
+}
+
+static uint16_t
+bond_ethdev_tx_secondary(void *queue __rte_unused, struct rte_mbuf **bufs, uint16_t nb_pkts)
+{
+ static bool once = true;
+
+ if (once) {
+ RTE_BOND_LOG(ERR, "transmit not supported in secondary");
+ once = false;
+ }
+ rte_pktmbuf_free_bulk(bufs, nb_pkts);
+ return nb_pkts;
+}
+
static uint16_t
bond_ethdev_rx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
{
@@ -1599,6 +1626,11 @@ bond_ethdev_mode_set(struct rte_eth_dev *eth_dev, uint8_t mode)
{
struct bond_dev_private *internals;
+ if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
+ RTE_BOND_LOG(ERR, "Setting mode in secondary not allowed");
+ return -1;
+ }
+
internals = eth_dev->data->dev_private;
switch (mode) {
@@ -3798,9 +3830,18 @@ bond_probe(struct rte_vdev_device *dev)
RTE_BOND_LOG(ERR, "Failed to probe %s", name);
return -1;
}
- /* TODO: request info from primary to set up Rx and Tx */
+
eth_dev->dev_ops = &default_dev_ops;
eth_dev->device = &dev->device;
+
+ /*
+ * Propagation of bond mode would require adding
+ * MP client/server support and lots of error handling.
+ *
+ * For now just install a black hole.
+ */
+ eth_dev->tx_pkt_burst = bond_ethdev_tx_secondary;
+ eth_dev->rx_pkt_burst = bond_ethdev_rx_secondary;
rte_eth_dev_probing_finish(eth_dev);
return 0;
}
--
2.53.0
^ permalink raw reply related
* [PATCH v2 2/4] net/bonding: check mode before setting dedicated queues
From: Stephen Hemminger @ 2026-05-28 23:59 UTC (permalink / raw)
To: dev
Cc: Stephen Hemminger, stable, Chas Williams, Min Hu (Connor),
Declan Doherty, Tomasz Kulasek
In-Reply-To: <20260529000157.235931-1-stephen@networkplumber.org>
The calls to enable and disable dedicated queues are missing
check for mode.
Fixes: 112891cd27e5 ("net/bonding: add dedicated HW queues for LACP control")
Cc: stable@dpdk.org
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
drivers/net/bonding/rte_eth_bond_8023ad.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c
index eba713e381..d1f30229d0 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.c
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.c
@@ -1725,7 +1725,6 @@ RTE_EXPORT_SYMBOL(rte_eth_bond_8023ad_dedicated_queues_enable)
int
rte_eth_bond_8023ad_dedicated_queues_enable(uint16_t port)
{
- int retval = 0;
struct rte_eth_dev *dev;
struct bond_dev_private *internals;
@@ -1742,17 +1741,19 @@ rte_eth_bond_8023ad_dedicated_queues_enable(uint16_t port)
if (dev->data->dev_started)
return -1;
+ if (internals->mode != BONDING_MODE_8023AD)
+ return -1;
+
internals->mode4.dedicated_queues.enabled = 1;
bond_ethdev_mode_set(dev, internals->mode);
- return retval;
+ return 0;
}
RTE_EXPORT_SYMBOL(rte_eth_bond_8023ad_dedicated_queues_disable)
int
rte_eth_bond_8023ad_dedicated_queues_disable(uint16_t port)
{
- int retval = 0;
struct rte_eth_dev *dev;
struct bond_dev_private *internals;
@@ -1766,9 +1767,12 @@ rte_eth_bond_8023ad_dedicated_queues_disable(uint16_t port)
if (dev->data->dev_started)
return -1;
+ if (internals->mode != BONDING_MODE_8023AD)
+ return -1;
+
internals->mode4.dedicated_queues.enabled = 0;
bond_ethdev_mode_set(dev, internals->mode);
- return retval;
+ return 0;
}
--
2.53.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox