* Re: [PATCH] bus/fslmc: fix shadowed variables in queue storage macros
From: Weijun Pan @ 2026-06-27 16:24 UTC (permalink / raw)
To: Thomas Monjalon, Hemant Agrawal
Cc: dev@dpdk.org, Sachin Saxena, Jun Yang, stable@dpdk.org,
Stephen Hemminger
In-Reply-To: <2S2V_VmSTBa7oGRJ0YAQqg@monjalon.net>
[-- Attachment #1: Type: text/plain, Size: 916 bytes --]
Thanks for the feedback.
I will prepare a v2 for this patch. For the queue storage helpers, I will replace the macros with static inline functions, based on Stephen's suggestion.
Thanks,
Weijun
________________________________
From: Thomas Monjalon <thomas@monjalon.net>
Sent: Wednesday, June 10, 2026 9:15 AM
To: Weijun Pan <wpan3636@gmail.com>; Hemant Agrawal <hemant.agrawal@nxp.com>; Weijun Pan <wpan36@wisc.edu>
Cc: dev@dpdk.org <dev@dpdk.org>; Sachin Saxena <sachin.saxena@nxp.com>; Jun Yang <jun.yang@nxp.com>; stable@dpdk.org <stable@dpdk.org>; Stephen Hemminger <stephen@networkplumber.org>
Subject: Re: [PATCH] bus/fslmc: fix shadowed variables in queue storage macros
07/04/2026 16:09, Stephen Hemminger:
> Why are these not inline functions.
> Macros with lower case names are likely place fore confusion like this?
Hemant, Sachin, Weijun, please could you consider this comment?
[-- Attachment #2: Type: text/html, Size: 2396 bytes --]
^ permalink raw reply
* Re: [PATCH] net/virtio-user: fix eventfd sharing in secondary process
From: Samar Yadav @ 2026-06-26 7:37 UTC (permalink / raw)
To: stephen; +Cc: dev, maxime.coquelin, chenbox, tiwei.bie, stable
In-Reply-To: <20260624081610.780c4b0f@phoenix.local>
[-- Attachment #1: Type: text/plain, Size: 1833 bytes --]
Agreed on the related pthread_mutex_init bug.
In this patch dev->mutex is only ever locked by the primary process:
the MP handler runs in the primary's EAL dispatch thread, and the
teardown path in virtio_user_dev_uninit() is primary-only. The
secondary communicates via rte_mp_request_sync() over the EAL socket
and never calls pthread_mutex_lock() on dev->mutex directly.
That said, POSIX requires PTHREAD_PROCESS_SHARED for a mutex stored in
shared memory regardless of which processes actually lock it, and other
DPDK multiprocess-aware code already uses rte_thread_mutex_init_shared()
for shared-memory mutexes. The pthread_mutex_init(&dev->mutex, NULL) call
predates this
patch but since this patch explicitly documents the lock's role I will fix
the
initialisation in v2:
- pthread_mutex_init(&dev->mutex, NULL);
+ rte_thread_mutex_init_shared(&dev->mutex);
On Wed, Jun 24, 2026 at 8:46 PM Stephen Hemminger <
stephen@networkplumber.org> wrote:
> On Wed, 24 Jun 2026 08:57:41 +0000
> Samar Yadav <samaryadav5@gmail.com> wrote:
>
> > @@ -865,9 +913,15 @@ virtio_user_dev_uninit(struct virtio_user_dev *dev)
> >
> > rte_mem_event_callback_unregister(VIRTIO_USER_MEM_EVENT_CLB_NAME,
> dev);
> >
> > + /*
> > + * Serialize closing/freeing the kick/call fd arrays against the MP
> > + * handler, which reads them under the same lock to share them with
> > + * secondary processes.
> > + */
> > + pthread_mutex_lock(&dev->mutex);
> > virtio_user_dev_uninit_notify(dev);
> > -
> > virtio_user_free_vrings(dev);
> > + pthread_mutex_unlock(&dev->mutex);
> >
> > free(dev->ifname);
>
> Related bug. virtio_user is not initializing mutex as safe between
> processes. See rte_thread_mutex_init_shared() vs pthread_mutex_init()
>
[-- Attachment #2: Type: text/html, Size: 2429 bytes --]
^ permalink raw reply
* Re: [PATCH] net/virtio-user: fix eventfd sharing in secondary process
From: Samar Yadav @ 2026-06-26 7:41 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev, maxime.coquelin, chenbox, tiwei.bie, stable
In-Reply-To: <20260624081036.6c6c82e8@phoenix.local>
[-- Attachment #1: Type: text/plain, Size: 1024 bytes --]
Agreed Stephen, will switch to rte_calloc in patch v2:
- pp->kickfds = rte_malloc("virtio_user_proc_priv",
- total_queues * sizeof(int), 0);
- pp->callfds = rte_malloc("virtio_user_proc_priv",
- total_queues * sizeof(int), 0);
+ pp->kickfds = rte_calloc("virtio_user_proc_priv",
+ total_queues, sizeof(int), 0);
+ pp->callfds = rte_calloc("virtio_user_proc_priv",
+ total_queues, sizeof(int), 0);
On Wed, Jun 24, 2026 at 8:47 PM Stephen Hemminger <
stephen@networkplumber.org> wrote:
> On Wed, 24 Jun 2026 08:57:41 +0000
> Samar Yadav <samaryadav5@gmail.com> wrote:
>
> > + pp = rte_zmalloc("virtio_user_proc_priv", sizeof(*pp), 0);
> > + if (pp == NULL)
> > + return -ENOMEM;
> > +
> > + pp->kickfds = rte_malloc("virtio_user_proc_priv",
> > + total_queues * sizeof(int), 0);
> > + pp->callfds = rte_malloc("virtio_user_proc_priv",
> > + total_queues * sizeof(int), 0);
>
> Better to use rte_calloc.
>
[-- Attachment #2: Type: text/html, Size: 1617 bytes --]
^ permalink raw reply
* Re: [PATCH] net/virtio-user: fix eventfd sharing in secondary process
From: samar yadav @ 2026-06-26 8:04 UTC (permalink / raw)
To: stephen; +Cc: chenbox, dev, maxime.coquelin, samaryadav5, stable, tiwei.bie
In-Reply-To: <20260624081036.6c6c82e8@phoenix.local>
On Wed, 24 Jun 2026 08:10:36 -0700
Stephen Hemminger <stephen@networkplumber.org> wrote:
> > + pp = rte_zmalloc("virtio_user_proc_priv", sizeof(*pp), 0);
> > + if (pp == NULL)
> > + return -ENOMEM;
> > +
> > + pp->kickfds = rte_malloc("virtio_user_proc_priv",
> > + total_queues * sizeof(int), 0);
> > + pp->callfds = rte_malloc("virtio_user_proc_priv",
> > + total_queues * sizeof(int), 0);
>
> Better to use rte_calloc.
Agreed Stephen, will switch to rte_calloc in patch v2:
- pp->kickfds = rte_malloc("virtio_user_proc_priv",
- total_queues * sizeof(int), 0);
- pp->callfds = rte_malloc("virtio_user_proc_priv",
- total_queues * sizeof(int), 0);
+ pp->kickfds = rte_calloc("virtio_user_proc_priv",
+ total_queues, sizeof(int), 0);
+ pp->callfds = rte_calloc("virtio_user_proc_priv",
+ total_queues, sizeof(int), 0);
Samar Yadav
^ permalink raw reply
* Re: [PATCH] net/virtio-user: fix eventfd sharing in secondary process
From: samar yadav @ 2026-06-26 8:05 UTC (permalink / raw)
To: stephen; +Cc: chenbox, dev, maxime.coquelin, samaryadav5, stable, tiwei.bie
In-Reply-To: <20260624081610.780c4b0f@phoenix.local>
On Wed, 24 Jun 2026 08:16:10 -0700
Stephen Hemminger <stephen@networkplumber.org> wrote:
> > + /*
> > + * Serialize closing/freeing the kick/call fd arrays against the MP
> > + * handler, which reads them under the same lock to share them with
> > + * secondary processes.
> > + */
> > + pthread_mutex_lock(&dev->mutex);
> > virtio_user_dev_uninit_notify(dev);
> > -
> > virtio_user_free_vrings(dev);
> > + pthread_mutex_unlock(&dev->mutex);
>
> Related bug. virtio_user is not initializing mutex as safe between
> processes. See rte_thread_mutex_init_shared() vs pthread_mutex_init()
Agreed on the related pthread_mutex_init bug.
In this patch dev->mutex is only ever locked by the primary process:
the MP handler runs in the primary's EAL dispatch thread, and the
teardown path in virtio_user_dev_uninit() is primary-only. The
secondary communicates via rte_mp_request_sync() over the EAL socket
and never calls pthread_mutex_lock() on dev->mutex directly.
That said, POSIX requires PTHREAD_PROCESS_SHARED for a mutex stored in
shared memory regardless of which processes actually lock it, and other
DPDK multiprocess-aware code already uses rte_thread_mutex_init_shared()
for shared-memory mutexes. The pthread_mutex_init(&dev->mutex, NULL) call predates this
patch but since this patch explicitly documents the lock's role I will fix the
initialisation in v2:
- pthread_mutex_init(&dev->mutex, NULL);
+ rte_thread_mutex_init_shared(&dev->mutex);
Samar Yadav
^ permalink raw reply
* Re: [PATCH v4 0/4] add versioned symbols for recently stabilized APIs
From: David Marchand @ 2026-06-28 13:57 UTC (permalink / raw)
To: Dariusz Sosnowski
Cc: Bruce Richardson, Thomas Monjalon, Andrew Rybchenko,
Viacheslav Ovsiienko, Bing Zhao, Ori Kam, Suanming Mou,
Matan Azrad, dev, Yu Jiang
In-Reply-To: <20260625160645.1341914-1-dsosnowski@nvidia.com>
Hello Dariusz,
On Thu, 25 Jun 2026 at 18:08, 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 - Version the rte_flow_dynf_metadata_register() function stabilized in
> https://git.dpdk.org/dpdk/commit/?id=4ee2f5c1cedf9ee7f39afa667f71b07f4004ba5c
> Restore EXPERIMENTAL version on global variable symbols
> rte_flow_dynf_metadata_offs and rte_flow_dynf_metadata_mask.
>
> v4:
> - Fixed build with older meson versions.
>
> v3:
> - https://inbox.dpdk.org/dev/20260625133311.1299705-1-dsosnowski@nvidia.com/
> - Added rebuilding of drivers with -DRTE_BUILD_SHARED_LIB
> whenever function versioning is enabled.
>
> v2:
> - https://inbox.dpdk.org/dev/20260624131337.1127323-1-dsosnowski@nvidia.com/
> - Drop patches introducing versioning macros for symbol aliases
> and their usage (patch 4 and 5 from v1)
> - EXPERIMENTAL version on global variable symbols
> rte_flow_dynf_metadata_offs and rte_flow_dynf_metadata_mask,
> as discussed under v1.
> - Change commit title prefix in patch (2) from "drivers" to "build".
>
> v1: https://inbox.dpdk.org/dev/20260623113752.1100072-1-dsosnowski@nvidia.com/
>
> Dariusz Sosnowski (4):
> eal: fix macro for versioned experimental symbol
> build: support function versioning for drivers
> net/mlx5: fix stabilized function versions
> ethdev: fix promoted flow metadata symbols
>
> drivers/meson.build | 21 ++++++++++++++++++++-
> 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 | 2 +-
> lib/ethdev/meson.build | 2 ++
> lib/ethdev/rte_flow.c | 13 ++++++++-----
> 7 files changed, 61 insertions(+), 19 deletions(-)
LGTM.
Series applied, thanks Dariusz.
Please send the patch to drop this compat in 26.11.
--
David Marchand
^ permalink raw reply
* Re: [EXTERNAL] [PATCH] dev: skip multi-process in hotplug
From: David Marchand @ 2026-06-28 14:02 UTC (permalink / raw)
To: Long Li; +Cc: dev@dpdk.org
In-Reply-To: <SA1PR21MB66832482A8C80E279EAAAB7DCEEB2@SA1PR21MB6683.namprd21.prod.outlook.com>
On Fri, 26 Jun 2026 at 20:10, Long Li <longli@microsoft.com> wrote:
> > @@ -418,6 +434,9 @@ rte_dev_remove(struct rte_device *dev)
> > if (ret != 0)
> > return ret;
> >
> > + if (!do_mp)
> > + goto skip_mp_req;
> > +
>
> Need to call free(devargs) as it no longer used.
Yes good catch, but I'd rather not build this devargs at all.
I will send a v2.
>
>
> > memset(&req, 0, sizeof(req));
> > req.t = EAL_DEV_REQ_TYPE_DETACH;
> > strlcpy(req.devargs, devargs, EAL_DEV_MP_DEV_ARGS_MAX_LEN);
--
David Marchand
^ permalink raw reply
* [PATCH v2] dev: skip multi-process in hotplug
From: David Marchand @ 2026-06-28 14:05 UTC (permalink / raw)
To: dev; +Cc: longli
In-Reply-To: <20260625072254.4190227-1-david.marchand@redhat.com>
If multi-process is disabled (--no-shconf/--in-memory),
there is no need to build a multi-process message.
Signed-off-by: David Marchand <david.marchand@redhat.com>
---
lib/eal/common/eal_common_dev.c | 46 ++++++++++++++++++++++++---------
1 file changed, 34 insertions(+), 12 deletions(-)
diff --git a/lib/eal/common/eal_common_dev.c b/lib/eal/common/eal_common_dev.c
index 762ed09e21..47fc45aa3e 100644
--- a/lib/eal/common/eal_common_dev.c
+++ b/lib/eal/common/eal_common_dev.c
@@ -267,10 +267,16 @@ RTE_EXPORT_SYMBOL(rte_dev_probe)
int
rte_dev_probe(const char *devargs)
{
+ const struct internal_config *internal_conf =
+ eal_get_internal_configuration();
+ bool do_mp = internal_conf->no_shconf == 0;
struct eal_dev_mp_req req;
struct rte_device *dev;
int ret;
+ if (!do_mp)
+ goto skip_mp_req;
+
memset(&req, 0, sizeof(req));
req.t = EAL_DEV_REQ_TYPE_ATTACH;
strlcpy(req.devargs, devargs, EAL_DEV_MP_DEV_ARGS_MAX_LEN);
@@ -294,6 +300,7 @@ rte_dev_probe(const char *devargs)
/* attach a shared device from primary start from here: */
+skip_mp_req:
/* primary attach the new device itself. */
ret = local_dev_probe(devargs, &dev);
@@ -311,6 +318,9 @@ rte_dev_probe(const char *devargs)
return ret;
}
+ if (!do_mp)
+ goto skip_mp_notify;
+
/* primary send attach sync request to secondary. */
ret = eal_dev_hotplug_request_to_secondary(&req);
@@ -337,16 +347,19 @@ rte_dev_probe(const char *devargs)
goto rollback;
}
+skip_mp_notify:
return 0;
rollback:
- req.t = EAL_DEV_REQ_TYPE_ATTACH_ROLLBACK;
+ if (do_mp) {
+ req.t = EAL_DEV_REQ_TYPE_ATTACH_ROLLBACK;
- /* primary send rollback request to secondary. */
- if (eal_dev_hotplug_request_to_secondary(&req) != 0)
- EAL_LOG(WARNING,
- "Failed to rollback device attach on secondary."
- "Devices in secondary may not sync with primary");
+ /* primary send rollback request to secondary. */
+ if (eal_dev_hotplug_request_to_secondary(&req) != 0)
+ EAL_LOG(WARNING,
+ "Failed to rollback device attach on secondary."
+ "Devices in secondary may not sync with primary");
+ }
/* primary rollback itself. */
if (local_dev_remove(dev) != 0)
@@ -407,6 +420,9 @@ RTE_EXPORT_SYMBOL(rte_dev_remove)
int
rte_dev_remove(struct rte_device *dev)
{
+ const struct internal_config *internal_conf =
+ eal_get_internal_configuration();
+ bool do_mp = internal_conf->no_shconf == 0;
struct eal_dev_mp_req req;
char *devargs;
int ret;
@@ -416,6 +432,9 @@ rte_dev_remove(struct rte_device *dev)
return -ENOENT;
}
+ if (!do_mp)
+ goto skip_mp_req;
+
ret = build_devargs(dev->bus->name, dev->name, "", &devargs);
if (ret != 0)
return ret;
@@ -474,6 +493,7 @@ rte_dev_remove(struct rte_device *dev)
goto rollback;
}
+skip_mp_req:
/* primary detach the device itself. */
ret = local_dev_remove(dev);
@@ -490,13 +510,15 @@ rte_dev_remove(struct rte_device *dev)
return 0;
rollback:
- req.t = EAL_DEV_REQ_TYPE_DETACH_ROLLBACK;
+ if (do_mp) {
+ req.t = EAL_DEV_REQ_TYPE_DETACH_ROLLBACK;
- /* primary send rollback request to secondary. */
- if (eal_dev_hotplug_request_to_secondary(&req) != 0)
- EAL_LOG(WARNING,
- "Failed to rollback device detach on secondary."
- "Devices in secondary may not sync with primary");
+ /* primary send rollback request to secondary. */
+ if (eal_dev_hotplug_request_to_secondary(&req) != 0)
+ EAL_LOG(WARNING,
+ "Failed to rollback device detach on secondary."
+ "Devices in secondary may not sync with primary");
+ }
return ret;
}
--
2.54.0
^ permalink raw reply related
* [PATCH v2] bus/fslmc: convert queue storage macros to inline functions
From: Weijun Pan @ 2026-06-28 15:25 UTC (permalink / raw)
To: dev
Cc: hemant.agrawal, sachin.saxena, jun.yang, stable, stephen, thomas,
david.marchand, Weijun Pan
In-Reply-To: <20260407141928.9426-1-wpan36@wisc.edu>
From: Weijun Pan <wpan36@wisc.edu>
The queue storage allocation and free helpers are implemented as macros
which declare local variables in the caller scope. This can cause shadow
warnings when -Wshadow is enabled.
Convert them to static inline functions to avoid macro-local variable
scope issues without changing behavior.
Bugzilla ID: 1744
Fixes: 12d98eceb8ac ("bus/fslmc: enhance QBMAN DQ storage logic")
Cc: jun.yang@nxp.com
Cc: stable@dpdk.org
Signed-off-by: Weijun Pan <wpan36@wisc.edu>
---
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 75 ++++++++++++++-----------
1 file changed, 42 insertions(+), 33 deletions(-)
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index e625a5c035..d09dd5d1f9 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
@@ -202,39 +202,48 @@ struct swp_active_dqs {
uint64_t reserved[7];
};
-#define dpaa2_queue_storage_alloc(q, num) \
-({ \
- int ret = 0, i; \
- \
- for (i = 0; i < (num); i++) { \
- (q)->q_storage[i] = rte_zmalloc(NULL, \
- sizeof(struct queue_storage_info_t), \
- RTE_CACHE_LINE_SIZE); \
- if (!(q)->q_storage[i]) { \
- ret = -ENOBUFS; \
- break; \
- } \
- ret = dpaa2_alloc_dq_storage((q)->q_storage[i]); \
- if (ret) \
- break; \
- } \
- ret; \
-})
-
-#define dpaa2_queue_storage_free(q, num) \
-({ \
- if (q) { \
- int i; \
- \
- for (i = 0; i < (num); i++) { \
- if ((q)->q_storage[i]) { \
- dpaa2_free_dq_storage((q)->q_storage[i]); \
- rte_free((q)->q_storage[i]); \
- (q)->q_storage[i] = NULL; \
- } \
- } \
- } \
-})
+int dpaa2_alloc_dq_storage(struct queue_storage_info_t *q_storage);
+void dpaa2_free_dq_storage(struct queue_storage_info_t *q_storage);
+
+static inline int
+dpaa2_queue_storage_alloc(struct dpaa2_queue *q, int num)
+{
+ int ret = 0, i;
+
+ for (i = 0; i < num; i++) {
+ q->q_storage[i] = rte_zmalloc(NULL,
+ sizeof(struct queue_storage_info_t),
+ RTE_CACHE_LINE_SIZE);
+ if (!q->q_storage[i]) {
+ ret = -ENOBUFS;
+ break;
+ }
+
+ ret = dpaa2_alloc_dq_storage(q->q_storage[i]);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+
+static inline void
+dpaa2_queue_storage_free(struct dpaa2_queue *q, int num)
+{
+ int i;
+
+ if (!q)
+ return;
+
+ for (i = 0; i < num; i++) {
+ if (q->q_storage[i]) {
+ dpaa2_free_dq_storage(q->q_storage[i]);
+ rte_free(q->q_storage[i]);
+ q->q_storage[i] = NULL;
+ }
+ }
+}
+
#define NUM_MAX_SWP 64
--
2.34.1
^ permalink raw reply related
* Re: [PATCH v3 2/3] dma/ae4dma: add control path operations
From: Stephen Hemminger @ 2026-06-28 16:04 UTC (permalink / raw)
To: fengchengwen
Cc: Raghavendra Ningoji, dev, david.marchand, bruce.richardson,
Selwin.Sebastian, bhagyada.modali, rjarry, thomas
In-Reply-To: <6db5bccd-f82a-4a31-ab4c-b3addbcbcc94@huawei.com>
On Sat, 27 Jun 2026 08:09:09 +0800
fengchengwen <fengchengwen@huawei.com> wrote:
> >
> > +static int
> > +ae4dma_dev_configure(struct rte_dma_dev *dev __rte_unused,
> > + const struct rte_dma_conf *dev_conf,
> > + uint32_t conf_sz)
> > +{
> > + if (sizeof(struct rte_dma_conf) != conf_sz)
> > + return -EINVAL;
>
> This may break ABI compatible
Ignore that suggestion. This is a reasonable way to handle new configuration
functions. You need/want a minimal set of values. If rte_dma_conf grows in size
then the code can add compatability; by requiring a minimum set of values
and then setting the rest to zero.
Something like
static int
ae4dma_dev_configure(struct rte_dma_dev *dev __rte_unused,
const struct rte_dma_conf *dev_conf,
size_t conf_sz)
{
if (conf_sz < sizeof(struct orig_rte_dma_conf))
return -EINVAL;
struct rte_dma_conf conf;
memcpy(&conf, dev_conf, RTE_MIN(conf_sz, sizeof(conf)));
dev_conf = &conf;
Looking at rte_dma_conf the structure has holes and dmadev lib
doesn't validate undefined flags, so it already has future ABI problems.
^ permalink raw reply
* Re: [PATCH v3 0/9] ENETC driver related changes series
From: Stephen Hemminger @ 2026-06-28 22:24 UTC (permalink / raw)
To: Gagandeep Singh; +Cc: dev, hemant.agrawal
In-Reply-To: <20260623060004.2187716-1-g.singh@nxp.com>
On Tue, 23 Jun 2026 11:29:55 +0530
Gagandeep Singh <g.singh@nxp.com> wrote:
> V3 changes:
> - Added documentation for all devargs in enetc4.rst.
> - Fixed kvlist memory leak issue.
>
> V2 changes:
> - Fixed an un-used variable compilation issue reported on fedora:43-gcc-minsize
> - Fixed various AI reported issues:
> - Release notes updated for all new devargs
> - enect4.ini features doc updated for scattered RX.
> - removed Not required RTE_PTYPE_UNKNOWN.
> - Fixed mid-frame mbuf leak in SG case.
> - Enabled SG for enetc4 PF also.
> - move to calloc from rte_zmalloc in parse_txq_prior().
> - added vaidation checks on strdup, strtoul.
> - added NC devargs to use cacheable ops conditionally.
> - removed dead code like bd_base_p etc.
> - Fixed rte_cpu_to_le_16() conversion on flags and combined
> all flags related patches in one patch.
> - Fixed memory leak issue due to TXQ priority patch.
> - There were some false positives, I have ignored them:
> Race condition on flags field:
> clean_tx_ring only touches HW-completed BDs (next_to_clean→hwci),
> never newly-submitted BDs; doorbell hasn't fired yet.
> Missing dcbf in clean_tx_ring:
> DPDK is single-threaded per queue; TX path always overwrites
> flags completely before dcbf.
> TX dcbf granularity with wrap:
> Safe (AI admits it).
> RX refill flush at wrap:
> In-loop dcbf at i & mask == 0 already flushes aligned groups;
> trailing flush only needed for partial groups.
> RX reading before invalidate:
> dccivac precedes the read for every group in the loop
>
> Gagandeep Singh (7):
> net/enetc: fix TX BD structure
> net/enetc: fix queue initialization
> net/enetc: support ESP packet type in packet parsing
> net/enetc: update random MAC generation code
> net/enetc: add option to disable VSI messaging
> net/enetc: add devargs to control VSI-PSI timeout and delay
> net/enetc4: add cacheable BD ring support with SW cache maintenance
>
> Vanshika Shukla (2):
> net/enetc: support scatter-gather
> net/enetc: set user configurable priority to TX rings
>
> doc/guides/nics/enetc4.rst | 62 +++-
> doc/guides/nics/features/enetc4.ini | 1 +
> doc/guides/rel_notes/release_26_07.rst | 10 +
> drivers/net/enetc/base/enetc_hw.h | 13 +-
> drivers/net/enetc/enetc.h | 31 +-
> drivers/net/enetc/enetc4_ethdev.c | 172 ++++++++--
> drivers/net/enetc/enetc4_vf.c | 206 ++++++++++--
> drivers/net/enetc/enetc_ethdev.c | 25 +-
> drivers/net/enetc/enetc_rxtx.c | 430 ++++++++++++++++++++++---
> 9 files changed, 831 insertions(+), 119 deletions(-)
>
I had merged this to net-next, but now removed it after running ./devtools/test-meson-builds.sh
This script runs a number of builds with different configs, and these driver changes fail in one case.
DPDK 26.07.0-rc1
User defined options
buildtype : minsize
default_library : static
enable_deprecated_libs: *
enable_stdatomic : false
examples : l3fwd
werror : true
Found ninja-1.13.2 at /usr/bin/ninja
ninja: Entering directory `./build-gcc-static'
[2191/3862] Compiling C object drivers/libtmp_rte_net_enetc.a.p/net_enetc_enetc_rxtx.c.o
FAILED: [code=1] drivers/libtmp_rte_net_enetc.a.p/net_enetc_enetc_rxtx.c.o
/usr/bin/ccache gcc -Idrivers/libtmp_rte_net_enetc.a.p -Idrivers -I../drivers -Idrivers/net/enetc -I../drivers/net/enetc -I../drivers/net/enetc/base -Ilib/ethdev -I../lib/ethdev -Ilib/eal/common -I../lib/eal/common -I. -I.. -Iconfig -I../config -Ilib/eal/include -I../lib/eal/include -Ilib/eal/linux/include -I../lib/eal/linux/include -Ilib/eal/x86/include -I../lib/eal/x86/include -I../kernel/linux -Ilib/eal -I../lib/eal -Ilib/kvargs -I../lib/kvargs -Ilib/log -I../lib/log -Ilib/metrics -I../lib/metrics -Ilib/telemetry -I../lib/telemetry -Ilib/argparse -I../lib/argparse -Ilib/net -I../lib/net -Ilib/mbuf -I../lib/mbuf -Ilib/mempool -I../lib/mempool -Ilib/ring -I../lib/ring -Ilib/meter -I../lib/meter -Idrivers/bus/pci -I../drivers/bus/pci -I../drivers/bus/pci/linux -Ilib/pci -I../lib/pci -Idrivers/bus/vdev -I../drivers/bus/vdev -Idrivers/common/dpaax -I../drivers/common/dpaax -I../drivers/common/dpaax/caamflib -I/usr/include/x86_64-linux-gnu -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -Werror -std=c11 -Os -g -include rte_config.h -Wvla -Wcast-qual -Wdeprecated -Wformat -Wformat-nonliteral -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Wold-style-definition -Wpointer-arith -Wshadow -Wsign-compare -Wstrict-prototypes -Wundef -Wwrite-strings -Wno-packed-not-aligned -Wno-missing-field-initializers -fzero-init-padding-bits=all -D_GNU_SOURCE -fPIC -march=native -mrtm -DALLOW_EXPERIMENTAL_API -DALLOW_INTERNAL_API -Wno-format-truncation -Wno-address-of-packed-member -DRTE_COMPONENT_CLASS=pmd_net -DRTE_COMPONENT_NAME=enetc -DRTE_LOG_DEFAULT_LOGTYPE=pmd.net.enetc -MD -MQ drivers/libtmp_rte_net_enetc.a.p/net_enetc_enetc_rxtx.c.o -MF drivers/libtmp_rte_net_enetc.a.p/net_enetc_enetc_rxtx.c.o.d -o drivers/libtmp_rte_net_enetc.a.p/net_enetc_enetc_rxtx.c.o -c ../drivers/net/enetc/enetc_rxtx.c
../drivers/net/enetc/enetc_rxtx.c: In function ‘enetc_xmit_pkts_nc’:
../drivers/net/enetc/enetc_rxtx.c:213:20: error: ‘txbd’ may be used uninitialized [-Werror=maybe-uninitialized]
213 | if (likely(txbd))
| ^
../drivers/net/enetc/enetc_rxtx.c:162:29: note: ‘txbd’ was declared here
162 | struct enetc_tx_bd *txbd;
| ^~~~
../drivers/net/enetc/enetc_rxtx.c: In function ‘enetc_xmit_pkts_cacheable’:
../drivers/net/enetc/enetc_rxtx.c:715:20: error: ‘txbd’ may be used uninitialized [-Werror=maybe-uninitialized]
715 | if (likely(txbd))
| ^
../drivers/net/enetc/enetc_rxtx.c:644:29: note: ‘txbd’ was declared here
644 | struct enetc_tx_bd *txbd;
| ^~~~
cc1: all warnings being treated as errors
[2224/3862] Generating drivers/rte_common_cnxk.sym_chk with a custom command (wrapped by meson to capture output)
ninja: build stopped: subcommand failed.
^ permalink raw reply
* Re: [PATCH v3 0/9] ENETC driver related changes series
From: Stephen Hemminger @ 2026-06-28 22:40 UTC (permalink / raw)
To: Gagandeep Singh; +Cc: dev, hemant.agrawal
In-Reply-To: <20260623060004.2187716-1-g.singh@nxp.com>
On Tue, 23 Jun 2026 11:29:55 +0530
Gagandeep Singh <g.singh@nxp.com> wrote:
> V3 changes:
> - Added documentation for all devargs in enetc4.rst.
> - Fixed kvlist memory leak issue.
>
> V2 changes:
> - Fixed an un-used variable compilation issue reported on fedora:43-gcc-minsize
> - Fixed various AI reported issues:
> - Release notes updated for all new devargs
> - enect4.ini features doc updated for scattered RX.
> - removed Not required RTE_PTYPE_UNKNOWN.
> - Fixed mid-frame mbuf leak in SG case.
> - Enabled SG for enetc4 PF also.
> - move to calloc from rte_zmalloc in parse_txq_prior().
> - added vaidation checks on strdup, strtoul.
> - added NC devargs to use cacheable ops conditionally.
> - removed dead code like bd_base_p etc.
> - Fixed rte_cpu_to_le_16() conversion on flags and combined
> all flags related patches in one patch.
> - Fixed memory leak issue due to TXQ priority patch.
> - There were some false positives, I have ignored them:
> Race condition on flags field:
> clean_tx_ring only touches HW-completed BDs (next_to_clean→hwci),
> never newly-submitted BDs; doorbell hasn't fired yet.
> Missing dcbf in clean_tx_ring:
> DPDK is single-threaded per queue; TX path always overwrites
> flags completely before dcbf.
> TX dcbf granularity with wrap:
> Safe (AI admits it).
> RX refill flush at wrap:
> In-loop dcbf at i & mask == 0 already flushes aligned groups;
> trailing flush only needed for partial groups.
> RX reading before invalidate:
> dccivac precedes the read for every group in the loop
>
> Gagandeep Singh (7):
> net/enetc: fix TX BD structure
> net/enetc: fix queue initialization
> net/enetc: support ESP packet type in packet parsing
> net/enetc: update random MAC generation code
> net/enetc: add option to disable VSI messaging
> net/enetc: add devargs to control VSI-PSI timeout and delay
> net/enetc4: add cacheable BD ring support with SW cache maintenance
>
> Vanshika Shukla (2):
> net/enetc: support scatter-gather
> net/enetc: set user configurable priority to TX rings
>
> doc/guides/nics/enetc4.rst | 62 +++-
> doc/guides/nics/features/enetc4.ini | 1 +
> doc/guides/rel_notes/release_26_07.rst | 10 +
> drivers/net/enetc/base/enetc_hw.h | 13 +-
> drivers/net/enetc/enetc.h | 31 +-
> drivers/net/enetc/enetc4_ethdev.c | 172 ++++++++--
> drivers/net/enetc/enetc4_vf.c | 206 ++++++++++--
> drivers/net/enetc/enetc_ethdev.c | 25 +-
> drivers/net/enetc/enetc_rxtx.c | 430 ++++++++++++++++++++++---
> 9 files changed, 831 insertions(+), 119 deletions(-)
>
LOL AI apologized for missing this in review.
You're right, and I missed it — twice. I explicitly considered that
txbd guard in my v2 review and talked myself out of flagging it as
"over-defensive," but the runtime argument (the inner loop always
executes because tx_pkts[start] is non-NULL) is invisible to the
compiler. Under -Werror=maybe-uninitialized at -Os that's a hard build
break, and per-commit buildability is non-negotiable. That's a real
review failure on my part. Let me reproduce it, pin down which patch
introduces it, and confirm the fix.
drivers/net/enetc/enetc_rxtx.c
enetc_xmit_pkts_nc() and enetc_xmit_pkts_cacheable() both fail to
build with -Werror=maybe-uninitialized (-Os, gcc):
error: 'txbd' may be used uninitialized
txbd is declared without an initializer and assigned only inside the
inner per-segment loop; the compiler cannot prove that loop runs
before txbd is read after it. Initialize at declaration:
- struct enetc_tx_bd *txbd;
+ struct enetc_tx_bd *txbd = NULL;
The _nc fix belongs in patch 5 (so that commit builds independently);
the _cacheable fix belongs in patch 9.
^ permalink raw reply
* Re: [PATCH v3 2/3] dma/ae4dma: add control path operations
From: fengchengwen @ 2026-06-29 0:36 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Raghavendra Ningoji, dev, david.marchand, bruce.richardson,
Selwin.Sebastian, bhagyada.modali, rjarry, thomas
In-Reply-To: <20260628090451.19970403@phoenix.local>
On 6/29/2026 12:04 AM, Stephen Hemminger wrote:
> On Sat, 27 Jun 2026 08:09:09 +0800
> fengchengwen <fengchengwen@huawei.com> wrote:
>
>>>
>>> +static int
>>> +ae4dma_dev_configure(struct rte_dma_dev *dev __rte_unused,
>>> + const struct rte_dma_conf *dev_conf,
>>> + uint32_t conf_sz)
>>> +{
>>> + if (sizeof(struct rte_dma_conf) != conf_sz)
>>> + return -EINVAL;
>>
>> This may break ABI compatible
>
> Ignore that suggestion. This is a reasonable way to handle new configuration
> functions. You need/want a minimal set of values. If rte_dma_conf grows in size
> then the code can add compatability; by requiring a minimum set of values
> and then setting the rest to zero.
>
> Something like
>
> static int
> ae4dma_dev_configure(struct rte_dma_dev *dev __rte_unused,
> const struct rte_dma_conf *dev_conf,
> size_t conf_sz)
> {
> if (conf_sz < sizeof(struct orig_rte_dma_conf))
> return -EINVAL;
+1 for this
>
> struct rte_dma_conf conf;
> memcpy(&conf, dev_conf, RTE_MIN(conf_sz, sizeof(conf)));
> dev_conf = &conf;
>
> Looking at rte_dma_conf the structure has holes and dmadev lib
> doesn't validate undefined flags, so it already has future ABI problems.
Yes, it indeed
^ permalink raw reply
* Re: [PATCH v2] dev: skip multi-process in hotplug
From: fengchengwen @ 2026-06-29 0:42 UTC (permalink / raw)
To: David Marchand, dev; +Cc: longli
In-Reply-To: <20260628140557.1718861-1-david.marchand@redhat.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
Minor suggestion: how about replace "bool do_mp = internal_conf->no_shconf == 0;" to "bool do_mp = !!internal_conf->no_shconf;" or bool do_mp = internal_conf->no_shconf;"
the no_shconf's prototype is "volatile unsigned", most of invokation is some like "if (internal_conf->no_shconf)"
On 6/28/2026 10:05 PM, David Marchand wrote:
> If multi-process is disabled (--no-shconf/--in-memory),
> there is no need to build a multi-process message.
>
> Signed-off-by: David Marchand <david.marchand@redhat.com>
> ---
> lib/eal/common/eal_common_dev.c | 46 ++++++++++++++++++++++++---------
> 1 file changed, 34 insertions(+), 12 deletions(-)
>
> diff --git a/lib/eal/common/eal_common_dev.c b/lib/eal/common/eal_common_dev.c
> index 762ed09e21..47fc45aa3e 100644
> --- a/lib/eal/common/eal_common_dev.c
> +++ b/lib/eal/common/eal_common_dev.c
> @@ -267,10 +267,16 @@ RTE_EXPORT_SYMBOL(rte_dev_probe)
> int
> rte_dev_probe(const char *devargs)
> {
> + const struct internal_config *internal_conf =
> + eal_get_internal_configuration();
> + bool do_mp = internal_conf->no_shconf == 0;
> struct eal_dev_mp_req req;
> struct rte_device *dev;
> int ret;
>
> + if (!do_mp)
> + goto skip_mp_req;
> +
> memset(&req, 0, sizeof(req));
> req.t = EAL_DEV_REQ_TYPE_ATTACH;
> strlcpy(req.devargs, devargs, EAL_DEV_MP_DEV_ARGS_MAX_LEN);
> @@ -294,6 +300,7 @@ rte_dev_probe(const char *devargs)
>
> /* attach a shared device from primary start from here: */
>
> +skip_mp_req:
> /* primary attach the new device itself. */
> ret = local_dev_probe(devargs, &dev);
>
> @@ -311,6 +318,9 @@ rte_dev_probe(const char *devargs)
> return ret;
> }
>
> + if (!do_mp)
> + goto skip_mp_notify;
> +
> /* primary send attach sync request to secondary. */
> ret = eal_dev_hotplug_request_to_secondary(&req);
>
> @@ -337,16 +347,19 @@ rte_dev_probe(const char *devargs)
> goto rollback;
> }
>
> +skip_mp_notify:
> return 0;
>
> rollback:
> - req.t = EAL_DEV_REQ_TYPE_ATTACH_ROLLBACK;
> + if (do_mp) {
> + req.t = EAL_DEV_REQ_TYPE_ATTACH_ROLLBACK;
>
> - /* primary send rollback request to secondary. */
> - if (eal_dev_hotplug_request_to_secondary(&req) != 0)
> - EAL_LOG(WARNING,
> - "Failed to rollback device attach on secondary."
> - "Devices in secondary may not sync with primary");
> + /* primary send rollback request to secondary. */
> + if (eal_dev_hotplug_request_to_secondary(&req) != 0)
> + EAL_LOG(WARNING,
> + "Failed to rollback device attach on secondary."
> + "Devices in secondary may not sync with primary");
> + }
>
> /* primary rollback itself. */
> if (local_dev_remove(dev) != 0)
> @@ -407,6 +420,9 @@ RTE_EXPORT_SYMBOL(rte_dev_remove)
> int
> rte_dev_remove(struct rte_device *dev)
> {
> + const struct internal_config *internal_conf =
> + eal_get_internal_configuration();
> + bool do_mp = internal_conf->no_shconf == 0;
> struct eal_dev_mp_req req;
> char *devargs;
> int ret;
> @@ -416,6 +432,9 @@ rte_dev_remove(struct rte_device *dev)
> return -ENOENT;
> }
>
> + if (!do_mp)
> + goto skip_mp_req;
> +
> ret = build_devargs(dev->bus->name, dev->name, "", &devargs);
> if (ret != 0)
> return ret;
> @@ -474,6 +493,7 @@ rte_dev_remove(struct rte_device *dev)
> goto rollback;
> }
>
> +skip_mp_req:
> /* primary detach the device itself. */
> ret = local_dev_remove(dev);
>
> @@ -490,13 +510,15 @@ rte_dev_remove(struct rte_device *dev)
> return 0;
>
> rollback:
> - req.t = EAL_DEV_REQ_TYPE_DETACH_ROLLBACK;
> + if (do_mp) {
> + req.t = EAL_DEV_REQ_TYPE_DETACH_ROLLBACK;
>
> - /* primary send rollback request to secondary. */
> - if (eal_dev_hotplug_request_to_secondary(&req) != 0)
> - EAL_LOG(WARNING,
> - "Failed to rollback device detach on secondary."
> - "Devices in secondary may not sync with primary");
> + /* primary send rollback request to secondary. */
> + if (eal_dev_hotplug_request_to_secondary(&req) != 0)
> + EAL_LOG(WARNING,
> + "Failed to rollback device detach on secondary."
> + "Devices in secondary may not sync with primary");
> + }
>
> return ret;
> }
^ permalink raw reply
* Re: [PATCH] net/af_xdp: add Rx metadata and dynamic timestamping support
From: Mark Blasko @ 2026-06-29 0:50 UTC (permalink / raw)
To: Stephen Hemminger
Cc: dev, Ciara Loftus, Maryam Tahhan, Joshua Washington,
Jasper Tran O'Leary
In-Reply-To: <20260623150638.266d8574@phoenix.local>
In AF_PACKET, the PMD reads the timestamp from socket ring headers
because the kernel stack processes the packet and allocates a socket
buffer. Since the kernel stack and socket buffer allocation are bypassed
in AF_XDP, UMEM frames are given directly to the PMD, which
means the kernel never generates these socket headers. Also, it
looks like the TAP PMD doesn't support RX timestamps.
Since the location of metadata in the UMEM headroom is determined
by the XDP program, the current driver implementation is coupled to
a specific XDP program layout. As an alternative, we could just
plumb the entire metadata headroom to the DPDK application and let
the application parse it based on whatever XDP program is in use.
That would couple the application and the XDP program, but would
at least decouple the driver and the XDP program.
On Tue, Jun 23, 2026 at 3:06 PM Stephen Hemminger
<stephen@networkplumber.org> wrote:
>
> On Tue, 23 Jun 2026 21:53:24 +0000
> Mark Blasko <blasko@google.com> wrote:
>
> > + if (rxq->rx_timestamp_enabled &&
> > + timestamp_dynfield_offset >= 0) {
> > + struct af_xdp_rx_metadata *meta;
> > +
> > + meta = (struct af_xdp_rx_metadata *)
> > + ((char *)rte_pktmbuf_mtod(bufs[i], void *) -
> > + sizeof(struct af_xdp_rx_metadata));
> > + *RTE_MBUF_DYNFIELD(bufs[i],
> > + timestamp_dynfield_offset,
> > + uint64_t *) = meta->rx_timestamp;
> > + bufs[i]->ol_flags |= timestamp_dynflag;
> > + }
> > +
>
> Why does XDP time stamp need to be different than how other drivers
> already do timestamps. See AF_PACKET and TAP device?
>
> Should not be driver specific here.
^ permalink raw reply
* [PATCH 1/2] net/e1000: fix igc RSS redirection table
From: Shuzo Ichiyoshi @ 2026-06-29 4:51 UTC (permalink / raw)
To: Ferruh Yigit, Alvin Zhang; +Cc: dev, Shuzo Ichiyoshi, stable
The IGC RETA register stores four 8-bit queue indexes.
igc_rss_configure() and igc_add_rss_filter() used a fresh
uninitialized union for each table entry and wrote the register only
every fourth entry. As a result, three bytes of each RETA register
came from stack garbage.
Build the register a word at a time and initialize all four queue
indexes before writing it.
Fixes: a5aeb2b9e225 ("net/igc: support Rx and Tx")
Fixes: 746664d546fb ("net/igc: support flow API")
Cc: stable@dpdk.org
Signed-off-by: Shuzo Ichiyoshi <deadcafe.beef@gmail.com>
---
drivers/net/intel/e1000/igc_txrx.c | 49 ++++++++++++++++--------------
1 file changed, 26 insertions(+), 23 deletions(-)
diff --git a/drivers/net/intel/e1000/igc_txrx.c b/drivers/net/intel/e1000/igc_txrx.c
index c13460f381..1ab8f2079d 100644
--- a/drivers/net/intel/e1000/igc_txrx.c
+++ b/drivers/net/intel/e1000/igc_txrx.c
@@ -828,17 +828,20 @@ igc_rss_configure(struct rte_eth_dev *dev)
uint16_t i;
/* Fill in redirection table. */
- for (i = 0; i < IGC_RSS_RDT_SIZD; i++) {
- union igc_rss_reta_reg reta;
- uint16_t q_idx, reta_idx;
-
- q_idx = (uint8_t)((dev->data->nb_rx_queues > 1) ?
- i % dev->data->nb_rx_queues : 0);
- reta_idx = i % sizeof(reta);
- reta.bytes[reta_idx] = q_idx;
- if (reta_idx == sizeof(reta) - 1)
- E1000_WRITE_REG_LE_VALUE(hw,
- E1000_RETA(i / sizeof(reta)), reta.dword);
+ for (i = 0; i < IGC_RSS_RDT_SIZD; i += IGC_RSS_RDT_REG_SIZE) {
+ union igc_rss_reta_reg reta = { .dword = 0 };
+ uint16_t reta_idx;
+
+ RTE_BUILD_BUG_ON(sizeof(reta.bytes) != IGC_RSS_RDT_REG_SIZE);
+ for (reta_idx = 0; reta_idx < IGC_RSS_RDT_REG_SIZE; reta_idx++) {
+ uint16_t q_idx;
+
+ q_idx = (uint8_t)((dev->data->nb_rx_queues > 1) ?
+ (i + reta_idx) % dev->data->nb_rx_queues : 0);
+ reta.bytes[reta_idx] = q_idx;
+ }
+ E1000_WRITE_REG_LE_VALUE(hw,
+ E1000_RETA(i / IGC_RSS_RDT_REG_SIZE), reta.dword);
}
/*
@@ -944,18 +947,18 @@ igc_add_rss_filter(struct rte_eth_dev *dev, struct igc_rss_filter *rss)
igc_rss_conf_set(rss_filter, &rss->conf);
/* Fill in redirection table. */
- for (i = 0, j = 0; i < IGC_RSS_RDT_SIZD; i++, j++) {
- union igc_rss_reta_reg reta;
- uint16_t q_idx, reta_idx;
-
- if (j == rss->conf.queue_num)
- j = 0;
- q_idx = rss->conf.queue[j];
- reta_idx = i % sizeof(reta);
- reta.bytes[reta_idx] = q_idx;
- if (reta_idx == sizeof(reta) - 1)
- E1000_WRITE_REG_LE_VALUE(hw,
- E1000_RETA(i / sizeof(reta)), reta.dword);
+ for (i = 0, j = 0; i < IGC_RSS_RDT_SIZD; i += IGC_RSS_RDT_REG_SIZE) {
+ union igc_rss_reta_reg reta = { .dword = 0 };
+ uint16_t reta_idx;
+
+ RTE_BUILD_BUG_ON(sizeof(reta.bytes) != IGC_RSS_RDT_REG_SIZE);
+ for (reta_idx = 0; reta_idx < IGC_RSS_RDT_REG_SIZE; reta_idx++, j++) {
+ if (j == rss->conf.queue_num)
+ j = 0;
+ reta.bytes[reta_idx] = rss->conf.queue[j];
+ }
+ E1000_WRITE_REG_LE_VALUE(hw,
+ E1000_RETA(i / IGC_RSS_RDT_REG_SIZE), reta.dword);
}
if (rss_conf.rss_key == NULL)
--
2.43.0
^ permalink raw reply related
* [PATCH 2/2] net/e1000: fix igc Tx descriptor ring wrap
From: Shuzo Ichiyoshi @ 2026-06-29 4:51 UTC (permalink / raw)
To: David Zage, Song Yoong Siang, Bruce Richardson
Cc: dev, Shuzo Ichiyoshi, stable
In-Reply-To: <20260629045511.473850-1-deadcafe.beef@gmail.com>
igc_xmit_pkts() reserves two extra descriptors for launch time.
It indexed sw_ring[tx_last + 2] without wrapping the descriptor
index first.
If tx_last is one of the last two descriptors in the ring, this
reads past the software ring. Wrap the index before looking up
last_id.
Fixes: 2e79349dcd07 ("net/e1000: fix igc launch time calculation")
Cc: stable@dpdk.org
Signed-off-by: Shuzo Ichiyoshi <deadcafe.beef@gmail.com>
---
drivers/net/intel/e1000/igc_txrx.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/net/intel/e1000/igc_txrx.c b/drivers/net/intel/e1000/igc_txrx.c
index 1ab8f2079d..d61fdb33a8 100644
--- a/drivers/net/intel/e1000/igc_txrx.c
+++ b/drivers/net/intel/e1000/igc_txrx.c
@@ -1834,7 +1834,11 @@ igc_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
* The "last descriptor" of the previously sent packet, if any,
* which used the last descriptor to allocate.
*/
- tx_end = sw_ring[tx_last + 2].last_id;
+ tx_end = (uint16_t)(tx_last + 2);
+ if (tx_end >= txq->nb_tx_desc)
+ tx_end = (uint16_t)(tx_end - txq->nb_tx_desc);
+
+ tx_end = sw_ring[tx_end].last_id;
/*
* The next descriptor following that "last descriptor" in the
--
2.43.0
^ permalink raw reply related
* [PATCH v4 1/9] net/enetc: fix TX BD structure
From: Gagandeep Singh @ 2026-06-29 5:18 UTC (permalink / raw)
To: dev; +Cc: hemant.agrawal, stable, Gagandeep Singh
In-Reply-To: <20260629051819.989176-1-g.singh@nxp.com>
The flags field in struct enetc_tx_bd was declared as uint16_t but
ENETC4 TX BDs only use an 8-bit flags byte. Fix the type to uint8_t
to match the hardware descriptor layout.
Fixes: 696fa399d797 ("net/enetc: add PMD with basic operations")
Cc: stable@dpdk.org
Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
drivers/net/enetc/base/enetc_hw.h | 7 +++----
drivers/net/enetc/enetc_rxtx.c | 17 +++++++++--------
2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/net/enetc/base/enetc_hw.h b/drivers/net/enetc/base/enetc_hw.h
index 173d677..19efadd 100644
--- a/drivers/net/enetc/base/enetc_hw.h
+++ b/drivers/net/enetc/base/enetc_hw.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright 2018-2024 NXP
+ * Copyright 2018-2026 NXP
*/
#ifndef _ENETC_HW_H_
@@ -198,8 +198,7 @@ enum enetc_bdr_type {TX, RX};
#define ENETC_TX_ADDR(txq, addr) ((void *)((txq)->enetc_txbdr + (addr)))
-#define ENETC_TXBD_FLAGS_IE BIT(13)
-#define ENETC_TXBD_FLAGS_F BIT(15)
+#define ENETC_TXBD_FLAGS_F BIT(7)
/* ENETC Parsed values (Little Endian) */
#define ENETC_PARSE_ERROR 0x8000
@@ -262,7 +261,7 @@ struct enetc_tx_bd {
uint8_t l3t:1;
uint8_t resv:5;
uint8_t l4t:3;
- uint16_t flags;
+ uint8_t flags;
};/* default layout */
uint32_t txstart;
uint32_t lstatus;
diff --git a/drivers/net/enetc/enetc_rxtx.c b/drivers/net/enetc/enetc_rxtx.c
index a2b8153..d3b98b3 100644
--- a/drivers/net/enetc/enetc_rxtx.c
+++ b/drivers/net/enetc/enetc_rxtx.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright 2018-2024 NXP
+ * Copyright 2018-2026 NXP
*/
#include <stdbool.h>
@@ -101,7 +101,7 @@ enetc_xmit_pkts(void *tx_queue,
tx_swbd = &tx_ring->q_swbd[i];
txbd->frm_len = tx_pkts[start]->pkt_len;
txbd->buf_len = txbd->frm_len;
- txbd->flags = rte_cpu_to_le_16(ENETC_TXBD_FLAGS_F);
+ txbd->flags = ENETC_TXBD_FLAGS_F;
txbd->addr = (uint64_t)(uintptr_t)
rte_cpu_to_le_64((size_t)tx_swbd->buffer_addr->buf_iova +
tx_swbd->buffer_addr->data_off);
@@ -133,13 +133,13 @@ enetc4_tx_offload_checksum(struct rte_mbuf *mbuf, struct enetc_tx_bd *txbd)
txbd->ipcs = ENETC4_TXBD_IPCS;
txbd->l3_start = mbuf->l2_len;
txbd->l3_hdr_size = mbuf->l3_len / 4;
- txbd->flags |= rte_cpu_to_le_16(ENETC4_TXBD_FLAGS_L_TX_CKSUM);
+ txbd->flags |= ENETC4_TXBD_FLAGS_L_TX_CKSUM;
if ((mbuf->ol_flags & RTE_MBUF_F_TX_UDP_CKSUM) == RTE_MBUF_F_TX_UDP_CKSUM) {
- txbd->l4t = rte_cpu_to_le_16(ENETC4_TXBD_L4T_UDP);
- txbd->flags |= rte_cpu_to_le_16(ENETC4_TXBD_FLAGS_L4CS);
+ txbd->l4t = ENETC4_TXBD_L4T_UDP;
+ txbd->flags |= ENETC4_TXBD_FLAGS_L4CS;
} else if ((mbuf->ol_flags & RTE_MBUF_F_TX_TCP_CKSUM) == RTE_MBUF_F_TX_TCP_CKSUM) {
- txbd->l4t = rte_cpu_to_le_16(ENETC4_TXBD_L4T_TCP);
- txbd->flags |= rte_cpu_to_le_16(ENETC4_TXBD_FLAGS_L4CS);
+ txbd->l4t = ENETC4_TXBD_L4T_TCP;
+ txbd->flags |= ENETC4_TXBD_FLAGS_L4CS;
}
}
}
@@ -172,7 +172,7 @@ enetc_xmit_pkts_nc(void *tx_queue,
dcbf(data + j);
txbd = ENETC_TXBD(*tx_ring, i);
- txbd->flags = rte_cpu_to_le_16(ENETC4_TXBD_FLAGS_F);
+ txbd->flags = 0;
if (tx_ring->q_swbd[i].buffer_addr->ol_flags & ENETC4_TX_CKSUM_OFFLOAD_MASK)
enetc4_tx_offload_checksum(tx_ring->q_swbd[i].buffer_addr, txbd);
@@ -182,6 +182,7 @@ enetc_xmit_pkts_nc(void *tx_queue,
txbd->addr = (uint64_t)(uintptr_t)
rte_cpu_to_le_64((size_t)tx_swbd->buffer_addr->buf_iova +
tx_swbd->buffer_addr->data_off);
+ txbd->flags |= ENETC4_TXBD_FLAGS_F;
i++;
start++;
if (unlikely(i == tx_ring->bd_count))
--
2.25.1
^ permalink raw reply related
* [PATCH v4 4/9] net/enetc: update random MAC generation code
From: Gagandeep Singh @ 2026-06-29 5:18 UTC (permalink / raw)
To: dev; +Cc: hemant.agrawal, Gagandeep Singh
In-Reply-To: <20260629051819.989176-1-g.singh@nxp.com>
Use rte_eth_random_addr() instead of manual rte_rand() based MAC
generation. Also handle VF path by writing to ENETC_SIPMAR0/1 instead
of ENETC_PSIPMAR0/1 when running as a VF.
Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
drivers/net/enetc/enetc_ethdev.c | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/drivers/net/enetc/enetc_ethdev.c b/drivers/net/enetc/enetc_ethdev.c
index 8196377..55b0e0b 100644
--- a/drivers/net/enetc/enetc_ethdev.c
+++ b/drivers/net/enetc/enetc_ethdev.c
@@ -195,20 +195,18 @@ enetc_hardware_init(struct enetc_eth_hw *hw)
}
if ((high_mac | low_mac) == 0) {
- char *first_byte;
-
ENETC_PMD_NOTICE("MAC is not available for this SI, "
"set random MAC");
- mac = (uint32_t *)hw->mac.addr;
- *mac = (uint32_t)rte_rand();
- first_byte = (char *)mac;
- *first_byte &= 0xfe; /* clear multicast bit */
- *first_byte |= 0x02; /* set local assignment bit (IEEE802) */
-
- enetc_port_wr(enetc_hw, ENETC_PSIPMAR0(0), *mac);
- mac++;
- *mac = (uint16_t)rte_rand();
- enetc_port_wr(enetc_hw, ENETC_PSIPMAR1(0), *mac);
+ rte_eth_random_addr(hw->mac.addr);
+ high_mac = *(uint32_t *)hw->mac.addr;
+ low_mac = *(uint16_t *)(hw->mac.addr + 4);
+ if (hw->device_id == ENETC_DEV_ID_VF) {
+ enetc_wr(enetc_hw, ENETC_SIPMAR0, high_mac);
+ enetc_wr(enetc_hw, ENETC_SIPMAR1, low_mac);
+ } else {
+ enetc_port_wr(enetc_hw, ENETC_PSIPMAR0(0), high_mac);
+ enetc_port_wr(enetc_hw, ENETC_PSIPMAR1(0), low_mac);
+ }
enetc_print_ethaddr("New address: ",
(const struct rte_ether_addr *)hw->mac.addr);
}
--
2.25.1
^ permalink raw reply related
* [PATCH v4 5/9] net/enetc: support scatter-gather
From: Gagandeep Singh @ 2026-06-29 5:18 UTC (permalink / raw)
To: dev; +Cc: hemant.agrawal, Vanshika Shukla
In-Reply-To: <20260629051819.989176-1-g.singh@nxp.com>
From: Vanshika Shukla <vanshika.shukla@nxp.com>
Add scatter-gather support for ENETC4 PMD:
- Add ENETC_RXBD_LSTATUS_R/F bits for RX BD status
- Add ENETC4_MAX_SEGS (63) for max segments per TX packet
- Update enetc4_vf_dev_infos_get to fill nb_seg_max, offloads,
max queues and packet length
- Extend enetc_xmit_pkts_nc to handle multi-segment mbufs
- Extend enetc_clean_rx_ring_nc to chain scatter-gather segments
using LSTATUS_R/F bits
Signed-off-by: Vanshika Shukla <vanshika.shukla@nxp.com>
---
doc/guides/nics/features/enetc4.ini | 1 +
doc/guides/rel_notes/release_26_07.rst | 3 +-
drivers/net/enetc/base/enetc_hw.h | 2 +
drivers/net/enetc/enetc.h | 7 +-
drivers/net/enetc/enetc4_ethdev.c | 10 +-
drivers/net/enetc/enetc4_vf.c | 46 +++++++--
drivers/net/enetc/enetc_rxtx.c | 132 ++++++++++++++++---------
7 files changed, 141 insertions(+), 60 deletions(-)
diff --git a/doc/guides/nics/features/enetc4.ini b/doc/guides/nics/features/enetc4.ini
index 87425f4..698140e 100644
--- a/doc/guides/nics/features/enetc4.ini
+++ b/doc/guides/nics/features/enetc4.ini
@@ -17,6 +17,7 @@ Basic stats = Y
L3 checksum offload = Y
L4 checksum offload = Y
Queue start/stop = Y
+Scattered Rx = Y
Linux = Y
ARMv8 = Y
Usage doc = Y
diff --git a/doc/guides/rel_notes/release_26_07.rst b/doc/guides/rel_notes/release_26_07.rst
index 35476c2..f900145 100644
--- a/doc/guides/rel_notes/release_26_07.rst
+++ b/doc/guides/rel_notes/release_26_07.rst
@@ -189,7 +189,8 @@ New Features
* **Updated NXP ENETC ethernet driver.**
- * Added support for ESP packet type in packet parsing
+ * Added support for ESP packet type in packet parsing.
+ * Added scatter-gather support for ENETC4 PFs and VFs.
Removed Items
-------------
diff --git a/drivers/net/enetc/base/enetc_hw.h b/drivers/net/enetc/base/enetc_hw.h
index f79c950..6e96562 100644
--- a/drivers/net/enetc/base/enetc_hw.h
+++ b/drivers/net/enetc/base/enetc_hw.h
@@ -230,6 +230,8 @@ enum enetc_bdr_type {TX, RX};
(0x0005 | ENETC_PKT_TYPE_IPV4)
#define ENETC_PKT_TYPE_IPV6_ESP \
(0x0005 | ENETC_PKT_TYPE_IPV6)
+#define ENETC_RXBD_LSTATUS_R BIT(30)
+#define ENETC_RXBD_LSTATUS_F BIT(31)
/* PCI device info */
struct enetc_hw {
diff --git a/drivers/net/enetc/enetc.h b/drivers/net/enetc/enetc.h
index 4d99b5b..01da898 100644
--- a/drivers/net/enetc/enetc.h
+++ b/drivers/net/enetc/enetc.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright 2018-2019,2024 NXP
+ * Copyright 2018-2019,2024-2026 NXP
*/
#ifndef _ENETC_H_
@@ -28,6 +28,8 @@
#define MIN_BD_COUNT 32
/* BD ALIGN */
#define BD_ALIGN 8
+/* Max segments per ENETC4 TX packet (scatter-gather) */
+#define ENETC4_MAX_SEGS 63
/* minimum frame size supported */
#define ENETC_MAC_MINFRM_SIZE 68
@@ -90,6 +92,9 @@ struct enetc_bdr {
int next_to_alloc; /* Rx */
};
struct rte_mempool *mb_pool; /* mbuf pool to populate RX ring. */
+ /* Partial scatter-gather chain persisted across burst calls. */
+ struct rte_mbuf *pkt_first_seg; /* first segment of in-progress frame */
+ struct rte_mbuf *pkt_last_seg; /* last segment linked so far */
struct rte_eth_dev *ndev;
uint64_t ierrors;
uint8_t rx_deferred_start;
diff --git a/drivers/net/enetc/enetc4_ethdev.c b/drivers/net/enetc/enetc4_ethdev.c
index 154fc09..ad1ef4d 100644
--- a/drivers/net/enetc/enetc4_ethdev.c
+++ b/drivers/net/enetc/enetc4_ethdev.c
@@ -14,13 +14,15 @@
static uint64_t dev_rx_offloads_sup =
RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
- RTE_ETH_RX_OFFLOAD_TCP_CKSUM;
+ RTE_ETH_RX_OFFLOAD_TCP_CKSUM |
+ RTE_ETH_RX_OFFLOAD_SCATTER;
/* Supported Tx offloads */
static uint64_t dev_tx_offloads_sup =
RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
- RTE_ETH_TX_OFFLOAD_TCP_CKSUM;
+ RTE_ETH_TX_OFFLOAD_TCP_CKSUM |
+ RTE_ETH_TX_OFFLOAD_MULTI_SEGS;
static int
enetc4_dev_start(struct rte_eth_dev *dev)
@@ -199,11 +201,15 @@ enetc4_dev_infos_get(struct rte_eth_dev *dev,
.nb_max = MAX_BD_COUNT,
.nb_min = MIN_BD_COUNT,
.nb_align = BD_ALIGN,
+ .nb_seg_max = ENETC4_MAX_SEGS,
+ .nb_mtu_seg_max = ENETC4_MAX_SEGS,
};
dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
.nb_max = MAX_BD_COUNT,
.nb_min = MIN_BD_COUNT,
.nb_align = BD_ALIGN,
+ .nb_seg_max = ENETC4_MAX_SEGS,
+ .nb_mtu_seg_max = ENETC4_MAX_SEGS,
};
dev_info->max_rx_queues = hw->max_rx_queues;
dev_info->max_tx_queues = hw->max_tx_queues;
diff --git a/drivers/net/enetc/enetc4_vf.c b/drivers/net/enetc/enetc4_vf.c
index bec7128..9dc4e1d 100644
--- a/drivers/net/enetc/enetc4_vf.c
+++ b/drivers/net/enetc/enetc4_vf.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright 2024 NXP
+ * Copyright 2024-2026 NXP
*/
#include <stdbool.h>
@@ -18,8 +18,19 @@ uint16_t enetc_crc_table[ENETC_CRC_TABLE_SIZE];
bool enetc_crc_gen;
/* Supported Rx offloads */
-static uint64_t dev_vf_rx_offloads_sup =
- RTE_ETH_RX_OFFLOAD_VLAN_FILTER;
+static uint64_t dev_rx_offloads_sup =
+ RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
+ RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
+ RTE_ETH_RX_OFFLOAD_TCP_CKSUM |
+ RTE_ETH_RX_OFFLOAD_VLAN_FILTER |
+ RTE_ETH_RX_OFFLOAD_SCATTER;
+
+/* Supported Tx offloads */
+static uint64_t dev_tx_offloads_sup =
+ RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
+ RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
+ RTE_ETH_TX_OFFLOAD_TCP_CKSUM |
+ RTE_ETH_TX_OFFLOAD_MULTI_SEGS;
static void
enetc_gen_crc_table(void)
@@ -61,21 +72,38 @@ static int
enetc4_vf_dev_infos_get(struct rte_eth_dev *dev,
struct rte_eth_dev_info *dev_info)
{
- int ret = 0;
+ struct enetc_eth_hw *hw =
+ ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
PMD_INIT_FUNC_TRACE();
- ret = enetc4_dev_infos_get(dev, dev_info);
- if (ret)
- return ret;
-
+ dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
+ .nb_max = MAX_BD_COUNT,
+ .nb_min = MIN_BD_COUNT,
+ .nb_align = BD_ALIGN,
+ .nb_seg_max = ENETC4_MAX_SEGS,
+ .nb_mtu_seg_max = ENETC4_MAX_SEGS,
+ };
+ dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
+ .nb_max = MAX_BD_COUNT,
+ .nb_min = MIN_BD_COUNT,
+ .nb_align = BD_ALIGN,
+ .nb_seg_max = ENETC4_MAX_SEGS,
+ .nb_mtu_seg_max = ENETC4_MAX_SEGS,
+ };
+ dev_info->max_rx_queues = hw->max_rx_queues;
+ dev_info->max_tx_queues = hw->max_tx_queues;
+ dev_info->max_rx_pktlen = ENETC4_MAC_MAXFRM_SIZE;
dev_info->max_mtu = dev_info->max_rx_pktlen - (RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN);
dev_info->max_mac_addrs = ENETC4_MAC_ENTRIES;
- dev_info->rx_offload_capa |= dev_vf_rx_offloads_sup;
+ dev_info->rx_offload_capa = dev_rx_offloads_sup;
+ dev_info->tx_offload_capa = dev_tx_offloads_sup;
+ dev_info->flow_type_rss_offloads = ENETC_RSS_OFFLOAD_ALL;
return 0;
}
+
int
enetc4_vf_dev_stop(struct rte_eth_dev *dev __rte_unused)
{
diff --git a/drivers/net/enetc/enetc_rxtx.c b/drivers/net/enetc/enetc_rxtx.c
index 94177bb..3c61d43 100644
--- a/drivers/net/enetc/enetc_rxtx.c
+++ b/drivers/net/enetc/enetc_rxtx.c
@@ -149,54 +149,65 @@ enetc_xmit_pkts_nc(void *tx_queue,
struct rte_mbuf **tx_pkts,
uint16_t nb_pkts)
{
- struct enetc_swbd *tx_swbd;
- int i, start, bds_to_use;
- struct enetc_tx_bd *txbd;
struct enetc_bdr *tx_ring = (struct enetc_bdr *)tx_queue;
- unsigned int buflen, j;
+ int i, start, bds_to_use, bd_count;
+ struct enetc_tx_bd *txbd = NULL;
+ struct rte_mbuf *seg;
+ uint16_t seg_len, segs_per_pkt;
+ bool is_first_seg;
+ unsigned int j;
uint8_t *data;
i = tx_ring->next_to_use;
-
bds_to_use = enetc_bd_unused(tx_ring);
- if (bds_to_use < nb_pkts)
- nb_pkts = bds_to_use;
+ bd_count = tx_ring->bd_count;
start = 0;
- while (nb_pkts--) {
- tx_ring->q_swbd[i].buffer_addr = tx_pkts[start];
+ while (start < nb_pkts) {
+ seg = tx_pkts[start];
+ segs_per_pkt = seg->nb_segs;
- buflen = rte_pktmbuf_pkt_len(tx_ring->q_swbd[i].buffer_addr);
- data = rte_pktmbuf_mtod(tx_ring->q_swbd[i].buffer_addr, void *);
- for (j = 0; j <= buflen; j += RTE_CACHE_LINE_SIZE)
- dcbf(data + j);
+ if (bds_to_use < segs_per_pkt)
+ break;
- txbd = ENETC_TXBD(*tx_ring, i);
- txbd->flags = 0;
- if (tx_ring->q_swbd[i].buffer_addr->ol_flags & ENETC4_TX_CKSUM_OFFLOAD_MASK)
- enetc4_tx_offload_checksum(tx_ring->q_swbd[i].buffer_addr, txbd);
+ is_first_seg = true;
+ while (seg) {
+ tx_ring->q_swbd[i].buffer_addr = NULL;
+ seg_len = rte_pktmbuf_data_len(seg);
+ data = rte_pktmbuf_mtod(seg, void *);
+
+ /* Flush payload to PoC so HW DMA reads the correct data. */
+ for (j = 0; j < seg_len; j += RTE_CACHE_LINE_SIZE)
+ dcbf(data + j);
+ /* Cover the last byte of an unaligned buffer. */
+ dcbf(data + (seg_len - 1));
+
+ txbd = ENETC_TXBD(*tx_ring, i);
+ txbd->flags = 0;
+ if (is_first_seg) {
+ tx_ring->q_swbd[i].buffer_addr = tx_pkts[start];
+ txbd->frm_len = rte_pktmbuf_pkt_len(seg);
+ if (seg->ol_flags & ENETC4_TX_CKSUM_OFFLOAD_MASK)
+ enetc4_tx_offload_checksum(seg, txbd);
+ is_first_seg = false;
+ }
+
+ txbd->buf_len = rte_cpu_to_le_16(seg_len);
+ txbd->addr = rte_cpu_to_le_64(rte_mbuf_data_iova(seg));
+ seg = seg->next;
+ i++;
+ bds_to_use--;
+ if (unlikely(i == bd_count))
+ i = 0;
+ }
- tx_swbd = &tx_ring->q_swbd[i];
- txbd->frm_len = buflen;
- txbd->buf_len = txbd->frm_len;
- txbd->addr = (uint64_t)(uintptr_t)
- rte_cpu_to_le_64((size_t)tx_swbd->buffer_addr->buf_iova +
- tx_swbd->buffer_addr->data_off);
- txbd->flags |= ENETC4_TXBD_FLAGS_F;
- i++;
+ /* Set the frame-last flag on the final BD of this packet. */
+ if (likely(txbd))
+ txbd->flags |= ENETC4_TXBD_FLAGS_F;
start++;
- if (unlikely(i == tx_ring->bd_count))
- i = 0;
}
- /* we're only cleaning up the Tx ring here, on the assumption that
- * software is slower than hardware and hardware completed sending
- * older frames out by now.
- * We're also cleaning up the ring before kicking off Tx for the new
- * batch to minimize chances of contention on the Tx ring
- */
enetc_clean_tx_ring(tx_ring);
-
tx_ring->next_to_use = i;
enetc_wr_reg(tx_ring->tcir, i);
return start;
@@ -501,38 +512,63 @@ enetc_clean_rx_ring_nc(struct enetc_bdr *rx_ring,
int cleaned_cnt, i;
struct enetc_swbd *rx_swbd;
union enetc_rx_bd *rxbd, rxbd_temp;
+ struct rte_mbuf *first_seg, *cur_seg;
uint32_t bd_status;
uint8_t *data;
uint32_t j;
+ struct rte_mbuf *seg;
+ uint16_t data_len;
/* next descriptor to process */
i = rx_ring->next_to_clean;
- /* next descriptor to process */
rxbd = ENETC_RXBD(*rx_ring, i);
-
cleaned_cnt = enetc_bd_unused(rx_ring);
rx_swbd = &rx_ring->q_swbd[i];
+ /* Restore partial multi-segment chain from a previous burst. */
+ first_seg = rx_ring->pkt_first_seg;
+ cur_seg = rx_ring->pkt_last_seg;
+
while (likely(rx_frm_cnt < work_limit)) {
rxbd_temp = *rxbd;
bd_status = rte_le_to_cpu_32(rxbd_temp.r.lstatus);
- if (!bd_status)
+ /* LSTATUS_R indicates this BD has been written by HW */
+ if (!(bd_status & ENETC_RXBD_LSTATUS_R))
break;
if (rxbd_temp.r.error)
rx_ring->ierrors++;
- rx_swbd->buffer_addr->pkt_len = rxbd_temp.r.buf_len -
- rx_ring->crc_len;
- rx_swbd->buffer_addr->data_len = rx_swbd->buffer_addr->pkt_len;
- rx_swbd->buffer_addr->hash.rss = rxbd_temp.r.rss_hash;
- enetc_dev_rx_parse(rx_swbd->buffer_addr,
- rxbd_temp.r.parse_summary);
+ seg = rx_swbd->buffer_addr;
+ data_len = rte_le_to_cpu_16(rxbd_temp.r.buf_len);
+ seg->data_len = data_len;
+
+ if (!first_seg) {
+ first_seg = seg;
+ cur_seg = seg;
+ first_seg->pkt_len = data_len;
+ enetc_dev_rx_parse(first_seg, rxbd_temp.r.parse_summary);
+ first_seg->hash.rss = rxbd_temp.r.rss_hash;
+ } else {
+ first_seg->pkt_len += data_len;
+ first_seg->nb_segs++;
+ cur_seg->next = seg;
+ cur_seg = seg;
+ }
- data = rte_pktmbuf_mtod(rx_swbd->buffer_addr, void *);
- for (j = 0; j <= rx_swbd->buffer_addr->pkt_len; j += RTE_CACHE_LINE_SIZE)
+ /* Invalidate packet data cache lines so CPU reads HW-written data. */
+ data = rte_pktmbuf_mtod(seg, void *);
+ for (j = 0; j < data_len; j += RTE_CACHE_LINE_SIZE)
dccivac(data + j);
+ dccivac(data + (data_len - 1));
+
+ if (bd_status & ENETC_RXBD_LSTATUS_F) {
+ seg->next = NULL;
+ first_seg->pkt_len -= rx_ring->crc_len;
+ rx_pkts[rx_frm_cnt] = first_seg;
+ rx_frm_cnt++;
+ first_seg = NULL;
+ }
- rx_pkts[rx_frm_cnt] = rx_swbd->buffer_addr;
cleaned_cnt++;
rx_swbd++;
i++;
@@ -541,9 +577,11 @@ enetc_clean_rx_ring_nc(struct enetc_bdr *rx_ring,
rx_swbd = &rx_ring->q_swbd[i];
}
rxbd = ENETC_RXBD(*rx_ring, i);
- rx_frm_cnt++;
}
+ /* Save partial chain for the next burst if frame is incomplete. */
+ rx_ring->pkt_first_seg = first_seg;
+ rx_ring->pkt_last_seg = cur_seg;
rx_ring->next_to_clean = i;
enetc_refill_rx_ring(rx_ring, cleaned_cnt);
--
2.25.1
^ permalink raw reply related
* [PATCH v4 7/9] net/enetc: add devargs to control VSI-PSI timeout and delay
From: Gagandeep Singh @ 2026-06-29 5:18 UTC (permalink / raw)
To: dev; +Cc: hemant.agrawal, Gagandeep Singh
In-Reply-To: <20260629051819.989176-1-g.singh@nxp.com>
Add two new devargs for ENETC4 VF:
- enetc4_vsi_timeout: VSI-PSI message wait timeout (iteration count)
- enetc4_vsi_delay: VSI-PSI message wait delay in microseconds
Store the values in struct enetc_eth_hw and use them in
enetc4_msg_vsi_send() instead of the hardcoded defaults.
Fall back to ENETC4_DEF_VSI_WAIT_TIMEOUT_UPDATE /
ENETC4_DEF_VSI_WAIT_DELAY_UPDATE when not set.
Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
doc/guides/nics/enetc4.rst | 18 +++++++
doc/guides/rel_notes/release_26_07.rst | 2 +
drivers/net/enetc/enetc.h | 2 +
drivers/net/enetc/enetc4_vf.c | 68 +++++++++++++++++++-------
4 files changed, 73 insertions(+), 17 deletions(-)
diff --git a/doc/guides/nics/enetc4.rst b/doc/guides/nics/enetc4.rst
index 7b94941..3c4af22 100644
--- a/doc/guides/nics/enetc4.rst
+++ b/doc/guides/nics/enetc4.rst
@@ -110,3 +110,21 @@ VF-specific devargs
Usage example::
dpdk-testpmd -a 0000:00:01.0,enetc4_vsi_disable -- -i
+
+``enetc4_vsi_timeout``
+ Set the VSI-PSI message wait timeout as an iteration count.
+ Controls how many polling iterations the driver waits for a VSI-PSI
+ response before timing out.
+ Defaults to ``ENETC4_DEF_VSI_WAIT_TIMEOUT_UPDATE`` when not set.
+
+ Usage example::
+
+ dpdk-testpmd -a 0000:00:01.0,enetc4_vsi_timeout=200 -- -i
+
+``enetc4_vsi_delay``
+ Set the VSI-PSI message wait delay in microseconds between polling iterations.
+ Defaults to ``ENETC4_DEF_VSI_WAIT_DELAY_UPDATE`` when not set.
+
+ Usage example::
+
+ dpdk-testpmd -a 0000:00:01.0,enetc4_vsi_delay=10 -- -i
diff --git a/doc/guides/rel_notes/release_26_07.rst b/doc/guides/rel_notes/release_26_07.rst
index 783ad16..192623d 100644
--- a/doc/guides/rel_notes/release_26_07.rst
+++ b/doc/guides/rel_notes/release_26_07.rst
@@ -193,6 +193,8 @@ New Features
* Added scatter-gather support for ENETC4 PFs and VFs.
* Added devargs option ``enetc4_vsi_disable`` to disable VSI-PSI
messaging.
+ * Added devargs options ``enetc4_vsi_timeout`` and ``enetc4_vsi_delay``
+ for VSI-PSI messaging timeout and delay.
Removed Items
-------------
diff --git a/drivers/net/enetc/enetc.h b/drivers/net/enetc/enetc.h
index 01da898..80844e9 100644
--- a/drivers/net/enetc/enetc.h
+++ b/drivers/net/enetc/enetc.h
@@ -112,6 +112,8 @@ struct enetc_eth_hw {
uint32_t num_rss;
uint32_t max_rx_queues;
uint32_t max_tx_queues;
+ uint32_t vsi_timeout; /* VSI-PSI message wait timeout (iterations) */
+ uint32_t vsi_delay; /* VSI-PSI message wait delay (us) */
};
/*
diff --git a/drivers/net/enetc/enetc4_vf.c b/drivers/net/enetc/enetc4_vf.c
index 44c0dc0..62206d7 100644
--- a/drivers/net/enetc/enetc4_vf.c
+++ b/drivers/net/enetc/enetc4_vf.c
@@ -10,6 +10,8 @@
#include "enetc.h"
#define ENETC4_VSI_DISABLE "enetc4_vsi_disable"
+#define ENETC4_VSI_TIMEOUT "enetc4_vsi_timeout"
+#define ENETC4_VSI_DELAY "enetc4_vsi_delay"
#define ENETC_CRC_TABLE_SIZE 256
#define ENETC_POLY 0x1021
@@ -262,10 +264,13 @@ enetc4_process_psi_msg(struct rte_eth_dev *eth_dev, struct enetc_hw *enetc_hw)
}
static int
-enetc4_msg_vsi_send(struct enetc_hw *enetc_hw, struct enetc_msg_swbd *msg)
+enetc4_msg_vsi_send(struct enetc_eth_hw *hw, struct enetc_msg_swbd *msg)
{
- int timeout = ENETC4_DEF_VSI_WAIT_TIMEOUT_UPDATE;
- int delay_us = ENETC4_DEF_VSI_WAIT_DELAY_UPDATE;
+ struct enetc_hw *enetc_hw = &hw->hw;
+ int timeout = hw->vsi_timeout ? (int)hw->vsi_timeout :
+ ENETC4_DEF_VSI_WAIT_TIMEOUT_UPDATE;
+ int delay_us = hw->vsi_delay ? (int)hw->vsi_delay :
+ ENETC4_DEF_VSI_WAIT_DELAY_UPDATE;
uint8_t class_id = 0;
int err = 0;
int vsimsgsr;
@@ -382,7 +387,7 @@ enetc4_vf_set_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *addr)
ENETC_CMD_ID_SET_PRIMARY_MAC, 0, 0, 0);
/* send the command and wait */
- err = enetc4_msg_vsi_send(enetc_hw, msg);
+ err = enetc4_msg_vsi_send(hw, msg);
if (err) {
ENETC_PMD_ERR("VSI message send error");
goto end;
@@ -426,7 +431,6 @@ static int
enetc4_vf_promisc_send_message(struct rte_eth_dev *dev, bool promisc_en)
{
struct enetc_eth_hw *hw = ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- struct enetc_hw *enetc_hw = &hw->hw;
struct enetc_msg_cmd_set_promisc *cmd;
struct enetc_msg_swbd *msg;
uint32_t msg_size;
@@ -466,7 +470,7 @@ enetc4_vf_promisc_send_message(struct rte_eth_dev *dev, bool promisc_en)
ENETC_CMD_ID_SET_MAC_PROMISCUOUS, 0, 0, 0);
/* send the command and wait */
- err = enetc4_msg_vsi_send(enetc_hw, msg);
+ err = enetc4_msg_vsi_send(hw, msg);
if (err) {
ENETC_PMD_ERR("VSI message send error");
goto end;
@@ -483,7 +487,6 @@ static int
enetc4_vf_allmulti_send_message(struct rte_eth_dev *dev, bool mc_promisc)
{
struct enetc_eth_hw *hw = ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- struct enetc_hw *enetc_hw = &hw->hw;
struct enetc_msg_cmd_set_promisc *cmd;
struct enetc_msg_swbd *msg;
uint32_t msg_size;
@@ -524,7 +527,7 @@ enetc4_vf_allmulti_send_message(struct rte_eth_dev *dev, bool mc_promisc)
ENETC_CMD_ID_SET_MAC_PROMISCUOUS, 0, 0, 0);
/* send the command and wait */
- err = enetc4_msg_vsi_send(enetc_hw, msg);
+ err = enetc4_msg_vsi_send(hw, msg);
if (err) {
ENETC_PMD_ERR("VSI message send error");
goto end;
@@ -630,7 +633,7 @@ enetc4_vf_get_link_status(struct rte_eth_dev *dev, struct enetc_psi_reply_msg *r
ENETC_CMD_ID_GET_LINK_STATUS, 0, 0, 0);
/* send the command and wait */
- err = enetc4_msg_vsi_send(enetc_hw, msg);
+ err = enetc4_msg_vsi_send(hw, msg);
if (err) {
ENETC_PMD_ERR("VSI message send error");
goto end;
@@ -676,7 +679,7 @@ enetc4_vf_get_link_speed(struct rte_eth_dev *dev, struct enetc_psi_reply_msg *re
ENETC_CMD_ID_GET_LINK_SPEED, 0, 0, 0);
/* send the command and wait */
- err = enetc4_msg_vsi_send(enetc_hw, msg);
+ err = enetc4_msg_vsi_send(hw, msg);
if (err) {
ENETC_PMD_ERR("VSI message send error");
goto end;
@@ -819,7 +822,6 @@ static int
enetc4_vf_vlan_promisc(struct rte_eth_dev *dev, bool promisc_en)
{
struct enetc_eth_hw *hw = ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- struct enetc_hw *enetc_hw = &hw->hw;
struct enetc_msg_cmd_set_vlan_promisc *cmd;
struct enetc_msg_swbd *msg;
uint32_t msg_size;
@@ -858,7 +860,7 @@ enetc4_vf_vlan_promisc(struct rte_eth_dev *dev, bool promisc_en)
ENETC_CMD_ID_SET_VLAN_PROMISCUOUS, 0, 0, 0);
/* send the command and wait */
- err = enetc4_msg_vsi_send(enetc_hw, msg);
+ err = enetc4_msg_vsi_send(hw, msg);
if (err) {
ENETC_PMD_ERR("VSI message send error");
goto end;
@@ -921,7 +923,7 @@ enetc4_vf_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *addr,
ENETC_MSG_ADD_EXACT_MAC_ENTRIES, 0, 0, 0);
/* send the command and wait */
- err = enetc4_msg_vsi_send(enetc_hw, msg);
+ err = enetc4_msg_vsi_send(hw, msg);
if (err) {
ENETC_PMD_ERR("VSI message send error");
goto end;
@@ -1021,7 +1023,7 @@ static int enetc4_vf_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id,
}
/* send the command and wait */
- err = enetc4_msg_vsi_send(enetc_hw, msg);
+ err = enetc4_msg_vsi_send(hw, msg);
if (err) {
ENETC_PMD_ERR("VSI message send error");
goto end;
@@ -1104,7 +1106,6 @@ static int
enetc4_vf_link_register_notif(struct rte_eth_dev *dev, bool enable)
{
struct enetc_eth_hw *hw = ENETC_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- struct enetc_hw *enetc_hw = &hw->hw;
struct enetc_msg_swbd *msg;
struct rte_eth_link link;
uint32_t msg_size;
@@ -1138,7 +1139,7 @@ enetc4_vf_link_register_notif(struct rte_eth_dev *dev, bool enable)
cmd, 0, 0, 0);
/* send the command and wait */
- err = enetc4_msg_vsi_send(enetc_hw, msg);
+ err = enetc4_msg_vsi_send(hw, msg);
if (err)
ENETC_PMD_ERR("VSI msg error for link status notification");
@@ -1322,12 +1323,43 @@ enetc4_vf_dev_init(struct rte_eth_dev *eth_dev)
kvlist = rte_kvargs_parse(eth_dev->device->devargs->args,
NULL);
if (kvlist) {
+ const char *val;
+
if (rte_kvargs_count(kvlist, ENETC4_VSI_DISABLE) != 0) {
ENETC_PMD_NOTICE("VSI messaging disabled by devarg");
eth_dev->dev_ops = &enetc4_vf_ops_no_vsi_m;
} else {
eth_dev->dev_ops = &enetc4_vf_ops;
}
+
+ /* parse optional VSI-PSI timeout devarg */
+ val = rte_kvargs_get(kvlist, ENETC4_VSI_TIMEOUT);
+ if (val) {
+ errno = 0;
+ hw->vsi_timeout = (uint32_t)strtoul(val, NULL, 0);
+ if (errno != 0 || hw->vsi_timeout == 0) {
+ ENETC_PMD_ERR("Invalid VSI Timeout value = %u",
+ hw->vsi_timeout);
+ rte_kvargs_free(kvlist);
+ return -1;
+ }
+ ENETC_PMD_NOTICE("VSI timeout set to %u", hw->vsi_timeout);
+ }
+
+ /* parse optional VSI-PSI delay devarg */
+ val = rte_kvargs_get(kvlist, ENETC4_VSI_DELAY);
+ if (val) {
+ errno = 0;
+ hw->vsi_delay = (uint32_t)strtoul(val, NULL, 0);
+ if (errno != 0 || hw->vsi_delay == 0) {
+ ENETC_PMD_ERR("Invalid VSI Delay value = %u",
+ hw->vsi_delay);
+ rte_kvargs_free(kvlist);
+ return -1;
+ }
+ ENETC_PMD_NOTICE("VSI delay set to %u us", hw->vsi_delay);
+ }
+
rte_kvargs_free(kvlist);
} else {
eth_dev->dev_ops = &enetc4_vf_ops;
@@ -1443,5 +1475,7 @@ RTE_PMD_REGISTER_PCI(net_enetc4_vf, rte_enetc4_vf_pmd);
RTE_PMD_REGISTER_PCI_TABLE(net_enetc4_vf, pci_vf_id_enetc4_map);
RTE_PMD_REGISTER_KMOD_DEP(net_enetc4_vf, "* igb_uio | uio_pci_generic");
RTE_PMD_REGISTER_PARAM_STRING(net_enetc4_vf,
- ENETC4_VSI_DISABLE "=<any>");
+ ENETC4_VSI_DISABLE "=<any> "
+ ENETC4_VSI_TIMEOUT "=<uint> "
+ ENETC4_VSI_DELAY "=<uint>");
RTE_LOG_REGISTER_DEFAULT(enetc4_vf_logtype_pmd, NOTICE);
--
2.25.1
^ permalink raw reply related
* RE: [PATCH v3 0/9] ENETC driver related changes series
From: Gagandeep Singh @ 2026-06-29 5:19 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev@dpdk.org, Hemant Agrawal
In-Reply-To: <20260628154019.4c7697ca@phoenix.local>
Hi,
> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Monday, June 29, 2026 4:10 AM
> To: Gagandeep Singh <G.Singh@nxp.com>
> Cc: dev@dpdk.org; Hemant Agrawal <hemant.agrawal@nxp.com>
> Subject: Re: [PATCH v3 0/9] ENETC driver related changes series
>
> On Tue, 23 Jun 2026 11:29:55 +0530
> Gagandeep Singh <g.singh@nxp.com> wrote:
>
> > V3 changes:
> > - Added documentation for all devargs in enetc4.rst.
> > - Fixed kvlist memory leak issue.
> >
> > V2 changes:
> > - Fixed an un-used variable compilation issue reported on fedora:43-gcc-
> minsize
> > - Fixed various AI reported issues:
> > - Release notes updated for all new devargs
> > - enect4.ini features doc updated for scattered RX.
> > - removed Not required RTE_PTYPE_UNKNOWN.
> > - Fixed mid-frame mbuf leak in SG case.
> > - Enabled SG for enetc4 PF also.
> > - move to calloc from rte_zmalloc in parse_txq_prior().
> > - added vaidation checks on strdup, strtoul.
> > - added NC devargs to use cacheable ops conditionally.
> > - removed dead code like bd_base_p etc.
> > - Fixed rte_cpu_to_le_16() conversion on flags and combined
> > all flags related patches in one patch.
> > - Fixed memory leak issue due to TXQ priority patch.
> > - There were some false positives, I have ignored them:
> > Race condition on flags field:
> > clean_tx_ring only touches HW-completed BDs
> (next_to_clean→hwci),
> > never newly-submitted BDs; doorbell hasn't fired yet.
> > Missing dcbf in clean_tx_ring:
> > DPDK is single-threaded per queue; TX path always overwrites
> > flags completely before dcbf.
> > TX dcbf granularity with wrap:
> > Safe (AI admits it).
> > RX refill flush at wrap:
> > In-loop dcbf at i & mask == 0 already flushes aligned groups;
> > trailing flush only needed for partial groups.
> > RX reading before invalidate:
> > dccivac precedes the read for every group in the loop
> >
> > Gagandeep Singh (7):
> > net/enetc: fix TX BD structure
> > net/enetc: fix queue initialization
> > net/enetc: support ESP packet type in packet parsing
> > net/enetc: update random MAC generation code
> > net/enetc: add option to disable VSI messaging
> > net/enetc: add devargs to control VSI-PSI timeout and delay
> > net/enetc4: add cacheable BD ring support with SW cache maintenance
> >
> > Vanshika Shukla (2):
> > net/enetc: support scatter-gather
> > net/enetc: set user configurable priority to TX rings
> >
> > doc/guides/nics/enetc4.rst | 62 +++-
> > doc/guides/nics/features/enetc4.ini | 1 +
> > doc/guides/rel_notes/release_26_07.rst | 10 +
> > drivers/net/enetc/base/enetc_hw.h | 13 +-
> > drivers/net/enetc/enetc.h | 31 +-
> > drivers/net/enetc/enetc4_ethdev.c | 172 ++++++++--
> > drivers/net/enetc/enetc4_vf.c | 206 ++++++++++--
> > drivers/net/enetc/enetc_ethdev.c | 25 +-
> > drivers/net/enetc/enetc_rxtx.c | 430 ++++++++++++++++++++++---
> > 9 files changed, 831 insertions(+), 119 deletions(-)
> >
>
> LOL AI apologized for missing this in review.
>
> You're right, and I missed it — twice. I explicitly considered that txbd guard in my
> v2 review and talked myself out of flagging it as "over-defensive," but the runtime
> argument (the inner loop always executes because tx_pkts[start] is non-NULL) is
> invisible to the compiler. Under -Werror=maybe-uninitialized at -Os that's a hard
> build break, and per-commit buildability is non-negotiable. That's a real review
> failure on my part. Let me reproduce it, pin down which patch introduces it, and
> confirm the fix.
>
> drivers/net/enetc/enetc_rxtx.c
>
> enetc_xmit_pkts_nc() and enetc_xmit_pkts_cacheable() both fail to
> build with -Werror=maybe-uninitialized (-Os, gcc):
>
> error: 'txbd' may be used uninitialized
>
> txbd is declared without an initializer and assigned only inside the
> inner per-segment loop; the compiler cannot prove that loop runs
> before txbd is read after it. Initialize at declaration:
>
> - struct enetc_tx_bd *txbd;
> + struct enetc_tx_bd *txbd = NULL;
>
> The _nc fix belongs in patch 5 (so that commit builds independently);
> the _cacheable fix belongs in patch 9.
>
Thanks for reporting, I have submitted the V4 with fix.
^ permalink raw reply
* [PATCH v4 0/9] ENETC driver related changes series
From: Gagandeep Singh @ 2026-06-29 5:05 UTC (permalink / raw)
To: dev; +Cc: hemant.agrawal
In-Reply-To: <20260623060004.2187716-1-g.singh@nxp.com>
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=y, Size: 2551 bytes --]
V4 changes:
- Fixed a compilation issue: "txbd may be used uninitialized"
V3 changes:
- Added documentation for all devargs in enetc4.rst.
- Fixed kvlist memory leak issue.
V2 changes:
- Fixed an un-used variable compilation issue reported on fedora:43-gcc-minsize
- Fixed various AI reported issues:
- Release notes updated for all new devargs
- enect4.ini features doc updated for scattered RX.
- removed Not required RTE_PTYPE_UNKNOWN.
- Fixed mid-frame mbuf leak in SG case.
- Enabled SG for enetc4 PF also.
- move to calloc from rte_zmalloc in parse_txq_prior().
- added vaidation checks on strdup, strtoul.
- added NC devargs to use cacheable ops conditionally.
- removed dead code like bd_base_p etc.
- Fixed rte_cpu_to_le_16() conversion on flags and combined
all flags related patches in one patch.
- Fixed memory leak issue due to TXQ priority patch.
- There were some false positives, I have ignored them:
Race condition on flags field:
clean_tx_ring only touches HW-completed BDs (next_to_clean→hwci),
never newly-submitted BDs; doorbell hasn't fired yet.
Missing dcbf in clean_tx_ring:
DPDK is single-threaded per queue; TX path always overwrites
flags completely before dcbf.
TX dcbf granularity with wrap:
Safe (AI admits it).
RX refill flush at wrap:
In-loop dcbf at i & mask == 0 already flushes aligned groups;
trailing flush only needed for partial groups.
RX reading before invalidate:
dccivac precedes the read for every group in the loop
Gagandeep Singh (7):
net/enetc: fix TX BD structure
net/enetc: fix queue initialization
net/enetc: support ESP packet type in packet parsing
net/enetc: update random MAC generation code
net/enetc: add option to disable VSI messaging
net/enetc: add devargs to control VSI-PSI timeout and delay
net/enetc4: add cacheable BD ring support with SW cache maintenance
Vanshika Shukla (2):
net/enetc: support scatter-gather
net/enetc: set user configurable priority to TX rings
doc/guides/nics/enetc4.rst | 62 +++-
doc/guides/nics/features/enetc4.ini | 1 +
doc/guides/rel_notes/release_26_07.rst | 10 +
drivers/net/enetc/base/enetc_hw.h | 13 +-
drivers/net/enetc/enetc.h | 31 +-
drivers/net/enetc/enetc4_ethdev.c | 172 ++++++++--
drivers/net/enetc/enetc4_vf.c | 206 ++++++++++--
drivers/net/enetc/enetc_ethdev.c | 25 +-
drivers/net/enetc/enetc_rxtx.c | 430 ++++++++++++++++++++++---
9 files changed, 831 insertions(+), 119 deletions(-)
--
2.25.1
^ permalink raw reply
* [PATCH v4 1/9] net/enetc: fix TX BD structure
From: Gagandeep Singh @ 2026-06-29 5:05 UTC (permalink / raw)
To: dev; +Cc: hemant.agrawal, stable, Gagandeep Singh
In-Reply-To: <20260629050527.981200-1-g.singh@nxp.com>
The flags field in struct enetc_tx_bd was declared as uint16_t but
ENETC4 TX BDs only use an 8-bit flags byte. Fix the type to uint8_t
to match the hardware descriptor layout.
Fixes: 696fa399d797 ("net/enetc: add PMD with basic operations")
Cc: stable@dpdk.org
Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
drivers/net/enetc/base/enetc_hw.h | 7 +++----
drivers/net/enetc/enetc_rxtx.c | 17 +++++++++--------
2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/net/enetc/base/enetc_hw.h b/drivers/net/enetc/base/enetc_hw.h
index 173d677..19efadd 100644
--- a/drivers/net/enetc/base/enetc_hw.h
+++ b/drivers/net/enetc/base/enetc_hw.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright 2018-2024 NXP
+ * Copyright 2018-2026 NXP
*/
#ifndef _ENETC_HW_H_
@@ -198,8 +198,7 @@ enum enetc_bdr_type {TX, RX};
#define ENETC_TX_ADDR(txq, addr) ((void *)((txq)->enetc_txbdr + (addr)))
-#define ENETC_TXBD_FLAGS_IE BIT(13)
-#define ENETC_TXBD_FLAGS_F BIT(15)
+#define ENETC_TXBD_FLAGS_F BIT(7)
/* ENETC Parsed values (Little Endian) */
#define ENETC_PARSE_ERROR 0x8000
@@ -262,7 +261,7 @@ struct enetc_tx_bd {
uint8_t l3t:1;
uint8_t resv:5;
uint8_t l4t:3;
- uint16_t flags;
+ uint8_t flags;
};/* default layout */
uint32_t txstart;
uint32_t lstatus;
diff --git a/drivers/net/enetc/enetc_rxtx.c b/drivers/net/enetc/enetc_rxtx.c
index a2b8153..d3b98b3 100644
--- a/drivers/net/enetc/enetc_rxtx.c
+++ b/drivers/net/enetc/enetc_rxtx.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright 2018-2024 NXP
+ * Copyright 2018-2026 NXP
*/
#include <stdbool.h>
@@ -101,7 +101,7 @@ enetc_xmit_pkts(void *tx_queue,
tx_swbd = &tx_ring->q_swbd[i];
txbd->frm_len = tx_pkts[start]->pkt_len;
txbd->buf_len = txbd->frm_len;
- txbd->flags = rte_cpu_to_le_16(ENETC_TXBD_FLAGS_F);
+ txbd->flags = ENETC_TXBD_FLAGS_F;
txbd->addr = (uint64_t)(uintptr_t)
rte_cpu_to_le_64((size_t)tx_swbd->buffer_addr->buf_iova +
tx_swbd->buffer_addr->data_off);
@@ -133,13 +133,13 @@ enetc4_tx_offload_checksum(struct rte_mbuf *mbuf, struct enetc_tx_bd *txbd)
txbd->ipcs = ENETC4_TXBD_IPCS;
txbd->l3_start = mbuf->l2_len;
txbd->l3_hdr_size = mbuf->l3_len / 4;
- txbd->flags |= rte_cpu_to_le_16(ENETC4_TXBD_FLAGS_L_TX_CKSUM);
+ txbd->flags |= ENETC4_TXBD_FLAGS_L_TX_CKSUM;
if ((mbuf->ol_flags & RTE_MBUF_F_TX_UDP_CKSUM) == RTE_MBUF_F_TX_UDP_CKSUM) {
- txbd->l4t = rte_cpu_to_le_16(ENETC4_TXBD_L4T_UDP);
- txbd->flags |= rte_cpu_to_le_16(ENETC4_TXBD_FLAGS_L4CS);
+ txbd->l4t = ENETC4_TXBD_L4T_UDP;
+ txbd->flags |= ENETC4_TXBD_FLAGS_L4CS;
} else if ((mbuf->ol_flags & RTE_MBUF_F_TX_TCP_CKSUM) == RTE_MBUF_F_TX_TCP_CKSUM) {
- txbd->l4t = rte_cpu_to_le_16(ENETC4_TXBD_L4T_TCP);
- txbd->flags |= rte_cpu_to_le_16(ENETC4_TXBD_FLAGS_L4CS);
+ txbd->l4t = ENETC4_TXBD_L4T_TCP;
+ txbd->flags |= ENETC4_TXBD_FLAGS_L4CS;
}
}
}
@@ -172,7 +172,7 @@ enetc_xmit_pkts_nc(void *tx_queue,
dcbf(data + j);
txbd = ENETC_TXBD(*tx_ring, i);
- txbd->flags = rte_cpu_to_le_16(ENETC4_TXBD_FLAGS_F);
+ txbd->flags = 0;
if (tx_ring->q_swbd[i].buffer_addr->ol_flags & ENETC4_TX_CKSUM_OFFLOAD_MASK)
enetc4_tx_offload_checksum(tx_ring->q_swbd[i].buffer_addr, txbd);
@@ -182,6 +182,7 @@ enetc_xmit_pkts_nc(void *tx_queue,
txbd->addr = (uint64_t)(uintptr_t)
rte_cpu_to_le_64((size_t)tx_swbd->buffer_addr->buf_iova +
tx_swbd->buffer_addr->data_off);
+ txbd->flags |= ENETC4_TXBD_FLAGS_F;
i++;
start++;
if (unlikely(i == tx_ring->bd_count))
--
2.25.1
^ permalink raw reply related
* [PATCH v4 2/9] net/enetc: fix queue initialization
From: Gagandeep Singh @ 2026-06-29 5:05 UTC (permalink / raw)
To: dev; +Cc: hemant.agrawal, stable, Gagandeep Singh
In-Reply-To: <20260629050527.981200-1-g.singh@nxp.com>
Hardware can misbehave if the user tries to reset the consumer and
producer indexes without resetting the ring.
This patch adds the ring reset step before resetting the indexes.
Fixes: 6c9c5aadc0e0 ("net/enetc: support ENETC4 queue API")
Cc: stable@dpdk.org
Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
drivers/net/enetc/enetc4_ethdev.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/net/enetc/enetc4_ethdev.c b/drivers/net/enetc/enetc4_ethdev.c
index 78eba70..154fc09 100644
--- a/drivers/net/enetc/enetc4_ethdev.c
+++ b/drivers/net/enetc/enetc4_ethdev.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright 2024 NXP
+ * Copyright 2024-2026 NXP
*/
#include <stdbool.h>
@@ -279,6 +279,7 @@ enetc4_tx_queue_setup(struct rte_eth_dev *dev,
const struct rte_eth_txconf *tx_conf)
{
int err;
+ uint32_t tx_data;
struct enetc_bdr *tx_ring;
struct rte_eth_dev_data *data = dev->data;
struct enetc_eth_adapter *priv =
@@ -301,6 +302,10 @@ enetc4_tx_queue_setup(struct rte_eth_dev *dev,
goto fail;
tx_ring->ndev = dev;
+ /* reset queue */
+ tx_data = enetc4_txbdr_rd(&priv->hw.hw, tx_ring->index, ENETC_TBMR);
+ tx_data &= ~ENETC_TBMR_EN;
+ enetc4_txbdr_wr(&priv->hw.hw, tx_ring->index, ENETC_TBMR, tx_data);
enetc4_setup_txbdr(&priv->hw.hw, tx_ring);
data->tx_queues[queue_idx] = tx_ring;
tx_ring->tx_deferred_start = tx_conf->tx_deferred_start;
@@ -427,6 +432,7 @@ enetc4_rx_queue_setup(struct rte_eth_dev *dev,
struct rte_mempool *mb_pool)
{
int err = 0;
+ uint32_t rx_enable;
struct enetc_bdr *rx_ring;
struct rte_eth_dev_data *data = dev->data;
struct enetc_eth_adapter *adapter =
@@ -450,6 +456,10 @@ enetc4_rx_queue_setup(struct rte_eth_dev *dev,
goto fail;
rx_ring->ndev = dev;
+ /* reset queue */
+ rx_enable = enetc4_rxbdr_rd(&adapter->hw.hw, rx_ring->index, ENETC_RBMR);
+ rx_enable &= ~ENETC_RBMR_EN;
+ enetc4_rxbdr_wr(&adapter->hw.hw, rx_ring->index, ENETC_RBMR, rx_enable);
enetc4_setup_rxbdr(&adapter->hw.hw, rx_ring, mb_pool);
data->rx_queues[rx_queue_id] = rx_ring;
rx_ring->rx_deferred_start = rx_conf->rx_deferred_start;
--
2.25.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