* [PATCH 2/3] eventdev: improve bounds checks for names in adapter create
From: Bruce Richardson @ 2026-06-23 14:19 UTC (permalink / raw)
To: dev; +Cc: Bruce Richardson, stable, Naga Harish K S V, Jerin Jacob,
Nikhil Rao
In-Reply-To: <20260623141930.704771-1-bruce.richardson@intel.com>
The bounds checks for snprintf and then strncpy used different constant
defines, which happened to resolve to the same value (32). Make this
code more resilient by using sizeof() operator rather than the defines,
and replace use of strncpy with the better strlcpy.
Fixes: a3bbf2e09756 ("eventdev: add eth Tx adapter implementation")
Cc: stable@dpdk.org
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
lib/eventdev/rte_event_eth_tx_adapter.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/eventdev/rte_event_eth_tx_adapter.c b/lib/eventdev/rte_event_eth_tx_adapter.c
index 91c7be55c7..d531da5d69 100644
--- a/lib/eventdev/rte_event_eth_tx_adapter.c
+++ b/lib/eventdev/rte_event_eth_tx_adapter.c
@@ -748,7 +748,7 @@ txa_service_adapter_create_ext(uint8_t id, struct rte_eventdev *dev,
return -EINVAL;
socket_id = dev->data->socket_id;
- snprintf(mem_name, TXA_MEM_NAME_LEN,
+ snprintf(mem_name, sizeof(mem_name),
"rte_event_eth_txa_%d",
id);
@@ -767,7 +767,7 @@ txa_service_adapter_create_ext(uint8_t id, struct rte_eventdev *dev,
txa->id = id;
txa->eventdev_id = dev->data->dev_id;
txa->socket_id = socket_id;
- strncpy(txa->mem_name, mem_name, TXA_SERVICE_NAME_LEN);
+ strlcpy(txa->mem_name, mem_name, sizeof(txa->mem_name));
txa->conf_cb = conf_cb;
txa->conf_arg = conf_arg;
txa->service_id = TXA_INVALID_SERVICE_ID;
--
2.53.0
^ permalink raw reply related
* [PATCH 1/3] ethdev: remove use of strncpy
From: Bruce Richardson @ 2026-06-23 14:19 UTC (permalink / raw)
To: dev
Cc: Bruce Richardson, stable, Thomas Monjalon, Andrew Rybchenko,
Harman Kalra, Ferruh Yigit
In-Reply-To: <20260623141930.704771-1-bruce.richardson@intel.com>
The use of strncpy is not generally recommended, so replace it in code
tokenizing the representor list. Since its use in the function is not
involving null-terminated strings (we know that copied block will
not involve a null value in it), we can replace strncpy with memcpy
rather than a string function. This keeps the original intent of the
code.
For extra safety, also add in an explicit bounds check on the length
value before doing the memcpy.
Fixes: 9a9eb104edf6 ("ethdev: parse multiple representor devargs")
Cc: stable@dpdk.org
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
lib/ethdev/ethdev_driver.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/lib/ethdev/ethdev_driver.c b/lib/ethdev/ethdev_driver.c
index 70ddce5bfc..4043ce898f 100644
--- a/lib/ethdev/ethdev_driver.c
+++ b/lib/ethdev/ethdev_driver.c
@@ -583,10 +583,15 @@ eth_dev_tokenise_representor_list(char *p_val, struct rte_eth_devargs *eth_devar
return devargs;
}
+ /* len - 2 strips the outer '[' and ']'; guard against underflow and overflow */
+ if (len < 2 || (len - 2) >= BUFSIZ) {
+ RTE_ETHDEV_LOG_LINE(ERR, "Representor list too long or malformed: %s", p_val);
+ return -EINVAL;
+ }
memset(str, 0, BUFSIZ);
memset(da_val, 0, BUFSIZ);
/* Remove the exterior [] of the consolidated list */
- strncpy(str, &p_val[1], len - 2);
+ memcpy(str, &p_val[1], len - 2);
while (1) {
if (str[i] == '\0') {
if (da_val[0] != '\0') {
--
2.53.0
^ permalink raw reply related
* [PATCH 0/3] lib: remove use of strncpy
From: Bruce Richardson @ 2026-06-23 14:19 UTC (permalink / raw)
To: dev; +Cc: Bruce Richardson
Taking a lead from the kernel, which has just finished a multi-year
effort to remove use of strncpy[1], rework DPDK to remove use of the
same function. This series removes all remaining uses of strncpy
in lib directory.
[1] https://www.phoronix.com/news/Linux-7.2-Drops-strncpy
Bruce Richardson (3):
ethdev: remove use of strncpy
eventdev: improve bounds checks for names in adapter create
vhost: remove use of strncpy
lib/ethdev/ethdev_driver.c | 7 ++++++-
lib/eventdev/rte_event_eth_tx_adapter.c | 4 ++--
lib/vhost/socket.c | 4 +---
lib/vhost/vduse.c | 2 +-
lib/vhost/vhost.c | 12 +++---------
lib/vhost/vhost.h | 2 +-
6 files changed, 14 insertions(+), 17 deletions(-)
--
2.53.0
^ permalink raw reply
* Re: [PATCH v5] graph: add optional profiling stats
From: saeed bishara @ 2026-06-23 14:10 UTC (permalink / raw)
To: Morten Brørup
Cc: Jerin Jacob, dev, Jerin Jacob, Kiran Kumar K, Nithin Dabilpuram,
Zhirun Yan
In-Reply-To: <98CBD80474FA8B44BF855DF32C47DC35F6593A@smartserver.smartshare.dk>
> > also, instead of adding cacheline for this profiling data, can we
> > share with line 1 that used solely for xstats?
>
> This profiling data is 4 indexes * 2 values * 8-byte fields, so one cache line in itself.
make sense.
btw, the default value of RTE_GRAPH_BURST_SIZE is 256, I suspect that
real applications will enforce smaller burst when pulling from input
devices (e.g. 32). Do you expect such cases to change
RTE_GRAPH_BURST_SIZE?
^ permalink raw reply
* DPDK Release Status Meeting 2026-06-23
From: Mcnamara, John @ 2026-06-23 14:02 UTC (permalink / raw)
To: dev@dpdk.org; +Cc: Thomas Monjalon, David Marchand
[-- Attachment #1: Type: text/plain, Size: 2792 bytes --]
Release status meeting minutes 2026-06-23
=========================================
Agenda:
- Release Dates
- Subtrees
- Roadmaps
- LTS
- Defects
- Opens
Participants:
- ARM
- Broadcom
- Debian
- Intel
- Marvell
- Nvidia
- Red Hat
- Stephen Hemminger
Release Dates
-------------
The following are the proposed working dates for 27.03:
| Date | Milestone | Description |
|-----------------|------------------|---------------------------------|
| 30 April 2026 | RFC/v1 patches | Proposal deadline |
| 11 June 2026 | 26.07-rc1 | API freeze |
| 25 June 2026 | 26.07-rc2 | PMD features freeze |
| 02 July 2026 | 26.07-rc3 | Builtin apps features freeze |
| 9 July 2026 | 26.07-rc4 | Documentation ready |
| 16 July 2026 | 26.07.0 | Release |
See https://core.dpdk.org/roadmap/
Subtrees
--------
- next-net
- 76 patches ready for main.
- 26 patches in review/waiting.
- next-net-intel
- 6 patches merged, ready for main
- Small backlog.
- next-net-mlx
- Some patches getting ready for pull.
- next-broadcom
- Most patches merged.
- 1-2 in backlog.
- next-net-mvl
- PR sent.
- next-eventdev
- No change.
- next-baseband
- Nothing pending.
- next-virtio
- Nothing pending.
- next-crypto
- No update.
- next-dts
- No update.
- main
- BUS refactoring.
- DMA driver to review.
- Started pulling trees for RC2.
- RC2 targeting June 29 2026.
Other
-----
- None.
LTS
---
See also: https://core.dpdk.org/roadmap/#stable
LTS versions ongoing/released:
- 25.11.3 - In progress.
- 24.11.7 - In progress.
- 23.11.8 - In progress.
Older releases:
- 20.11.10 - Will only be updated with CVE and critical fixes.
- 19.11.14 - Will only be updated with CVE and critical fixes.
- Distros
- Debian 13 contains DPDK v24.11
- Ubuntu 25.04 contains DPDK v24.11
- Ubuntu 24.04 LTS contains DPDK v23.11
- RHEL 9 contains DPDK 24.11
Defects
-------
- Bugzilla links, 'Bugs', added for hosted projects
- https://www.dpdk.org/hosted-projects/
DPDK Release Status Meetings
----------------------------
The DPDK Release Status Meeting is intended for DPDK Committers to discuss the
status of the main tree and sub-trees, and for project managers to track
progress or milestone dates.
The meeting occurs on every Tuesday at 14:30 DST over Jitsi on https://meet.jit.si/DPDK
You don't need an invite to join the meeting but if you want a calendar reminder just
send an email to "John McNamara <john.mcnamara@intel.com>" for the invite.
[-- Attachment #2: Type: text/html, Size: 35226 bytes --]
^ permalink raw reply
* RE: [PATCH v3 6/6] test/bpf: check that bpf_convert can be JIT'd
From: Marat Khalili @ 2026-06-23 13:57 UTC (permalink / raw)
To: Stephen Hemminger, dev@dpdk.org; +Cc: Konstantin Ananyev
In-Reply-To: <20260621162524.82690-7-stephen@networkplumber.org>
Thank you for working on this, please see some comments inline.
> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Sunday 21 June 2026 17:24
> To: dev@dpdk.org
> Cc: Stephen Hemminger <stephen@networkplumber.org>; Konstantin Ananyev <konstantin.ananyev@huawei.com>;
> Marat Khalili <marat.khalili@huawei.com>
> Subject: [PATCH v3 6/6] test/bpf: check that bpf_convert can be JIT'd
>
> Add followup in bpf conversion tests to make sure resulting
> code was also run through JIT and that JIT produces
> same results as non-JIT.
>
> Reduce log output to make it easier to match which
> expression might be causing issues.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
> app/test/test_bpf.c | 94 +++++++++++++++++++++++++++++++++++++--------
> 1 file changed, 79 insertions(+), 15 deletions(-)
>
> diff --git a/app/test/test_bpf.c b/app/test/test_bpf.c
> index 3a88434c3c..973dd7d659 100644
> --- a/app/test/test_bpf.c
> +++ b/app/test/test_bpf.c
> @@ -8,6 +8,7 @@
> #include <inttypes.h>
> #include <unistd.h>
>
> +#include <rte_byteorder.h>
> #include <rte_memory.h>
> #include <rte_debug.h>
> #include <rte_hexdump.h>
> @@ -32,6 +33,7 @@ test_bpf(void)
> #include <rte_bpf.h>
> #include <rte_ether.h>
> #include <rte_ip.h>
> +#include <rte_udp.h>
>
>
> /* Tests of most simple BPF programs (no instructions, one instruction etc.) */
> @@ -4529,6 +4531,7 @@ test_bpf_match(pcap_t *pcap, const char *str,
> int ret = -1;
> uint64_t rc;
>
> + printf("%s '%s'\n", __func__, str);
> if (pcap_compile(pcap, &fcode, str, 1, PCAP_NETMASK_UNKNOWN)) {
> printf("%s@%d: pcap_compile(\"%s\") failed: %s;\n",
> __func__, __LINE__, str, pcap_geterr(pcap));
> @@ -4550,6 +4553,24 @@ test_bpf_match(pcap_t *pcap, const char *str,
> }
>
> rc = rte_bpf_exec(bpf, mb);
> +#if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_ARM64)
We are going to have a few of these lines, I think something like
RTE_BPF_JIT_SUPPORTED is warranted.
> + {
> + struct rte_bpf_jit jit;
> +
> + rte_bpf_get_jit(bpf, &jit);
Out of abundance of caution I would also prefill jit with zeroes and check the
return code here.
> + if (jit.func == NULL) {
> + printf("%s@%d: no JIT generated\n", __func__, __LINE__);
> + goto error;
> + }
> +
> + fflush(stdout);
> + uint64_t rc_jit = jit.func(mb);
> + if (rc_jit != rc) {
> + printf("%s@%d: JIT return code does not match\n", __func__, __LINE__);
> + goto error;
> + }
> + }
> +#endif
> /* The return code from bpf capture filter is non-zero if matched */
> ret = (rc == 0);
> error:
> @@ -4560,23 +4581,16 @@ test_bpf_match(pcap_t *pcap, const char *str,
> return ret;
> }
>
> -/* Basic sanity test can we match a IP packet */
> -static int
> -test_bpf_filter_sanity(pcap_t *pcap)
> +/* Setup mbuf for filter test */
> +static void
> +dummy_ip_prep(void *data, uint16_t plen)
> {
> - const uint32_t plen = 100;
> - struct rte_mbuf mb, *m;
> - uint8_t tbuf[RTE_MBUF_DEFAULT_BUF_SIZE];
> struct {
> struct rte_ether_hdr eth_hdr;
> struct rte_ipv4_hdr ip_hdr;
> - } *hdr;
> + struct rte_udp_hdr udp_hdr;
> + } *hdr = data;
>
> - memset(&mb, 0, sizeof(mb));
> - dummy_mbuf_prep(&mb, tbuf, sizeof(tbuf), plen);
> - m = &mb;
> -
> - hdr = rte_pktmbuf_mtod(m, typeof(hdr));
> hdr->eth_hdr = (struct rte_ether_hdr) {
> .dst_addr.addr_bytes = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
> .ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4),
> @@ -4589,13 +4603,32 @@ test_bpf_filter_sanity(pcap_t *pcap)
> .src_addr = rte_cpu_to_be_32(RTE_IPV4_LOOPBACK),
> .dst_addr = rte_cpu_to_be_32(RTE_IPV4_BROADCAST),
> };
> + hdr->udp_hdr = (struct rte_udp_hdr) {
> + .src_port = rte_rand_max(UINT16_MAX),
> + .dst_port = rte_cpu_to_be_16(9), /* discard port */
> + .dgram_len = rte_cpu_to_be_16(plen - sizeof(struct rte_ipv4_hdr)),
> + .dgram_cksum = 0,
> + };
> +}
> +
> +
> +/* Basic sanity test can we match a IP packet */
> +static int
> +test_bpf_filter_sanity(pcap_t *pcap)
> +{
> + struct rte_mbuf mb = { 0 };
> + uint8_t tbuf[RTE_MBUF_DEFAULT_BUF_SIZE];
> + const uint32_t plen = 100;
> +
> + dummy_mbuf_prep(&mb, tbuf, sizeof(tbuf), plen);
> + dummy_ip_prep(rte_pktmbuf_mtod(&mb, void *), plen);
>
> - if (test_bpf_match(pcap, "ip", m) != 0) {
> + if (test_bpf_match(pcap, "ip", &mb) != 0) {
> printf("%s@%d: filter \"ip\" doesn't match test data\n",
> __func__, __LINE__);
> return -1;
> }
> - if (test_bpf_match(pcap, "not ip", m) == 0) {
> + if (test_bpf_match(pcap, "not ip", &mb) == 0) {
Not a new bug, but this condition should be for non-positive, not just zero.
> printf("%s@%d: filter \"not ip\" does match test data\n",
> __func__, __LINE__);
> return -1;
> @@ -4648,10 +4681,15 @@ static const char * const sample_filters[] = {
> static int
> test_bpf_filter(pcap_t *pcap, const char *s)
> {
> + struct rte_mbuf mb = { 0 };
> + uint8_t tbuf[RTE_MBUF_DEFAULT_BUF_SIZE];
> + const uint32_t plen = 100;
> struct bpf_program fcode;
> struct rte_bpf_prm *prm = NULL;
> struct rte_bpf *bpf = NULL;
> + int ret = -1;
>
> + printf("%s '%s'\n", __func__, s);
> if (pcap_compile(pcap, &fcode, s, 1, PCAP_NETMASK_UNKNOWN)) {
> printf("%s@%d: pcap_compile('%s') failed: %s;\n",
> __func__, __LINE__, s, pcap_geterr(pcap));
> @@ -4665,8 +4703,10 @@ test_bpf_filter(pcap_t *pcap, const char *s)
> goto error;
> }
>
> +#ifdef DEBUG
> printf("bpf convert for \"%s\" produced:\n", s);
> rte_bpf_dump(stdout, prm->ins, prm->nb_ins);
> +#endif
>
> bpf = rte_bpf_load(prm);
> if (bpf == NULL) {
> @@ -4675,6 +4715,30 @@ test_bpf_filter(pcap_t *pcap, const char *s)
> goto error;
> }
>
> + dummy_mbuf_prep(&mb, tbuf, sizeof(tbuf), plen);
> + dummy_ip_prep(rte_pktmbuf_mtod(&mb, void *), plen);
> +
> + uint64_t rc = rte_bpf_exec(bpf, &mb);
Would it be hard to check the result against a known correct answer?
> +#if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_ARM64)
> + {
> + struct rte_bpf_jit jit;
> +
> + rte_bpf_get_jit(bpf, &jit);
Same suggestion regarding zeroing jit and check return code here.
> + if (jit.func == NULL) {
> + printf("%s@%d: no JIT generated\n", __func__, __LINE__);
> + goto error;
> + }
> +
> + fflush(stdout);
> + uint64_t rc_jit = jit.func(&mb);
> + if (rc_jit != rc) {
> + printf("%s@%d: JIT return code does not match\n", __func__, __LINE__);
> + goto error;
> + }
> + }
> +#endif
> + ret = 0;
> +
Are `test_bpf_filter` and `test_bpf_filter_sanity` substantially different any
more, or could they just be merged?
> error:
> if (bpf)
> rte_bpf_destroy(bpf);
> @@ -4685,7 +4749,7 @@ test_bpf_filter(pcap_t *pcap, const char *s)
>
> rte_free(prm);
> pcap_freecode(&fcode);
> - return (bpf == NULL) ? -1 : 0;
> + return ret;
> }
>
> static int
> --
> 2.53.0
^ permalink raw reply
* Re: [PATCH v4] pcapng: add user-supplied timestamp support
From: Stephen Hemminger @ 2026-06-23 13:53 UTC (permalink / raw)
To: Dawid Wesierski; +Cc: dev, mb, Marek Kasiewicz
In-Reply-To: <20260623141302.486601-1-dawid.wesierski@intel.com>
On Tue, 23 Jun 2026 10:10:11 -0400
Dawid Wesierski <dawid.wesierski@intel.com> wrote:
> +/*
> + * Compatibility wrapper: captures current TSC (converted at write time).
> + * Equivalent to rte_pcapng_copy_ts(..., 0).
> + */
> +RTE_EXPORT_SYMBOL(rte_pcapng_copy)
> +struct rte_mbuf *
> +rte_pcapng_copy(uint16_t port_id, uint32_t queue,
> + const struct rte_mbuf *md,
> + struct rte_mempool *mp,
> + uint32_t length,
> + enum rte_pcapng_direction direction,
> + const char *comment)
> +{
> + return rte_pcapng_copy_ts(port_id, queue, md, mp, length, direction,
> + comment, 0);
> +}
> +
> +/*
> + * Convert a TSC value to nanoseconds since the Unix epoch using the
> + * calibrated clock of the capture file. Uses the same pre-computed
> + * reciprocal multiplier as the internal write path (no integer division).
> + */
> +RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_pcapng_tsc_to_ns, 26.07)
> +uint64_t
> +rte_pcapng_tsc_to_ns(const rte_pcapng_t *self, uint64_t tsc)
> +{
> + return tsc_to_ns_epoch(&self->clock, tsc);
> +}
Why not just use function versioning on rte_pcapng_copy() to add new parameter?
Also should add a coverage test app/test/test_pcapng.c
^ permalink raw reply
* Re: [PATCH 0/5] add versioned symbols for recently stabilized APIs
From: David Marchand @ 2026-06-23 13:50 UTC (permalink / raw)
To: Dariusz Sosnowski, Thomas Monjalon, dpdk-techboard
Cc: Bruce Richardson, Andrew Rybchenko, Viacheslav Ovsiienko,
Bing Zhao, Ori Kam, Suanming Mou, Matan Azrad, dev
In-Reply-To: <20260623113752.1100072-1-dsosnowski@nvidia.com>
Hello Dariusz,
On Tue, 23 Jun 2026 at 13:38, Dariusz Sosnowski <dsosnowski@nvidia.com> wrote:
>
> Main goal of this patchset is to address https://bugs.dpdk.org/show_bug.cgi?id=1957
It is expected that experimental symbols may disappear overnight, and
this bug could also be closed as NOTABUG.
On the other hand, we do state in the doc that compatibility could be
provided when stabilising an experimental API, so ok.. let's try.
> but it also handles other recently stabilized symbols and has some minor fixes:
>
> - Patch 1 - Fix RTE_VERSION_EXPERIMENTAL_SYMBOL macro on clang.
Ouch... /me hides.
> - Patch 2 - Allow function versioning inside drivers.
> - Patch 3 - Version the function symbols stabilized in
> https://git.dpdk.org/dpdk/commit/?id=e8cab133645f5466ef75e511629add43b68a5027
> - Patch 4 - Introduce versioning macros for global variable symbols.
> - Patch 5 - Version the function and variable symbols stabilized in
> https://git.dpdk.org/dpdk/commit/?id=4ee2f5c1cedf9ee7f39afa667f71b07f4004ba5c
>
> Issue is still not fully fixed for stabilized global variables:
> rte_flow_dynf_metadata_offs and rte_flow_dynf_metadata_mask.
Well, symbol versioning is not something for variables.
Exposing global variables was a mistake from the start...
Those were exported for "performance" reasons as those are accessed
via inline helpers (but I am not sure there were benchmarks showing
the benefits).
I am for forbidding exports of global variables from now, unless some
really good performance benchmark is provided (@techboard for info).
Now, in practice for your issue, rather than reintroducing symbol
aliases (technical solution that I dropped when refactoring the
macros), I think we can do with some middle ground approach:
- leaving the inline helpers as "stable" (not __rte_experimental),
- restoring the EXPERIMENTAL version on the global variables, this
will restore the location of those symbols from the previous ABI pov,
and the checks won't catch this discrepancy anyway,
- during 26.11, drop the EXPERIMENTAL version on those variables,
In other words, stopping at your patch 3 of the series, then adding:
$ git diff
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index ec0fe08355..8bd21ccd31 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_SYMBOL(rte_flow_dynf_metadata_offs)
+RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_dynf_metadata_offs, 19.11)
int32_t rte_flow_dynf_metadata_offs = -1;
/* Mbuf dynamic field flag bit number for metadata. */
-RTE_EXPORT_SYMBOL(rte_flow_dynf_metadata_mask)
+RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_flow_dynf_metadata_mask, 19.11)
uint64_t rte_flow_dynf_metadata_mask;
/**
> Patch 4 and 5 address the bug for these global variables,
> by providing a single storage for both EXPERIMENTAL and
> DPDK_26 variable symbol versions.
> This is achieved through symbol aliasing.
> But this solution is limited only to executables compiled with clang.
>
> clang and gcc have a different default behavior regarding relocations
> of global variables exposed by shared libraries.
>
Yeah... not even thinking about adding MSVC in the list...
--
David Marchand
^ permalink raw reply related
* Re: [PATCH 1/5] eal: fix macro for versioned experimental symbol
From: Stephen Hemminger @ 2026-06-23 13:50 UTC (permalink / raw)
To: Dariusz Sosnowski; +Cc: David Marchand, dev, Bruce Richardson
In-Reply-To: <20260623113752.1100072-2-dsosnowski@nvidia.com>
On Tue, 23 Jun 2026 13:37:47 +0200
Dariusz Sosnowski <dsosnowski@nvidia.com> wrote:
> Add a missing semicolon after __asm__ block in
> RTE_VERSION_EXPERIMENTAL_SYMBOL macro.
> It's lack triggers the following compilation error with clang:
>
> ../lib/ethdev/rte_flow.c:320:1: error: expected ';' after top-level asm block
> 320 | RTE_VERSION_EXPERIMENTAL_SYMBOL(int, rte_flow_dynf_metadata_register, (void))
> | ^
> ../lib/eal/common/eal_export.h:75:74: note: expanded from macro 'RTE_VERSION_EXPERIMENTAL_SYMBOL'
> 75 | __asm__(".symver " RTE_STR(name) "_exp, " RTE_STR(name) "@EXPERIMENTAL") \
> | ^
> ../lib/eal/include/rte_common.h:237:20: note: expanded from macro '\
> __rte_used'
> 237 | #define __rte_used __attribute__((used))
> | ^
>
> Fixes: e30e194c4d06 ("eal: rework function versioning macros")
> Cc: david.marchand@redhat.com
>
> Signed-
I didn't see this because clang doesn't have symver support.
Which version of clang is this?
^ permalink raw reply
* Re: [PATCH 0/5] add versioned symbols for recently stabilized APIs
From: Stephen Hemminger @ 2026-06-23 13:48 UTC (permalink / raw)
To: Dariusz Sosnowski
Cc: Thomas Monjalon, David Marchand, Bruce Richardson,
Andrew Rybchenko, Viacheslav Ovsiienko, Bing Zhao, Ori Kam,
Suanming Mou, Matan Azrad, dev
In-Reply-To: <20260623113752.1100072-1-dsosnowski@nvidia.com>
On Tue, 23 Jun 2026 13:37:46 +0200
Dariusz Sosnowski <dsosnowski@nvidia.com> wrote:
> Main goal of this patchset is to address https://bugs.dpdk.org/show_bug.cgi?id=1957
> but it also handles other recently stabilized symbols and has some minor fixes:
>
> - Patch 1 - Fix RTE_VERSION_EXPERIMENTAL_SYMBOL macro on clang.
> - Patch 2 - Allow function versioning inside drivers.
> - Patch 3 - Version the function symbols stabilized in
> https://git.dpdk.org/dpdk/commit/?id=e8cab133645f5466ef75e511629add43b68a5027
> - Patch 4 - Introduce versioning macros for global variable symbols.
> - Patch 5 - Version the function and variable symbols stabilized in
> https://git.dpdk.org/dpdk/commit/?id=4ee2f5c1cedf9ee7f39afa667f71b07f4004ba5c
>
> Issue is still not fully fixed for stabilized global variables:
> rte_flow_dynf_metadata_offs and rte_flow_dynf_metadata_mask.
> Patch 4 and 5 address the bug for these global variables,
> by providing a single storage for both EXPERIMENTAL and
> DPDK_26 variable symbol versions.
> This is achieved through symbol aliasing.
> But this solution is limited only to executables compiled with clang.
>
> clang and gcc have a different default behavior regarding relocations
> of global variables exposed by shared libraries.
>
> With clang, R_X86_64_GLOB_DAT relocations are generated for executables:
>
> $ readelf -sW build-26.07/lib/librte_ethdev.so | grep rte_flow_dynf_metadata_offs
> 113: 00000000000ea4c0 4 OBJECT GLOBAL DEFAULT 24 rte_flow_dynf_metadata_offs@@DPDK_26
> 116: 00000000000ea4c0 4 OBJECT GLOBAL DEFAULT 24 rte_flow_dynf_metadata_offs@EXPERIMENTAL
> 970: 00000000000ea4c0 4 OBJECT LOCAL DEFAULT 24 rte_flow_dynf_metadata_offs_impl
> 1212: 00000000000ea4c0 4 OBJECT LOCAL DEFAULT 24 rte_flow_dynf_metadata_offs_v26
> 1325: 00000000000ea4c0 4 OBJECT LOCAL DEFAULT 24 rte_flow_dynf_metadata_offs_exp
> 1415: 00000000000ea4c0 4 OBJECT GLOBAL DEFAULT 24 rte_flow_dynf_metadata_offs@@DPDK_26
> 1705: 00000000000ea4c0 4 OBJECT GLOBAL DEFAULT 24 rte_flow_dynf_metadata_offs@EXPERIMENTAL
>
> $ readelf -rW build-26.07/drivers/librte_net_mlx5.so | grep rte_flow_dynf_metadata_offs
> 0000000003ed5f18 0000001600000006 R_X86_64_GLOB_DAT 0000000000000000 rte_flow_dynf_metadata_offs@DPDK_26 + 0
>
> $ readelf -rW build-25.11/app/dpdk-testpmd | grep rte_flow_dynf_metadata_offs
> --> 000000000028ef70 0000011300000006 R_X86_64_GLOB_DAT 0000000000000000 rte_flow_dynf_metadata_offs@EXPERIMENTAL + 0
>
> With gcc, R_X86_64_COPY relocations are generated:
>
> $ readelf -sW build-26.07/lib/librte_ethdev.so | grep rte_flow_dynf_metadata_offs
> 113: 00000000000e74e0 4 OBJECT GLOBAL DEFAULT 24 rte_flow_dynf_metadata_offs@@DPDK_26
> 116: 00000000000e74e0 4 OBJECT GLOBAL DEFAULT 24 rte_flow_dynf_metadata_offs@EXPERIMENTAL
> 1471: 00000000000e74e0 4 OBJECT LOCAL DEFAULT 24 rte_flow_dynf_metadata_offs_impl
> 2134: 00000000000e74e0 4 OBJECT LOCAL DEFAULT 24 rte_flow_dynf_metadata_offs_v26
> 2247: 00000000000e74e0 4 OBJECT LOCAL DEFAULT 24 rte_flow_dynf_metadata_offs_exp
> 2337: 00000000000e74e0 4 OBJECT GLOBAL DEFAULT 24 rte_flow_dynf_metadata_offs@@DPDK_26
> 2627: 00000000000e74e0 4 OBJECT GLOBAL DEFAULT 24 rte_flow_dynf_metadata_offs@EXPERIMENTAL
>
> $ readelf -rW build-26.07/drivers/librte_net_mlx5.so | grep rte_flow_dynf_metadata_offs
> 00000000046dbef0 0000001600000006 R_X86_64_GLOB_DAT 0000000000000000 rte_flow_dynf_metadata_offs@DPDK_26 + 0
>
> $ readelf -rW build-25.11/app/dpdk-testpmd | grep rte_flow_dynf_metadata_offs
> --> 000000000029b540 000001d200000005 R_X86_64_COPY 000000000029b540 rte_flow_dynf_metadata_offs@EXPERIMENTAL + 0
>
> With copy relocations (testpmd linked through gcc) the following happens:
>
> - When variable symbol (with EXPERIMENTAL version) gets resolved inside executable,
> global variable gets copied from read-only data to executable's BSS section.
> Executable will access this variable through BSS.
> - When variable symbol (with DPDK_26 version) gets resolved inside a library,
> global variable is accessed indirectly through GOT.
> It is stored inside BSS section of the shared library.
>
> So executable and libraries refer to different storage,
> eventually leading to inconsistent runtime behavior.
> Problems only appears when executable and library require
> different versions of global variable symbol.
> If testpmd from 26.07 is used with libraries from 26.07,
> GOT entry for these variables will point to copied variable.
>
> Without copy relocations (testpmd linked through clang) both
> executable and libraries access the global variable indirectly through GOT.
> Runtime behavior is consistent, regardless of the mix of variable symbol versions.
>
> The only other solution I could find was to use dlsym() inside libraries
> to dynamically resolve the location rte_flow_dynf_metadata_offs and rte_flow_dynf_metadata_mask,
> but this solution sounds like an overkill.
> Essentially this would require moving to getter/setter functions for these variables
> inside the library.
>
> I would appreciate any feedback or suggestions if anybody had encountered a similar issue before.
>
> Dariusz Sosnowski (5):
> eal: fix macro for versioned experimental symbol
> drivers: support function versioning
> net/mlx5: fix stabilized function versions
> eal: support aliases for versioned variable symbols
> ethdev: fix promoted flow metadata symbols
>
> buildtools/gen-version-map.py | 11 ++++++++++
> drivers/meson.build | 8 +++++++
> drivers/net/mlx5/meson.build | 2 ++
> drivers/net/mlx5/mlx5_driver_event.c | 22 ++++++++++++++-----
> drivers/net/mlx5/mlx5_flow.c | 18 ++++++++++-----
> lib/eal/common/eal_export.h | 24 +++++++++++++++++++-
> lib/ethdev/meson.build | 2 ++
> lib/ethdev/rte_flow.c | 33 ++++++++++++++++++----------
> 8 files changed, 96 insertions(+), 24 deletions(-)
>
> --
> 2.47.3
>
The bugfix is good, but not sure the rest is needed right now.
It is getting late to add more stuff for 26.07 and in 26.11 function versioning
will not be needed.
^ permalink raw reply
* [PATCH v4] pcapng: add user-supplied timestamp support
From: Dawid Wesierski @ 2026-06-23 14:10 UTC (permalink / raw)
To: dev; +Cc: dawid.wesierski, stephen, mb, Marek Kasiewicz
In-Reply-To: <20260618143819.310046-1-dawid.wesierski@intel.com>
From: "Wesierski, Dawid" <dawid.wesierski@intel.com>
Introduce rte_pcapng_copy_ts() alongside the existing rte_pcapng_copy()
so that callers with a hardware PTP or pre-captured timestamp can inject
an exact epoch-ns value directly into the packet record.
Timestamp handling in rte_pcapng_copy_ts():
- ts != 0: caller-supplied nanoseconds since the Unix epoch, stored as-is.
- ts == 0: TSC captured at copy time with bit 63 set as a sentinel.
rte_pcapng_write_packets() detects the sentinel and converts the TSC to
epoch ns using the file's calibrated clock. The TSC will not reach
bit 63 for centuries, and epoch-ns values stay below bit 63 until 2554,
so the bit is safe to use as a disambiguation flag.
rte_pcapng_copy() is retained as a real exported function (not an inline
wrapper) so the stable ABI symbol is preserved. It simply calls
rte_pcapng_copy_ts(..., 0) to capture the current TSC.
rte_pcapng_tsc_to_ns() is added as a new experimental helper (addressing
review requests from Stephen Hemminger and Morten Brørup). It exposes the
same calibrated, drift-compensated, divide-free TSC-to-epoch-ns conversion
used internally by rte_pcapng_write_packets(), allowing callers to convert
a TSC captured at packet arrival time before passing it to
rte_pcapng_copy_ts().
Signed-off-by: Marek Kasiewicz <marek.kasiewicz@intel.com>
Signed-off-by: Dawid Wesierski <dawid.wesierski@intel.com>
---
Hi Stephen, Morten,
Thank you very much for your review and comments.
I have prepared a v4 patch.
ABI failure > I have restored rte_pcapng_copy() as a real exported function instead of a static inline wrapper.
This should fix the iol-abi-testing failure. It now simply calls rte_pcapng_copy_ts(..., 0) internally.
As suggested, I've added a new experimental function uint64_t rte_pcapng_tsc_to_ns(const rte_pcapng_t *self, uint64_t tsc);
I exposed the internal calibrated clock state maintained by the pcapng.
Regards,
Dawid Węsierski.
.mailmap | 2 ++
lib/pcapng/rte_pcapng.c | 71 +++++++++++++++++++++++++++++++++--------
lib/pcapng/rte_pcapng.h | 64 +++++++++++++++++++++++++++++++++++++
3 files changed, 124 insertions(+), 13 deletions(-)
diff --git a/.mailmap b/.mailmap
index 4001e5fb0e..a7d97a631e 100644
--- a/.mailmap
+++ b/.mailmap
@@ -366,6 +366,7 @@ David Zeng <zengxhsh@cn.ibm.com>
Davide Caratti <dcaratti@redhat.com>
Dawid Gorecki <dgr@semihalf.com>
Dawid Jurczak <dawid_jurek@vp.pl>
+Dawid Wesierski <dawid.wesierski@intel.com> Wesierski, Dawid <dawid.wesierski@intel.com>
Dawid Zielinski <dawid.zielinski@intel.com>
Dawid Łukwiński <dawid.lukwinski@intel.com>
Daxue Gao <daxuex.gao@intel.com>
@@ -1014,6 +1015,7 @@ Marcin Wilk <marcin.wilk@caviumnetworks.com>
Marcin Wojtas <mw@semihalf.com>
Marcin Zapolski <marcinx.a.zapolski@intel.com>
Marco Varlese <mvarlese@suse.de>
+Marek Kasiewicz <marek.kasiewicz@intel.com>
Marek Mical <marekx.mical@intel.com>
Marek Zalfresso-jundzillo <marekx.zalfresso-jundzillo@intel.com>
Maria Lingemark <maria.lingemark@ericsson.com>
diff --git a/lib/pcapng/rte_pcapng.c b/lib/pcapng/rte_pcapng.c
index b5d1026891..f583fae995 100644
--- a/lib/pcapng/rte_pcapng.c
+++ b/lib/pcapng/rte_pcapng.c
@@ -546,14 +546,14 @@ pcapng_vlan_insert(struct rte_mbuf *m, uint16_t ether_type, uint16_t tci)
*/
/* Make a copy of original mbuf with pcapng header and options */
-RTE_EXPORT_SYMBOL(rte_pcapng_copy)
+RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_pcapng_copy_ts, 26.07)
struct rte_mbuf *
-rte_pcapng_copy(uint16_t port_id, uint32_t queue,
+rte_pcapng_copy_ts(uint16_t port_id, uint32_t queue,
const struct rte_mbuf *md,
struct rte_mempool *mp,
uint32_t length,
enum rte_pcapng_direction direction,
- const char *comment)
+ const char *comment, uint64_t ts)
{
struct pcapng_enhance_packet_block *epb;
uint32_t orig_len, pkt_len, padding, flags;
@@ -690,8 +690,20 @@ rte_pcapng_copy(uint16_t port_id, uint32_t queue,
/* Interface index is filled in later during write */
mc->port = port_id;
- /* Put timestamp in cycles here - adjust in packet write */
- timestamp = rte_get_tsc_cycles();
+ /*
+ * Timestamp handling:
+ * - If the caller supplied an explicit timestamp (ts != 0), it is
+ * already in nanoseconds since the Unix epoch, so store it as-is.
+ * - If the caller did not (ts == 0), store the current TSC and set
+ * the high bit as a sentinel so rte_pcapng_write_packets() knows
+ * it must convert TSC -> epoch ns at write time. The TSC counter
+ * will not reach bit 63 for centuries, and epoch-ns values stay
+ * below bit 63 until the year 2554, so the bit is safe to use.
+ */
+ if (ts != 0)
+ timestamp = ts;
+ else
+ timestamp = rte_get_tsc_cycles() | (UINT64_C(1) << 63);
epb->timestamp_hi = timestamp >> 32;
epb->timestamp_lo = (uint32_t)timestamp;
epb->capture_length = pkt_len;
@@ -707,6 +719,35 @@ rte_pcapng_copy(uint16_t port_id, uint32_t queue,
return NULL;
}
+/*
+ * Compatibility wrapper: captures current TSC (converted at write time).
+ * Equivalent to rte_pcapng_copy_ts(..., 0).
+ */
+RTE_EXPORT_SYMBOL(rte_pcapng_copy)
+struct rte_mbuf *
+rte_pcapng_copy(uint16_t port_id, uint32_t queue,
+ const struct rte_mbuf *md,
+ struct rte_mempool *mp,
+ uint32_t length,
+ enum rte_pcapng_direction direction,
+ const char *comment)
+{
+ return rte_pcapng_copy_ts(port_id, queue, md, mp, length, direction,
+ comment, 0);
+}
+
+/*
+ * Convert a TSC value to nanoseconds since the Unix epoch using the
+ * calibrated clock of the capture file. Uses the same pre-computed
+ * reciprocal multiplier as the internal write path (no integer division).
+ */
+RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_pcapng_tsc_to_ns, 26.07)
+uint64_t
+rte_pcapng_tsc_to_ns(const rte_pcapng_t *self, uint64_t tsc)
+{
+ return tsc_to_ns_epoch(&self->clock, tsc);
+}
+
/* Write pre-formatted packets to file. */
RTE_EXPORT_SYMBOL(rte_pcapng_write_packets)
ssize_t
@@ -720,7 +761,7 @@ rte_pcapng_write_packets(rte_pcapng_t *self,
for (i = 0; i < nb_pkts; i++) {
struct rte_mbuf *m = pkts[i];
struct pcapng_enhance_packet_block *epb;
- uint64_t cycles, timestamp;
+ uint64_t timestamp;
/* sanity check that is really a pcapng mbuf */
epb = rte_pktmbuf_mtod(m, struct pcapng_enhance_packet_block *);
@@ -738,14 +779,18 @@ rte_pcapng_write_packets(rte_pcapng_t *self,
}
/*
- * When data is captured by pcapng_copy the current TSC is stored.
- * Adjust the value recorded in file to PCAP epoch units.
+ * If rte_pcapng_copy[_ts]() stored a TSC value (high bit set
+ * as sentinel), convert it to nanoseconds since the Unix epoch
+ * using the per-file clock. Otherwise the timestamp is already
+ * in epoch ns and is written unchanged.
*/
- cycles = (uint64_t)epb->timestamp_hi << 32;
- cycles += epb->timestamp_lo;
- timestamp = tsc_to_ns_epoch(&self->clock, cycles);
- epb->timestamp_hi = timestamp >> 32;
- epb->timestamp_lo = (uint32_t)timestamp;
+ timestamp = ((uint64_t)epb->timestamp_hi << 32) | epb->timestamp_lo;
+ if (timestamp & (UINT64_C(1) << 63)) {
+ timestamp &= ~(UINT64_C(1) << 63);
+ timestamp = tsc_to_ns_epoch(&self->clock, timestamp);
+ epb->timestamp_hi = timestamp >> 32;
+ epb->timestamp_lo = (uint32_t)timestamp;
+ }
/*
* Handle case of highly fragmented and large burst size
diff --git a/lib/pcapng/rte_pcapng.h b/lib/pcapng/rte_pcapng.h
index d8d328f710..6eeaeada05 100644
--- a/lib/pcapng/rte_pcapng.h
+++ b/lib/pcapng/rte_pcapng.h
@@ -108,9 +108,50 @@ enum rte_pcapng_direction {
RTE_PCAPNG_DIRECTION_OUT = 2,
};
+/**
+ * Format an mbuf with a caller-supplied timestamp for writing to file.
+ *
+ * @param port_id
+ * The Ethernet port on which packet was received
+ * or is going to be transmitted.
+ * @param queue
+ * The queue on the Ethernet port where packet was received
+ * or is going to be transmitted.
+ * @param mp
+ * The mempool from which the "clone" mbufs are allocated.
+ * @param m
+ * The mbuf to copy
+ * @param length
+ * The upper limit on bytes to copy. Passing UINT32_MAX
+ * means all data (after offset).
+ * @param direction
+ * The direction of the packer: receive, transmit or unknown.
+ * @param comment
+ * Optional per packet comment.
+ * Truncated to UINT16_MAX characters.
+ * @param ts
+ * Packet timestamp in nanoseconds since the Unix epoch. If zero, the
+ * current TSC is captured and converted to epoch ns by
+ * rte_pcapng_write_packets() when the packet is written.
+ *
+ * @return
+ * - The pointer to the new mbuf formatted for pcapng_write
+ * - NULL on error such as invalid port or out of memory.
+ */
+__rte_experimental
+struct rte_mbuf *
+rte_pcapng_copy_ts(uint16_t port_id, uint32_t queue,
+ const struct rte_mbuf *m, struct rte_mempool *mp,
+ uint32_t length,
+ enum rte_pcapng_direction direction, const char *comment,
+ uint64_t ts);
+
/**
* Format an mbuf for writing to file.
*
+ * Equivalent to rte_pcapng_copy_ts() with ts=0: the current TSC is
+ * captured at copy time and converted to epoch ns at write time.
+ *
* @param port_id
* The Ethernet port on which packet was received
* or is going to be transmitted.
@@ -153,6 +194,29 @@ rte_pcapng_copy(uint16_t port_id, uint32_t queue,
uint32_t
rte_pcapng_mbuf_size(uint32_t length);
+/**
+ * Convert a TSC value to nanoseconds since the Unix epoch.
+ *
+ * Uses the same calibrated clock reference as the capture file so that
+ * the result is consistent with timestamps written by
+ * rte_pcapng_write_packets(). The conversion is drift-compensated and
+ * uses a pre-computed reciprocal multiplier (no integer division).
+ *
+ * Typical use: convert a TSC timestamp captured close to packet arrival
+ * (e.g., from a PMD or hardware register) to an epoch-ns value before
+ * passing it to rte_pcapng_copy_ts().
+ *
+ * @param self
+ * The handle to the packet capture file.
+ * @param tsc
+ * TSC value to convert.
+ * @return
+ * Nanoseconds since the Unix epoch corresponding to @p tsc.
+ */
+__rte_experimental
+uint64_t
+rte_pcapng_tsc_to_ns(const rte_pcapng_t *self, uint64_t tsc);
+
/**
* Write packets to the capture file.
*
--
2.47.3
---------------------------------------------------------------------
Intel Technology Poland sp. z o.o.
ul. Slowackiego 173 | 80-298 Gdansk | Sad Rejonowy Gdansk Polnoc | VII Wydzial Gospodarczy Krajowego Rejestru Sadowego - KRS 101882 | NIP 957-07-52-316 | Kapital zakladowy 200.000 PLN.
Spolka oswiadcza, ze posiada status duzego przedsiebiorcy w rozumieniu ustawy z dnia 8 marca 2013 r. o przeciwdzialaniu nadmiernym opoznieniom w transakcjach handlowych.
Ta wiadomosc wraz z zalacznikami jest przeznaczona dla okreslonego adresata i moze zawierac informacje poufne. W razie przypadkowego otrzymania tej wiadomosci, prosimy o powiadomienie nadawcy oraz trwale jej usuniecie; jakiekolwiek przegladanie lub rozpowszechnianie jest zabronione.
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). If you are not the intended recipient, please contact the sender and delete all copies; any review or distribution by others is strictly prohibited.
^ permalink raw reply related
* Re: [PATCH] common/cnxk: fix inline dev null dereference
From: Jerin Jacob @ 2026-06-23 13:35 UTC (permalink / raw)
To: Aarnav JP
Cc: dev, Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori,
Satha Rao, Harman Kalra, Rakesh Kudurumalla, jerinj, rbhansali,
stable
In-Reply-To: <20260623085433.3190541-1-ajp@marvell.com>
On Tue, Jun 23, 2026 at 2:31 PM Aarnav JP <ajp@marvell.com> wrote:
>
> inl_dev is initialized to NULL and only assigned within the
> if (idev && idev->nix_inl_dev) block.
> Move inl_dev->res_addr_offset and inl_dev->cpt_cq_ena
> accesses inside this null-guarded block in
> nix_inl_inb_ipsec_sa_tbl_setup() and nix_inl_reass_inb_sa_tbl_setup()
> to avoid dereferencing a null pointer.
>
> Fixes: 3fdf3e53f3c4 ("common/cnxk: enable CPT CQ for inline IPsec inbound")
> Cc: stable@dpdk.org
>
> Signed-off-by: Aarnav JP <ajp@marvell.com>
Applied to dpdk-next-net-mrvl/for-main. Thanks
^ permalink raw reply
* Re: [PATCH] net/mlx5: fix double free in vectorized Rx recovery
From: Dariusz Sosnowski @ 2026-06-23 12:50 UTC (permalink / raw)
To: Borys Tsyrulnikov
Cc: Thomas Monjalon, Viacheslav Ovsiienko, Bing Zhao, Ori Kam,
Suanming Mou, Matan Azrad, Alexander Kozyrev, dev, stable
In-Reply-To: <20260617134301.798213-1-tsyrulnikov.borys@gmail.com>
On Wed, Jun 17, 2026 at 04:43:01PM +0300, Borys Tsyrulnikov wrote:
> During Rx queue error recovery, the vectorized path in
> mlx5_rx_err_handle() reallocates an mbuf for every queue element. When
> rte_mbuf_raw_alloc() fails (for example, the mempool is exhausted), the
> rollback loop frees the mbufs allocated so far, but masks the element
> ring index with "& elts_n" instead of "& (elts_n - 1)".
>
> elts_n is a power-of-two element count, so "x & elts_n" isolates a
> single bit and can only evaluate to 0 or elts_n, regardless of the loop
> counter. The rollback therefore never frees the mbufs just allocated in
> this pass (they are leaked); instead it repeatedly frees elts[0], a live
> mbuf still posted to the NIC (use-after-free / double free), and
> elts[elts_n], the fake_mbuf padding entry used by the vector datapath.
>
> Mask with the existing e_mask (elts_n - 1), as already done in the
> matching forward allocation loop just above.
>
> Fixes: 0f20acbf5eda ("net/mlx5: implement vectorized MPRQ burst")
> Cc: stable@dpdk.org
>
> Signed-off-by: Borys Tsyrulnikov <tsyrulnikov.borys@gmail.com>
Acked-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
^ permalink raw reply
* Re: [PATCH v3 05/25] bpf/validate: introduce debugging interface
From: Thomas Monjalon @ 2026-06-23 12:29 UTC (permalink / raw)
To: Marat Khalili; +Cc: Konstantin Ananyev, dev@dpdk.org
In-Reply-To: <84ce7f7669404239864c61819267d9b6@huawei.com>
23/06/2026 12:29, Marat Khalili:
> > -----Original Message-----
> > From: Thomas Monjalon <thomas@monjalon.net>
> > Sent: Tuesday 23 June 2026 11:19
> > To: Marat Khalili <marat.khalili@huawei.com>
> > Cc: Konstantin Ananyev <konstantin.ananyev@huawei.com>; dev@dpdk.org
> > Subject: Re: [PATCH v3 05/25] bpf/validate: introduce debugging interface
> >
> > 12/06/2026 12:47, Marat Khalili:
> > > +#ifndef LIST_FOREACH_SAFE
> > > +/* We need this macro which neither Linux nor EAL for Linux include yet. */
> > > +#define LIST_FOREACH_SAFE(var, head, field, tvar) \
> > > + for ((var) = LIST_FIRST((head)); \
> > > + (var) && ((tvar) = LIST_NEXT((var), field), 1); \
> > > + (var) = (tvar))
> > > +#else
> > > +#ifdef RTE_EXEC_ENV_LINUX
> > > +#error "Don't need LIST_FOREACH_SAFE in this version of DPDK anymore, remove it."
> > > +#endif
> > > +#endif
> >
> > It fails on Alpine Linux.
> > Why adding this #error?
> >
>
> This is interesting. My mental model was that Linux is never going to have
> LIST_FOREACH_SAFE, but DPDK will eventually gain its own polyfill. I was
> actually expecting it to happen before my patch is published, so this was a
> reminder to remove my own definition since it clearly belongs to some common
> library. Turns out I was wrong on both accounts: there are Linuxes that define
> LIST_FOREACH_SAFE, and I managed to submit faster. Apart from these
> organizational issues the whole else branch can be safely removed. Do you want
> me to submit an updated version?
Yes would be nice so we will have a full CI run on it
now that the dependency is merged in main.
^ permalink raw reply
* RE: [PATCH v5] graph: add optional profiling stats
From: Morten Brørup @ 2026-06-23 12:04 UTC (permalink / raw)
To: saeed bishara
Cc: Jerin Jacob, dev, Jerin Jacob, Kiran Kumar K, Nithin Dabilpuram,
Zhirun Yan
In-Reply-To: <CAHfVqdWKoDqb0uD_HrF8e=GqadThPhZj0vZnRYDW=KMPei0mXQ@mail.gmail.com>
> From: saeed bishara [mailto:saeed.bishara.os@gmail.com]
> Sent: Tuesday, 23 June 2026 10.34
>
> > > > > + /** Fast path area cache line 3. */
> > > > > +#ifdef RTE_GRAPH_PROFILE
> > > > > + struct {
> > > > > + uint64_t calls; /**< Calls
> processing
> > > > resp. 0 or 1 objects. */
> > > > > + uint64_t cycles; /**< Cycles spent
> > > > processing resp. 0 or 1 objects. */
> > > > > + } usage_stats[2]; /**< Usage when this
> node
> > > > processed 0 or 1 objects. */
> > > > > + uint64_t full_burst_calls; /**< Calls
> processing a
> > > > full burst of objects. */
> > > > > + uint64_t full_burst_cycles; /**< Cycles spent
> > > > processing a full burst of objects. */
> > > > > + uint64_t half_burst_calls; /**< Calls
> processing a
> > > > half burst of objects. */
> > > > > + uint64_t half_burst_cycles; /**< Cycles spent
> > > > processing a half burst of objects. */
> > > > > + /** Fast path area cache line 4. */
> > > > > +#endif
> > > >
> > > > Is it an ABI breakage?
> Can you consider one array for all cases?
Ack.
> also, instead of adding cacheline for this profiling data, can we
> share with line 1 that used solely for xstats?
This profiling data is 4 indexes * 2 values * 8-byte fields, so one cache line in itself.
^ permalink raw reply
* Re: [PATCH v1 0/5] prefix lcore role enum values
From: lihuisong (C) @ 2026-06-23 11:52 UTC (permalink / raw)
To: David Marchand
Cc: Stephen Hemminger, Morten Brørup, thomas, andrew.rybchenko,
dev, zhanjie9
In-Reply-To: <CAJFAV8yNsZ_SLcG-ukzmDTQXRXDsGVtf-9szwSc6T2GM+fhE_Q@mail.gmail.com>
On 6/22/2026 4:18 PM, David Marchand wrote:
> Hello all,
>
> On Mon, 22 Jun 2026 at 03:23, lihuisong (C) <lihuisong@huawei.com> wrote:
>> On 6/19/2026 10:03 AM, Stephen Hemminger wrote:
>>> On Wed, 17 Jun 2026 13:48:37 +0200
>>> Morten Brørup <mb@smartsharesystems.com> wrote:
>>>
>>>>> From: Huisong Li [mailto:lihuisong@huawei.com]
>>>>> Sent: Wednesday, 17 June 2026 12.28
>>>>>
>>>>> Add the RTE_LCORE_ prefix to the lcore role enum values in
>>>>> rte_lcore_role_t
>>>>> to follow DPDK naming conventions.
>>>>>
>>>>> - ROLE_RTE -> RTE_LCORE_ROLE_RTE
>>>>> - ROLE_OFF -> RTE_LCORE_ROLE_OFF
>>>>> - ROLE_SERVICE -> RTE_LCORE_ROLE_SERVICE
>>>>> - ROLE_NON_EAL -> RTE_LCORE_ROLE_NON_EAL
>>>>>
>>>>> Old names are kept as macros aliasing to the new names to preserve
>>>>> backward compatibility.
>>>>>
>>>> Series-Acked-by: Morten Brørup <mb@smartsharesystems.com>
>>>>
>>> The problem with this patch it causes build failures now with abi diff.
>>>
>>> Example build log...
>>>
>>>
>>> 2 functions with some indirect sub-type change:
>>>
>>>
>>>
>>>
>>>
>>> [C] 'function rte_lcore_role_t rte_eal_lcore_role(unsigned int)' at eal_common_lcore.c:74:1 has some indirect sub-type changes:
>>>
>>> return type changed:
>>>
>>> type size hasn't changed
>>>
>>> 4 enumerator deletions:
>>>
>>> 'rte_lcore_role_t::ROLE_RTE' value '0'
>>>
>>> 'rte_lcore_role_t::ROLE_OFF' value '1'
>>>
>>> 'rte_lcore_role_t::ROLE_SERVICE' value '2'
>>>
>>> 'rte_lcore_role_t::ROLE_NON_EAL' value '3'
>>>
>>> 4 enumerator insertions:
>>>
>>> 'rte_lcore_role_t::RTE_LCORE_ROLE_RTE' value '0'
>>>
>>> 'rte_lcore_role_t::RTE_LCORE_ROLE_OFF' value '1'
>>>
>>> 'rte_lcore_role_t::RTE_LCORE_ROLE_SERVICE' value '2'
>>>
>>> 'rte_lcore_role_t::RTE_LCORE_ROLE_NON_EAL' value '3'
>>>
>>>
>>>
>>>
>>>
>>> [C] 'function int rte_lcore_has_role(unsigned int, rte_lcore_role_t)' at eal_common_lcore.c:85:1 has some indirect sub-type changes:
>>>
>>> parameter 2 of type 'enum rte_lcore_role_t' has sub-type changes:
>>>
>>> enum type 'enum rte_lcore_role_t' changed at rte_lcore.h:33:1, as reported earlier
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> Error: ABI issue reported for abidiff --suppr /home/runner/work/dpdk/dpdk/devtools/libabigail.abignore --no-added-syms --headers-dir1 reference/usr/local/include --headers-dir2 install/usr/local/include reference/usr/local/lib/librte_eal.so.26.1 install/usr/local/lib/librte_eal.so.26.2
>> We just came back from the Dragon Boat Festival.
>> I also received this ABI change warning. But I didn't have any good
>> ideas yet.
>> Thanks for helping to handle this.
>> Sorry for the inconvenience.
> There is nothing broken from a ABI pov.
> This is a limitation in earlier versions of libabigail.
> I can't reproduce with libabigail 2.9 (update in progress as I see
> 2.10 is available now).
>
> I think it was solved in libabigail 2.8
> (https://sourceware.org/git/?p=libabigail.git;a=commit;h=6f5f91564bdd).
This seems to solve the problem.
>
> If we want to go with the enum renaming before 26.11, bumping
> libabigail to 2.10 in the CI is an option (latest upstream version,
> and this is the version in f43 and f44).
> I tried it in GHA:
> https://github.com/david-marchand/dpdk/actions/runs/27937595115/job/82662953500
I also tested it based on libabigail 2.9.0 version. No any warning.
-->
abidiff build-ref/lib/librte_eal.so build-new/lib/librte_eal.so
Functions changes summary: 0 Removed, 0 Changed (2 filtered out), 0
Added functions
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
>
>
^ permalink raw reply
* [PATCH 5/5] ethdev: fix promoted flow metadata symbols
From: Dariusz Sosnowski @ 2026-06-23 11:37 UTC (permalink / raw)
To: Thomas Monjalon, Andrew Rybchenko, Ori Kam
Cc: dev, David Marchand, Bruce Richardson, Yu Jiang
In-Reply-To: <20260623113752.1100072-1-dsosnowski@nvidia.com>
Offending patch stabilized the following symbols:
- 1 function symbol:
- rte_flow_dynf_metadata_register
- 2 global variable symbols:
- rte_flow_dynf_metadata_offs
- rte_flow_dynf_metadata_mask
Any application using these flow metadata symbols,
which was linked dynamically against 25.11 version of ethdev
library and using current version of ethdev library
would fail on symbol resolution, because EXPERIMENTAL versions
were not exported.
Specifically, on application start up
variable symbol lookup error happens:
/tmp/dpdk-25.11/usr/local/bin/dpdk-testpmd:
symbol lookup error: /tmp/dpdk-25.11/usr/local/bin/dpdk-testpmd:
undefined symbol: rte_flow_dynf_metadata_offs, version EXPERIMENTAL
This error occurss because symbol lookup for global variables
happens on application startup.
This patch addresses that by adding versioned aliases
for the following variable symbols:
- rte_flow_dynf_metadata_offs
- rte_flow_dynf_metadata_mask
Versioned function symbols are also added
for rte_flow_dynf_metadata_register().
Bugzilla ID: 1957
Fixes: 4ee2f5c1cedf ("ethdev: promote flow metadata API to stable")
Reported-by: Yu Jiang <yux.jiang@intel.com>
Signed-off-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
---
lib/ethdev/meson.build | 2 ++
lib/ethdev/rte_flow.c | 33 ++++++++++++++++++++++-----------
2 files changed, 24 insertions(+), 11 deletions(-)
diff --git a/lib/ethdev/meson.build b/lib/ethdev/meson.build
index 8ba6c708a2..63fd866af9 100644
--- a/lib/ethdev/meson.build
+++ b/lib/ethdev/meson.build
@@ -1,6 +1,8 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
+use_function_versioning = true
+
sources = files(
'ethdev_driver.c',
'ethdev_private.c',
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index ec0fe08355..a8c01ffe8a 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -23,12 +23,20 @@
#define FLOW_LOG RTE_ETHDEV_LOG_LINE
/* Mbuf dynamic field name for metadata. */
-RTE_EXPORT_SYMBOL(rte_flow_dynf_metadata_offs)
-int32_t rte_flow_dynf_metadata_offs = -1;
+static int32_t rte_flow_dynf_metadata_offs_impl = -1;
+
+RTE_DEFAULT_SYMBOL_ALIAS(26, int32_t, rte_flow_dynf_metadata_offs,
+ rte_flow_dynf_metadata_offs_impl);
+RTE_VERSION_EXPERIMENTAL_SYMBOL_ALIAS(int32_t, rte_flow_dynf_metadata_offs,
+ rte_flow_dynf_metadata_offs_impl);
/* Mbuf dynamic field flag bit number for metadata. */
-RTE_EXPORT_SYMBOL(rte_flow_dynf_metadata_mask)
-uint64_t rte_flow_dynf_metadata_mask;
+static uint64_t rte_flow_dynf_metadata_mask_impl = 0;
+
+RTE_DEFAULT_SYMBOL_ALIAS(26, uint64_t, rte_flow_dynf_metadata_mask,
+ rte_flow_dynf_metadata_mask_impl);
+RTE_VERSION_EXPERIMENTAL_SYMBOL_ALIAS(uint64_t, rte_flow_dynf_metadata_mask,
+ rte_flow_dynf_metadata_mask_impl);
/**
* Flow elements description tables.
@@ -281,9 +289,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_SYMBOL(rte_flow_dynf_metadata_register)
-int
-rte_flow_dynf_metadata_register(void)
+RTE_DEFAULT_SYMBOL(26, int, rte_flow_dynf_metadata_register, (void))
{
int offset;
int flag;
@@ -303,19 +309,24 @@ rte_flow_dynf_metadata_register(void)
flag = rte_mbuf_dynflag_register(&desc_flag);
if (flag < 0)
goto error;
- rte_flow_dynf_metadata_offs = offset;
- rte_flow_dynf_metadata_mask = RTE_BIT64(flag);
+ rte_flow_dynf_metadata_offs_impl = offset;
+ rte_flow_dynf_metadata_mask_impl = RTE_BIT64(flag);
rte_flow_trace_dynf_metadata_register(offset, RTE_BIT64(flag));
return 0;
error:
- rte_flow_dynf_metadata_offs = -1;
- rte_flow_dynf_metadata_mask = UINT64_C(0);
+ rte_flow_dynf_metadata_offs_impl = -1;
+ rte_flow_dynf_metadata_mask_impl = UINT64_C(0);
return -rte_errno;
}
+RTE_VERSION_EXPERIMENTAL_SYMBOL(int, rte_flow_dynf_metadata_register, (void))
+{
+ return rte_flow_dynf_metadata_register();
+}
+
static inline void
fts_enter(struct rte_eth_dev *dev)
{
--
2.47.3
^ permalink raw reply related
* [PATCH 4/5] eal: support aliases for versioned variable symbols
From: Dariusz Sosnowski @ 2026-06-23 11:37 UTC (permalink / raw)
To: Bruce Richardson; +Cc: dev, David Marchand
In-Reply-To: <20260623113752.1100072-1-dsosnowski@nvidia.com>
Existing symbol versioning macros are not suitable for versioning
exported global variables.
Specifically, if existing macros are used for versioning
global variable symbol promoted from experimental to stable,
result would be multiple variables with separate storage defined.
If an application was linked against older DPDK and had copy
relocations, this would yield an inconsistent behavior:
- Application would use experimental symbol version,
with storage set up in BSS section in application.
- Library would use latest symbol version,
with storage set up in BSS section of shared object.
This patch adds versioning macros which utilize symbol aliasing.
Specifically, a new variable (with version suffix) is defined
as an alias to private (static) variable inside the library.
Variable symbol versions are attached to these alias variables.
Following macros are added:
- RTE_VERSION_EXPERIMENTAL_SYMBOL_ALIAS
- RTE_DEFAULT_SYMBOL_ALIAS
Signed-off-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
---
buildtools/gen-version-map.py | 11 +++++++++++
lib/eal/common/eal_export.h | 22 ++++++++++++++++++++++
2 files changed, 33 insertions(+)
diff --git a/buildtools/gen-version-map.py b/buildtools/gen-version-map.py
index 57e08a8c0f..aa88e69179 100755
--- a/buildtools/gen-version-map.py
+++ b/buildtools/gen-version-map.py
@@ -14,8 +14,12 @@
export_int_sym_regexp = re.compile(r"^RTE_EXPORT_INTERNAL_SYMBOL\(([^)]+)\)")
export_sym_regexp = re.compile(r"^RTE_EXPORT_SYMBOL\(([^)]+)\)")
ver_sym_regexp = re.compile(r"^RTE_VERSION_SYMBOL\(([^,]+), [^,]+, ([^,]+),")
+
ver_exp_sym_regexp = re.compile(r"^RTE_VERSION_EXPERIMENTAL_SYMBOL\([^,]+, ([^,]+),")
+ver_exp_sym_alias_regexp = re.compile(r"^RTE_VERSION_EXPERIMENTAL_SYMBOL_ALIAS\([^,]+, ([^,]+),")
+
default_sym_regexp = re.compile(r"^RTE_DEFAULT_SYMBOL\(([^,]+), [^,]+, ([^,]+),")
+default_sym_alias_regexp = re.compile(r"^RTE_DEFAULT_SYMBOL_ALIAS\(([^,]+), [^,]+, ([^,]+),")
parser = argparse.ArgumentParser(
description=__doc__,
@@ -73,10 +77,17 @@
elif ver_exp_sym_regexp.match(ln):
node = "EXPERIMENTAL"
symbol = ver_exp_sym_regexp.match(ln).group(1)
+ elif ver_exp_sym_alias_regexp.match(ln):
+ node = "EXPERIMENTAL"
+ symbol = ver_exp_sym_alias_regexp.match(ln).group(1)
elif default_sym_regexp.match(ln):
abi = default_sym_regexp.match(ln).group(1)
node = f"DPDK_{abi}"
symbol = default_sym_regexp.match(ln).group(2)
+ elif default_sym_alias_regexp.match(ln):
+ abi = default_sym_alias_regexp.match(ln).group(1)
+ node = f"DPDK_{abi}"
+ symbol = default_sym_alias_regexp.match(ln).group(2)
if not symbol:
continue
diff --git a/lib/eal/common/eal_export.h b/lib/eal/common/eal_export.h
index 7971bf8d7a..5b458f81c6 100644
--- a/lib/eal/common/eal_export.h
+++ b/lib/eal/common/eal_export.h
@@ -63,6 +63,14 @@ __attribute__((__symver__(RTE_STR(name) "@@DPDK_" RTE_STR(ver)))) \
type name ## _v ## ver args; \
type name ## _v ## ver args
+#define RTE_VERSION_EXPERIMENTAL_SYMBOL_ALIAS(type, name, orig) VERSIONING_WARN \
+extern type name ## _exp __attribute((alias(RTE_STR(orig)), \
+ __symver__(RTE_STR(name) "@EXPERIMENTAL")))
+
+#define RTE_DEFAULT_SYMBOL_ALIAS(ver, type, name, orig) VERSIONING_WARN \
+extern type name ## _v ## ver __attribute((alias(RTE_STR(orig)), \
+ __symver__(RTE_STR(name) "@@DPDK_" RTE_STR(ver))))
+
#else /* !__has_attribute(symver) */
/* Use asm tag to create symbol table entry */
@@ -81,6 +89,14 @@ __asm__(".symver " RTE_STR(name) "_v" RTE_STR(ver) ", " RTE_STR(name) "@@DPDK_"
__rte_used type name ## _v ## ver args; \
type name ## _v ## ver args
+#define RTE_DEFAULT_SYMBOL_ALIAS(ver, type, name, orig) VERSIONING_WARN \
+extern type name ## _v ## ver __attribute__((alias(RTE_STR(orig)))); \
+__asm__(".symver " RTE_STR(name) "_v" RTE_STR(ver) ", " RTE_STR(name) "@@DPDK_" RTE_STR(ver));
+
+#define RTE_VERSION_EXPERIMENTAL_SYMBOL_ALIAS(type, name, orig) VERSIONING_WARN \
+extern type name ## _exp __attribute__((alias(RTE_STR(orig)))); \
+__asm__(".symver " RTE_STR(name) "_exp, " RTE_STR(name) "@EXPERIMENTAL");
+
#endif /* __has_attribute(symver) */
#else /* !RTE_BUILD_SHARED_LIB */
@@ -97,6 +113,12 @@ type name ## _exp args
#define RTE_DEFAULT_SYMBOL(ver, type, name, args) VERSIONING_WARN \
type name args
+#define RTE_VERSION_EXPERIMENTAL_SYMBOL_ALIAS(type, name, orig) VERSIONING_WARN \
+extern type name ## _exp __attribute__((alias(RTE_STR(orig))));
+
+#define RTE_DEFAULT_SYMBOL_ALIAS(ver, type, name, orig) VERSIONING_WARN \
+extern type name __attribute__((alias(RTE_STR(orig))));
+
#endif /* RTE_BUILD_SHARED_LIB */
#endif /* EAL_EXPORT_H */
--
2.47.3
^ permalink raw reply related
* [PATCH 3/5] net/mlx5: fix stabilized function versions
From: Dariusz Sosnowski @ 2026-06-23 11:37 UTC (permalink / raw)
To: Viacheslav Ovsiienko, Bing Zhao, Ori Kam, Suanming Mou,
Matan Azrad
Cc: dev, David Marchand, Bruce Richardson
In-Reply-To: <20260623113752.1100072-1-dsosnowski@nvidia.com>
Offending patch stabilized the following function symbols:
- rte_pmd_mlx5_driver_event_cb_register
- rte_pmd_mlx5_driver_event_cb_unregister
- rte_pmd_mlx5_enable_steering
- rte_pmd_mlx5_disable_steering
These function symbols were introduced in 25.11.
Any application using these functions, linked against 25.11 version,
would fail when used with 26.07 libraries, because only DPDK_26 versions
of these symbols were exported.
This patch fixes that by adding proper function symbol versioning
to these symbols.
Fixes: e8cab133645f ("net/mlx5: promote some private API to stable")
Signed-off-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
---
drivers/net/mlx5/meson.build | 2 ++
drivers/net/mlx5/mlx5_driver_event.c | 22 ++++++++++++++++------
drivers/net/mlx5/mlx5_flow.c | 18 ++++++++++++------
3 files changed, 30 insertions(+), 12 deletions(-)
diff --git a/drivers/net/mlx5/meson.build b/drivers/net/mlx5/meson.build
index 82a7dfe782..0fa6322779 100644
--- a/drivers/net/mlx5/meson.build
+++ b/drivers/net/mlx5/meson.build
@@ -2,6 +2,8 @@
# Copyright 2018 6WIND S.A.
# Copyright 2018 Mellanox Technologies, Ltd
+use_function_versioning = true
+
if not (is_linux or is_windows)
build = false
reason = 'only supported on Linux and Windows'
diff --git a/drivers/net/mlx5/mlx5_driver_event.c b/drivers/net/mlx5/mlx5_driver_event.c
index 89e49331c8..d0e22d6151 100644
--- a/drivers/net/mlx5/mlx5_driver_event.c
+++ b/drivers/net/mlx5/mlx5_driver_event.c
@@ -236,9 +236,8 @@ notify_existing_devices(rte_pmd_mlx5_driver_event_callback_t cb, void *opaque)
notify_existing_queues(port_id, cb, opaque);
}
-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)
+RTE_DEFAULT_SYMBOL(26, int, rte_pmd_mlx5_driver_event_cb_register,
+ (rte_pmd_mlx5_driver_event_callback_t cb, void *opaque))
{
struct registered_cb *r;
@@ -264,9 +263,14 @@ rte_pmd_mlx5_driver_event_cb_register(rte_pmd_mlx5_driver_event_callback_t cb, v
return 0;
}
-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)
+RTE_VERSION_EXPERIMENTAL_SYMBOL(int, rte_pmd_mlx5_driver_event_cb_register,
+ (rte_pmd_mlx5_driver_event_callback_t cb, void *opaque))
+{
+ return rte_pmd_mlx5_driver_event_cb_register(cb, opaque);
+}
+
+RTE_DEFAULT_SYMBOL(26, int, rte_pmd_mlx5_driver_event_cb_unregister,
+ (rte_pmd_mlx5_driver_event_callback_t cb))
{
struct registered_cb *r;
bool found = false;
@@ -289,6 +293,12 @@ rte_pmd_mlx5_driver_event_cb_unregister(rte_pmd_mlx5_driver_event_callback_t cb)
return 0;
}
+RTE_VERSION_EXPERIMENTAL_SYMBOL(int, rte_pmd_mlx5_driver_event_cb_unregister,
+ (rte_pmd_mlx5_driver_event_callback_t cb))
+{
+ return rte_pmd_mlx5_driver_event_cb_unregister(cb);
+}
+
RTE_FINI(rte_pmd_mlx5_driver_event_cb_cleanup) {
struct registered_cb *r;
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index a95dd9dc94..4b984df892 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -12506,9 +12506,7 @@ flow_disable_steering_run_on_related(struct rte_eth_dev *dev,
}
}
-RTE_EXPORT_SYMBOL(rte_pmd_mlx5_disable_steering)
-void
-rte_pmd_mlx5_disable_steering(void)
+RTE_DEFAULT_SYMBOL(26, void, rte_pmd_mlx5_disable_steering, (void))
{
uint16_t port_id;
@@ -12532,9 +12530,12 @@ rte_pmd_mlx5_disable_steering(void)
mlx5_steering_disabled = true;
}
-RTE_EXPORT_SYMBOL(rte_pmd_mlx5_enable_steering)
-int
-rte_pmd_mlx5_enable_steering(void)
+RTE_VERSION_EXPERIMENTAL_SYMBOL(void, rte_pmd_mlx5_disable_steering, (void))
+{
+ rte_pmd_mlx5_disable_steering();
+}
+
+RTE_DEFAULT_SYMBOL(26, int, rte_pmd_mlx5_enable_steering, (void))
{
uint16_t port_id;
@@ -12551,6 +12552,11 @@ rte_pmd_mlx5_enable_steering(void)
return 0;
}
+RTE_VERSION_EXPERIMENTAL_SYMBOL(int, rte_pmd_mlx5_enable_steering, (void))
+{
+ return rte_pmd_mlx5_enable_steering();
+}
+
bool
mlx5_vport_rx_metadata_passing_enabled(const struct mlx5_dev_ctx_shared *sh)
{
--
2.47.3
^ permalink raw reply related
* [PATCH 2/5] drivers: support function versioning
From: Dariusz Sosnowski @ 2026-06-23 11:37 UTC (permalink / raw)
To: David Marchand, Bruce Richardson; +Cc: dev
In-Reply-To: <20260623113752.1100072-1-dsosnowski@nvidia.com>
Add support for enabling function versioning
(through use_function_versioning meson variable) for drivers,
similar to libraries.
Signed-off-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
---
drivers/meson.build | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/meson.build b/drivers/meson.build
index 4d95604ecd..a63d93372a 100644
--- a/drivers/meson.build
+++ b/drivers/meson.build
@@ -171,6 +171,7 @@ foreach subpath:subdirs
pkgconfig_extra_libs = []
testpmd_sources = []
require_iova_in_mbuf = true
+ use_function_versioning = false
# for handling base code files which may need extra cflags
base_sources = []
base_cflags = []
@@ -273,6 +274,13 @@ foreach subpath:subdirs
endif
dpdk_conf.set(lib_name.to_upper(), 1)
+ if developer_mode and is_windows and use_function_versioning
+ message('@0@: Function versioning is not supported by Windows.'.format(name))
+ endif
+ if use_function_versioning
+ cflags += '-DRTE_USE_FUNCTION_VERSIONING'
+ endif
+
dpdk_extra_ldflags += pkgconfig_extra_libs
dpdk_headers += headers
--
2.47.3
^ permalink raw reply related
* [PATCH 0/5] add versioned symbols for recently stabilized APIs
From: Dariusz Sosnowski @ 2026-06-23 11:37 UTC (permalink / raw)
To: Thomas Monjalon, David Marchand, Bruce Richardson,
Andrew Rybchenko, Viacheslav Ovsiienko, Bing Zhao, Ori Kam,
Suanming Mou, Matan Azrad
Cc: dev
Main goal of this patchset is to address https://bugs.dpdk.org/show_bug.cgi?id=1957
but it also handles other recently stabilized symbols and has some minor fixes:
- Patch 1 - Fix RTE_VERSION_EXPERIMENTAL_SYMBOL macro on clang.
- Patch 2 - Allow function versioning inside drivers.
- Patch 3 - Version the function symbols stabilized in
https://git.dpdk.org/dpdk/commit/?id=e8cab133645f5466ef75e511629add43b68a5027
- Patch 4 - Introduce versioning macros for global variable symbols.
- Patch 5 - Version the function and variable symbols stabilized in
https://git.dpdk.org/dpdk/commit/?id=4ee2f5c1cedf9ee7f39afa667f71b07f4004ba5c
Issue is still not fully fixed for stabilized global variables:
rte_flow_dynf_metadata_offs and rte_flow_dynf_metadata_mask.
Patch 4 and 5 address the bug for these global variables,
by providing a single storage for both EXPERIMENTAL and
DPDK_26 variable symbol versions.
This is achieved through symbol aliasing.
But this solution is limited only to executables compiled with clang.
clang and gcc have a different default behavior regarding relocations
of global variables exposed by shared libraries.
With clang, R_X86_64_GLOB_DAT relocations are generated for executables:
$ readelf -sW build-26.07/lib/librte_ethdev.so | grep rte_flow_dynf_metadata_offs
113: 00000000000ea4c0 4 OBJECT GLOBAL DEFAULT 24 rte_flow_dynf_metadata_offs@@DPDK_26
116: 00000000000ea4c0 4 OBJECT GLOBAL DEFAULT 24 rte_flow_dynf_metadata_offs@EXPERIMENTAL
970: 00000000000ea4c0 4 OBJECT LOCAL DEFAULT 24 rte_flow_dynf_metadata_offs_impl
1212: 00000000000ea4c0 4 OBJECT LOCAL DEFAULT 24 rte_flow_dynf_metadata_offs_v26
1325: 00000000000ea4c0 4 OBJECT LOCAL DEFAULT 24 rte_flow_dynf_metadata_offs_exp
1415: 00000000000ea4c0 4 OBJECT GLOBAL DEFAULT 24 rte_flow_dynf_metadata_offs@@DPDK_26
1705: 00000000000ea4c0 4 OBJECT GLOBAL DEFAULT 24 rte_flow_dynf_metadata_offs@EXPERIMENTAL
$ readelf -rW build-26.07/drivers/librte_net_mlx5.so | grep rte_flow_dynf_metadata_offs
0000000003ed5f18 0000001600000006 R_X86_64_GLOB_DAT 0000000000000000 rte_flow_dynf_metadata_offs@DPDK_26 + 0
$ readelf -rW build-25.11/app/dpdk-testpmd | grep rte_flow_dynf_metadata_offs
--> 000000000028ef70 0000011300000006 R_X86_64_GLOB_DAT 0000000000000000 rte_flow_dynf_metadata_offs@EXPERIMENTAL + 0
With gcc, R_X86_64_COPY relocations are generated:
$ readelf -sW build-26.07/lib/librte_ethdev.so | grep rte_flow_dynf_metadata_offs
113: 00000000000e74e0 4 OBJECT GLOBAL DEFAULT 24 rte_flow_dynf_metadata_offs@@DPDK_26
116: 00000000000e74e0 4 OBJECT GLOBAL DEFAULT 24 rte_flow_dynf_metadata_offs@EXPERIMENTAL
1471: 00000000000e74e0 4 OBJECT LOCAL DEFAULT 24 rte_flow_dynf_metadata_offs_impl
2134: 00000000000e74e0 4 OBJECT LOCAL DEFAULT 24 rte_flow_dynf_metadata_offs_v26
2247: 00000000000e74e0 4 OBJECT LOCAL DEFAULT 24 rte_flow_dynf_metadata_offs_exp
2337: 00000000000e74e0 4 OBJECT GLOBAL DEFAULT 24 rte_flow_dynf_metadata_offs@@DPDK_26
2627: 00000000000e74e0 4 OBJECT GLOBAL DEFAULT 24 rte_flow_dynf_metadata_offs@EXPERIMENTAL
$ readelf -rW build-26.07/drivers/librte_net_mlx5.so | grep rte_flow_dynf_metadata_offs
00000000046dbef0 0000001600000006 R_X86_64_GLOB_DAT 0000000000000000 rte_flow_dynf_metadata_offs@DPDK_26 + 0
$ readelf -rW build-25.11/app/dpdk-testpmd | grep rte_flow_dynf_metadata_offs
--> 000000000029b540 000001d200000005 R_X86_64_COPY 000000000029b540 rte_flow_dynf_metadata_offs@EXPERIMENTAL + 0
With copy relocations (testpmd linked through gcc) the following happens:
- When variable symbol (with EXPERIMENTAL version) gets resolved inside executable,
global variable gets copied from read-only data to executable's BSS section.
Executable will access this variable through BSS.
- When variable symbol (with DPDK_26 version) gets resolved inside a library,
global variable is accessed indirectly through GOT.
It is stored inside BSS section of the shared library.
So executable and libraries refer to different storage,
eventually leading to inconsistent runtime behavior.
Problems only appears when executable and library require
different versions of global variable symbol.
If testpmd from 26.07 is used with libraries from 26.07,
GOT entry for these variables will point to copied variable.
Without copy relocations (testpmd linked through clang) both
executable and libraries access the global variable indirectly through GOT.
Runtime behavior is consistent, regardless of the mix of variable symbol versions.
The only other solution I could find was to use dlsym() inside libraries
to dynamically resolve the location rte_flow_dynf_metadata_offs and rte_flow_dynf_metadata_mask,
but this solution sounds like an overkill.
Essentially this would require moving to getter/setter functions for these variables
inside the library.
I would appreciate any feedback or suggestions if anybody had encountered a similar issue before.
Dariusz Sosnowski (5):
eal: fix macro for versioned experimental symbol
drivers: support function versioning
net/mlx5: fix stabilized function versions
eal: support aliases for versioned variable symbols
ethdev: fix promoted flow metadata symbols
buildtools/gen-version-map.py | 11 ++++++++++
drivers/meson.build | 8 +++++++
drivers/net/mlx5/meson.build | 2 ++
drivers/net/mlx5/mlx5_driver_event.c | 22 ++++++++++++++-----
drivers/net/mlx5/mlx5_flow.c | 18 ++++++++++-----
lib/eal/common/eal_export.h | 24 +++++++++++++++++++-
lib/ethdev/meson.build | 2 ++
lib/ethdev/rte_flow.c | 33 ++++++++++++++++++----------
8 files changed, 96 insertions(+), 24 deletions(-)
--
2.47.3
^ permalink raw reply
* [PATCH 1/5] eal: fix macro for versioned experimental symbol
From: Dariusz Sosnowski @ 2026-06-23 11:37 UTC (permalink / raw)
To: David Marchand; +Cc: dev, Bruce Richardson
In-Reply-To: <20260623113752.1100072-1-dsosnowski@nvidia.com>
Add a missing semicolon after __asm__ block in
RTE_VERSION_EXPERIMENTAL_SYMBOL macro.
It's lack triggers the following compilation error with clang:
../lib/ethdev/rte_flow.c:320:1: error: expected ';' after top-level asm block
320 | RTE_VERSION_EXPERIMENTAL_SYMBOL(int, rte_flow_dynf_metadata_register, (void))
| ^
../lib/eal/common/eal_export.h:75:74: note: expanded from macro 'RTE_VERSION_EXPERIMENTAL_SYMBOL'
75 | __asm__(".symver " RTE_STR(name) "_exp, " RTE_STR(name) "@EXPERIMENTAL") \
| ^
../lib/eal/include/rte_common.h:237:20: note: expanded from macro '\
__rte_used'
237 | #define __rte_used __attribute__((used))
| ^
Fixes: e30e194c4d06 ("eal: rework function versioning macros")
Cc: david.marchand@redhat.com
Signed-off-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
---
lib/eal/common/eal_export.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/eal/common/eal_export.h b/lib/eal/common/eal_export.h
index 888fd9f9ed..7971bf8d7a 100644
--- a/lib/eal/common/eal_export.h
+++ b/lib/eal/common/eal_export.h
@@ -72,7 +72,7 @@ __rte_used type name ## _v ## ver args; \
type name ## _v ## ver args
#define RTE_VERSION_EXPERIMENTAL_SYMBOL(type, name, args) VERSIONING_WARN \
-__asm__(".symver " RTE_STR(name) "_exp, " RTE_STR(name) "@EXPERIMENTAL") \
+__asm__(".symver " RTE_STR(name) "_exp, " RTE_STR(name) "@EXPERIMENTAL"); \
__rte_used type name ## _exp args; \
type name ## _exp args
--
2.47.3
^ permalink raw reply related
* [PATCH v3 4/4] net/txgbe: add VF support for Amber-Lite 40G NIC
From: Zaiyu Wang @ 2026-06-23 11:38 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, Jiawen Wu
In-Reply-To: <20260623113805.16464-1-zaiyuwang@trustnetic.com>
VF support for the 40G NIC was previously omitted; only the 25G VF was
added. Now add 40G VF support based on the existing 25G VF implementation,
with no major changes but only device ID adaptation.
Also, drop the redundant mac type check in txgbe_check_mac_link_vf(),
as the function now handles all VF types uniformly.
Signed-off-by: Zaiyu Wang <zaiyuwang@trustnetic.com>
---
drivers/net/txgbe/base/txgbe_devids.h | 2 ++
drivers/net/txgbe/base/txgbe_hw.c | 7 +++++++
drivers/net/txgbe/base/txgbe_regs.h | 7 +++++--
drivers/net/txgbe/base/txgbe_type.h | 1 +
drivers/net/txgbe/base/txgbe_vf.c | 6 +++---
drivers/net/txgbe/txgbe_ethdev.c | 1 +
drivers/net/txgbe/txgbe_ethdev_vf.c | 2 ++
7 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/drivers/net/txgbe/base/txgbe_devids.h b/drivers/net/txgbe/base/txgbe_devids.h
index b7133c7d54..f5454ffbb1 100644
--- a/drivers/net/txgbe/base/txgbe_devids.h
+++ b/drivers/net/txgbe/base/txgbe_devids.h
@@ -28,6 +28,8 @@
#define TXGBE_DEV_ID_AML_VF 0x5001
#define TXGBE_DEV_ID_AML5024_VF 0x5024
#define TXGBE_DEV_ID_AML5124_VF 0x5124
+#define TXGBE_DEV_ID_AML503F_VF 0x503f
+#define TXGBE_DEV_ID_AML513F_VF 0x513f
/*
* Subsystem IDs
diff --git a/drivers/net/txgbe/base/txgbe_hw.c b/drivers/net/txgbe/base/txgbe_hw.c
index 0f3db3a1ad..21465d68ff 100644
--- a/drivers/net/txgbe/base/txgbe_hw.c
+++ b/drivers/net/txgbe/base/txgbe_hw.c
@@ -2543,6 +2543,7 @@ s32 txgbe_init_shared_code(struct txgbe_hw *hw)
break;
case txgbe_mac_sp_vf:
case txgbe_mac_aml_vf:
+ case txgbe_mac_aml40_vf:
status = txgbe_init_ops_vf(hw);
break;
default:
@@ -2573,6 +2574,7 @@ bool txgbe_is_vf(struct txgbe_hw *hw)
switch (hw->mac.type) {
case txgbe_mac_sp_vf:
case txgbe_mac_aml_vf:
+ case txgbe_mac_aml40_vf:
return true;
default:
return false;
@@ -2620,6 +2622,11 @@ s32 txgbe_set_mac_type(struct txgbe_hw *hw)
hw->phy.media_type = txgbe_media_type_virtual;
hw->mac.type = txgbe_mac_aml_vf;
break;
+ case TXGBE_DEV_ID_AML503F_VF:
+ case TXGBE_DEV_ID_AML513F_VF:
+ hw->phy.media_type = txgbe_media_type_virtual;
+ hw->mac.type = txgbe_mac_aml40_vf;
+ break;
default:
err = TXGBE_ERR_DEVICE_NOT_SUPPORTED;
DEBUGOUT("Unsupported device id: %x", hw->device_id);
diff --git a/drivers/net/txgbe/base/txgbe_regs.h b/drivers/net/txgbe/base/txgbe_regs.h
index 95c585a025..5eb92c54b6 100644
--- a/drivers/net/txgbe/base/txgbe_regs.h
+++ b/drivers/net/txgbe/base/txgbe_regs.h
@@ -1824,12 +1824,14 @@ txgbe_map_reg(struct txgbe_hw *hw, u32 reg)
switch (reg) {
case TXGBE_REG_RSSTBL:
if (hw->mac.type == txgbe_mac_sp_vf ||
- hw->mac.type == txgbe_mac_aml_vf)
+ hw->mac.type == txgbe_mac_aml_vf ||
+ hw->mac.type == txgbe_mac_aml40_vf)
reg = TXGBE_VFRSSTBL(0);
break;
case TXGBE_REG_RSSKEY:
if (hw->mac.type == txgbe_mac_sp_vf ||
- hw->mac.type == txgbe_mac_aml_vf)
+ hw->mac.type == txgbe_mac_aml_vf ||
+ hw->mac.type == txgbe_mac_aml40_vf)
reg = TXGBE_VFRSSKEY(0);
break;
default:
@@ -2012,6 +2014,7 @@ static inline void txgbe_flush(struct txgbe_hw *hw)
break;
case txgbe_mac_sp_vf:
case txgbe_mac_aml_vf:
+ case txgbe_mac_aml40_vf:
rd32(hw, TXGBE_VFSTATUS);
break;
default:
diff --git a/drivers/net/txgbe/base/txgbe_type.h b/drivers/net/txgbe/base/txgbe_type.h
index 956080c702..132d5c4eff 100644
--- a/drivers/net/txgbe/base/txgbe_type.h
+++ b/drivers/net/txgbe/base/txgbe_type.h
@@ -171,6 +171,7 @@ enum txgbe_mac_type {
txgbe_mac_aml40,
txgbe_mac_sp_vf,
txgbe_mac_aml_vf,
+ txgbe_mac_aml40_vf,
txgbe_num_macs
};
diff --git a/drivers/net/txgbe/base/txgbe_vf.c b/drivers/net/txgbe/base/txgbe_vf.c
index 1a8a20f104..47d9bd16ee 100644
--- a/drivers/net/txgbe/base/txgbe_vf.c
+++ b/drivers/net/txgbe/base/txgbe_vf.c
@@ -134,7 +134,8 @@ s32 txgbe_reset_hw_vf(struct txgbe_hw *hw)
}
/* amlite: bme */
- if (hw->mac.type == txgbe_mac_aml_vf)
+ if (hw->mac.type == txgbe_mac_aml_vf ||
+ hw->mac.type == txgbe_mac_aml40_vf)
wr32(hw, TXGBE_BME_AML, 0x1);
if (!timeout)
@@ -493,8 +494,7 @@ s32 txgbe_check_mac_link_vf(struct txgbe_hw *hw, u32 *speed,
/* for SFP+ modules and DA cables it can take up to 500usecs
* before the link status is correct
*/
- if ((mac->type == txgbe_mac_sp_vf ||
- mac->type == txgbe_mac_aml_vf) && wait_to_complete) {
+ if (wait_to_complete) {
if (po32m(hw, TXGBE_VFSTATUS, TXGBE_VFSTATUS_UP,
0, NULL, 5, 100))
goto out;
diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
index 003a24141c..63b967d71a 100644
--- a/drivers/net/txgbe/txgbe_ethdev.c
+++ b/drivers/net/txgbe/txgbe_ethdev.c
@@ -5228,6 +5228,7 @@ txgbe_rss_update(enum txgbe_mac_type mac_type)
case txgbe_mac_aml:
case txgbe_mac_aml40:
case txgbe_mac_aml_vf:
+ case txgbe_mac_aml40_vf:
return 1;
default:
return 0;
diff --git a/drivers/net/txgbe/txgbe_ethdev_vf.c b/drivers/net/txgbe/txgbe_ethdev_vf.c
index e3832c0173..14cc49ece1 100644
--- a/drivers/net/txgbe/txgbe_ethdev_vf.c
+++ b/drivers/net/txgbe/txgbe_ethdev_vf.c
@@ -77,6 +77,8 @@ static const struct rte_pci_id pci_id_txgbevf_map[] = {
{ RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, TXGBE_DEV_ID_AML_VF) },
{ RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, TXGBE_DEV_ID_AML5024_VF) },
{ RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, TXGBE_DEV_ID_AML5124_VF) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, TXGBE_DEV_ID_AML503F_VF) },
+ { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, TXGBE_DEV_ID_AML513F_VF) },
{ .vendor_id = 0, /* sentinel */ },
};
--
2.21.0.windows.1
^ permalink raw reply related
* [PATCH v3 3/4] net/txgbe: add support for VF sensing PF down
From: Zaiyu Wang @ 2026-06-23 11:38 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, Jiawen Wu
In-Reply-To: <20260623113805.16464-1-zaiyuwang@trustnetic.com>
VFs should continue normal packet Rx/Tx after PF ifconfig down/up.
To achieve this, cooperate with mailbox commands added in our Linux
kernel driver txgbe-2.2.0. When mailbox messages lack the
TXGBE_VT_MSGTYPE_CTS flag, the PF is considered down. In this state,
the VF reports link down and stops transmitting. Upon detecting the
loss of CTS, the VF sends a reset request to the PF. If the request
succeeds (indicating PF recovery), the VF triggers an
RTE_ETH_EVENT_INTR_RESET event to notify the application or users to
reset the VF.
Additionally, hw->rx_loaded and hw->offset_loaded must be reset when
PF ifconfig down; otherwise, because hardware counter registers are
cleared during PF reset, the VF's software counters will overflow to
0xFFFFFFFF.
Signed-off-by: Zaiyu Wang <zaiyuwang@trustnetic.com>
---
drivers/net/txgbe/base/txgbe_type.h | 1 +
drivers/net/txgbe/txgbe_ethdev.c | 3 +-
drivers/net/txgbe/txgbe_ethdev_vf.c | 60 +++++++++++++++++++++++++----
3 files changed, 55 insertions(+), 9 deletions(-)
diff --git a/drivers/net/txgbe/base/txgbe_type.h b/drivers/net/txgbe/base/txgbe_type.h
index ede780321f..956080c702 100644
--- a/drivers/net/txgbe/base/txgbe_type.h
+++ b/drivers/net/txgbe/base/txgbe_type.h
@@ -883,6 +883,7 @@ struct txgbe_hw {
rte_atomic32_t swfw_busy;
u32 fec_mode;
u32 cur_fec_link;
+ bool pf_running;
};
struct txgbe_backplane_ability {
diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
index 0f484dfe91..003a24141c 100644
--- a/drivers/net/txgbe/txgbe_ethdev.c
+++ b/drivers/net/txgbe/txgbe_ethdev.c
@@ -3150,7 +3150,8 @@ txgbe_dev_link_update_share(struct rte_eth_dev *dev,
hw->mac.get_link_status = true;
- if (intr->flags & TXGBE_FLAG_NEED_LINK_CONFIG)
+ if (intr->flags & TXGBE_FLAG_NEED_LINK_CONFIG ||
+ (txgbe_is_vf(hw) && !hw->pf_running))
return rte_eth_linkstatus_set(dev, &link);
/* check if it needs to wait to complete, if lsc interrupt is enabled */
diff --git a/drivers/net/txgbe/txgbe_ethdev_vf.c b/drivers/net/txgbe/txgbe_ethdev_vf.c
index 7a50c7a855..e3832c0173 100644
--- a/drivers/net/txgbe/txgbe_ethdev_vf.c
+++ b/drivers/net/txgbe/txgbe_ethdev_vf.c
@@ -281,6 +281,7 @@ eth_txgbevf_dev_init(struct rte_eth_dev *eth_dev)
hw->subsystem_device_id = pci_dev->id.subsystem_device_id;
hw->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id;
hw->hw_addr = (void *)pci_dev->mem_resource[0].addr;
+ hw->pf_running = true;
/* initialize the vfta */
memset(shadow_vfta, 0, sizeof(*shadow_vfta));
@@ -1405,10 +1406,20 @@ static s32 txgbevf_get_pf_link_status(struct rte_eth_dev *dev)
if (retval)
return 0;
+ if (!(msgbuf[0] & TXGBE_NOFITY_VF_LINK_STATUS))
+ return 0;
+
rte_eth_linkstatus_get(dev, &link);
+ if (!hw->pf_running) {
+ link.link_status = RTE_ETH_LINK_DOWN;
+ link.link_speed = RTE_ETH_SPEED_NUM_NONE;
+ link.link_duplex = RTE_ETH_LINK_HALF_DUPLEX;
+ return rte_eth_linkstatus_set(dev, &link);
+ }
+
link_up = msgbuf[1] & TXGBE_VFSTATUS_UP;
- link_speed = (msgbuf[1] & 0xFFF0) >> 1;
+ link_speed = (msgbuf[1] & 0x1FFFFE) >> 1;
if (link_up == link.link_status && link_speed == link.link_speed)
return 0;
@@ -1434,10 +1445,22 @@ static s32 txgbevf_get_pf_link_status(struct rte_eth_dev *dev)
static void txgbevf_check_link_for_intr(struct rte_eth_dev *dev)
{
struct rte_eth_link orig_link, new_link;
+ struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
rte_eth_linkstatus_get(dev, &orig_link);
- txgbevf_dev_link_update(dev, 0);
- rte_eth_linkstatus_get(dev, &new_link);
+
+ if (hw->pf_running) {
+ txgbevf_dev_link_update(dev, 0);
+ rte_eth_linkstatus_get(dev, &new_link);
+ } else {
+ DEBUGOUT("PF ifconfig down, so VF link down");
+ new_link.link_status = RTE_ETH_LINK_DOWN;
+ new_link.link_speed = RTE_ETH_SPEED_NUM_NONE;
+ new_link.link_duplex = RTE_ETH_LINK_HALF_DUPLEX;
+ new_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+ RTE_ETH_LINK_SPEED_FIXED);
+ rte_eth_linkstatus_set(dev, &new_link);
+ }
PMD_DRV_LOG(INFO, "orig_link: %d, new_link: %d",
orig_link.link_status, new_link.link_status);
@@ -1450,6 +1473,8 @@ static void txgbevf_check_link_for_intr(struct rte_eth_dev *dev)
static void txgbevf_mbx_process(struct rte_eth_dev *dev)
{
struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
+ struct txgbe_mbx_info *mbx = &hw->mbx;
+ u32 msgbuf = 0;
u32 in_msg = 0;
/* peek the message first */
@@ -1457,14 +1482,33 @@ static void txgbevf_mbx_process(struct rte_eth_dev *dev)
/* PF reset VF event */
if (in_msg & TXGBE_PF_CONTROL_MSG) {
- if (in_msg & TXGBE_NOFITY_VF_LINK_STATUS) {
+ /* msg is not CTS, we need to do reset */
+ if (!(in_msg & TXGBE_VT_MSGTYPE_CTS)) {
+ /* send reset to PF to reconfig CTS flag */
+ int err = 0;
+
+ msgbuf = TXGBE_VF_RESET;
+ err = mbx->write_posted(hw, &msgbuf, 1, 0);
+ if (err) {
+ hw->pf_running = false;
+ txgbevf_check_link_for_intr(dev);
+ } else {
+ hw->pf_running = true;
+ rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET,
+ NULL);
+ }
+ }
+
+ if (in_msg & TXGBE_NOFITY_VF_LINK_STATUS)
txgbevf_get_pf_link_status(dev);
- } else {
- /* dummy mbx read to ack pf */
- txgbe_read_mbx(hw, &in_msg, 1, 0);
+ else
/* check link status if pf ping vf */
txgbevf_check_link_for_intr(dev);
- }
+ }
+
+ if (!hw->pf_running) {
+ hw->rx_loaded = true;
+ hw->offset_loaded = true;
}
}
--
2.21.0.windows.1
^ permalink raw reply related
* [PATCH v3 2/4] net/txgbe: implement USO support
From: Zaiyu Wang @ 2026-06-23 11:38 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, stable, Jiawen Wu, Ferruh Yigit
In-Reply-To: <20260623113805.16464-1-zaiyuwang@trustnetic.com>
USO (UDP Segmentation Offload), also known as UFO (UDP Fragmentation
Offload), is a hardware offload rarely seen in DPDK. Its implementation
is similar to TSO (TCP Segmentation Offload), so the driver enables
USO based on existing TSO support.
The driver has advertised RTE_ETH_TX_OFFLOAD_UDP_TSO in tx_offload_capa
since its initial integration, but the data path never implemented the
actual segmentation support. This commit fills that gap by enabling USO
in the transmit path, making the advertised capability fully functional.
Note:
USO segments UDP packets, requiring hardware to recalculate both IP
and UDP checksums due to length change. Thus, USO implicitly requires
IP and UDP checksum offloads, same as TSO.
Fixes: 86d8adc7702c ("net/txgbe: support getting device info")
Cc: stable@dpdk.org
Signed-off-by: Zaiyu Wang <zaiyuwang@trustnetic.com>
---
drivers/net/txgbe/txgbe_rxtx.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/net/txgbe/txgbe_rxtx.c b/drivers/net/txgbe/txgbe_rxtx.c
index e2cd9b8841..c4cbdbc2b4 100644
--- a/drivers/net/txgbe/txgbe_rxtx.c
+++ b/drivers/net/txgbe/txgbe_rxtx.c
@@ -58,6 +58,7 @@ static const u64 TXGBE_TX_OFFLOAD_MASK = (RTE_MBUF_F_TX_IP_CKSUM |
RTE_MBUF_F_TX_VLAN |
RTE_MBUF_F_TX_L4_MASK |
RTE_MBUF_F_TX_TCP_SEG |
+ RTE_MBUF_F_TX_UDP_SEG |
RTE_MBUF_F_TX_TUNNEL_MASK |
RTE_MBUF_F_TX_OUTER_IP_CKSUM |
RTE_MBUF_F_TX_OUTER_UDP_CKSUM |
@@ -367,7 +368,7 @@ txgbe_set_xmit_ctx(struct txgbe_tx_queue *txq,
type_tucmd_mlhl |= TXGBE_TXD_PTID(tx_offload.ptid);
/* check if TCP segmentation required for this packet */
- if (ol_flags & RTE_MBUF_F_TX_TCP_SEG) {
+ if (ol_flags & (RTE_MBUF_F_TX_TCP_SEG | RTE_MBUF_F_TX_UDP_SEG)) {
tx_offload_mask.l2_len |= ~0;
tx_offload_mask.l3_len |= ~0;
tx_offload_mask.l4_len |= ~0;
@@ -517,7 +518,7 @@ tx_desc_cksum_flags_to_olinfo(uint64_t ol_flags)
tmp |= TXGBE_TXD_CC;
tmp |= TXGBE_TXD_EIPCS;
}
- if (ol_flags & RTE_MBUF_F_TX_TCP_SEG) {
+ if (ol_flags & (RTE_MBUF_F_TX_TCP_SEG | RTE_MBUF_F_TX_UDP_SEG)) {
tmp |= TXGBE_TXD_CC;
/* implies IPv4 cksum */
if (ol_flags & RTE_MBUF_F_TX_IPV4)
@@ -537,7 +538,7 @@ tx_desc_ol_flags_to_cmdtype(uint64_t ol_flags)
if (ol_flags & RTE_MBUF_F_TX_VLAN)
cmdtype |= TXGBE_TXD_VLE;
- if (ol_flags & RTE_MBUF_F_TX_TCP_SEG)
+ if (ol_flags & (RTE_MBUF_F_TX_TCP_SEG | RTE_MBUF_F_TX_UDP_SEG))
cmdtype |= TXGBE_TXD_TSE;
if (ol_flags & RTE_MBUF_F_TX_MACSEC)
cmdtype |= TXGBE_TXD_LINKSEC;
@@ -587,6 +588,8 @@ tx_desc_ol_flags_to_ptype(uint64_t oflags)
if (oflags & RTE_MBUF_F_TX_TCP_SEG)
ptype |= (tun ? RTE_PTYPE_INNER_L4_TCP : RTE_PTYPE_L4_TCP);
+ else if (oflags & RTE_MBUF_F_TX_UDP_SEG)
+ ptype |= (tun ? RTE_PTYPE_INNER_L4_UDP : RTE_PTYPE_L4_UDP);
/* Tunnel */
switch (oflags & RTE_MBUF_F_TX_TUNNEL_MASK) {
@@ -1071,7 +1074,7 @@ txgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
olinfo_status = 0;
if (tx_ol_req) {
- if (ol_flags & RTE_MBUF_F_TX_TCP_SEG) {
+ if (ol_flags & (RTE_MBUF_F_TX_TCP_SEG | RTE_MBUF_F_TX_UDP_SEG)) {
/* when TSO is on, paylen in descriptor is the
* not the packet len but the tcp payload len
*/
@@ -2389,7 +2392,7 @@ txgbe_get_tx_port_offloads(struct rte_eth_dev *dev)
RTE_ETH_TX_OFFLOAD_TCP_CKSUM |
RTE_ETH_TX_OFFLOAD_SCTP_CKSUM |
RTE_ETH_TX_OFFLOAD_TCP_TSO |
- RTE_ETH_TX_OFFLOAD_UDP_TSO |
+ RTE_ETH_TX_OFFLOAD_UDP_TSO |
RTE_ETH_TX_OFFLOAD_UDP_TNL_TSO |
RTE_ETH_TX_OFFLOAD_IP_TNL_TSO |
RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO |
--
2.21.0.windows.1
^ 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