* [PATCH v7] graph: add optional profiling stats
From: Morten Brørup @ 2026-07-03 13:53 UTC (permalink / raw)
To: dev, Jerin Jacob, Kiran Kumar K, Nithin Dabilpuram, Zhirun Yan,
Saeed Bishara
Cc: Morten Brørup
In-Reply-To: <20260619202047.2809165-1-mb@smartsharesystems.com>
graph: add optional profiling stats
Added graph node profiling stats, build time configurable by enabling
RTE_GRAPH_PROFILE in rte_config.h.
Signed-off-by: Morten Brørup <mb@smartsharesystems.com>
---
v7:
* Use RTE_DIM() in histogram for loop.
* Added static_assert for histogram index values.
* Minor details to please checkpatch.
Although I disagree with requiring a space when indexing into
a constant array "(const type []){values} [idx];",
I have changed the code to comply.
v6:
* Consolidate the four histogram entries into one array. (Saeed Bishara)
* Sample at 32 objs instead of a half burst. (Saeed Bishara)
* Moved stats to different location in rte_node structure. (Jerin)
* Minor details to please checkpatch.
v5:
* Added stats for a half burst and a full burst.
v4:
* Added documentation. (AI)
* Added more comments. (AI)
* Improved dump. (AI)
* Debug shows both cycles/call and cycles/obj.
v3:
* Debug shows cycles/obj instead of cycles/call.
* Fixed missing --in-reply-to.
v2:
* Fixed indentation.
---
config/rte_config.h | 1 +
doc/guides/prog_guide/graph_lib.rst | 1 +
lib/graph/graph_debug.c | 48 +++++++++++++++++++++++++++++
lib/graph/node.c | 2 ++
lib/graph/rte_graph_worker_common.h | 29 +++++++++++++++--
5 files changed, 78 insertions(+), 3 deletions(-)
diff --git a/config/rte_config.h b/config/rte_config.h
index 0447cdf2ad..1942c1b1ec 100644
--- a/config/rte_config.h
+++ b/config/rte_config.h
@@ -106,6 +106,7 @@
/* rte_graph defines */
#define RTE_GRAPH_BURST_SIZE 256
#define RTE_LIBRTE_GRAPH_STATS 1
+/* RTE_GRAPH_PROFILE is not set */
/****** driver defines ********/
diff --git a/doc/guides/prog_guide/graph_lib.rst b/doc/guides/prog_guide/graph_lib.rst
index 8dd49c19d2..bc36042296 100644
--- a/doc/guides/prog_guide/graph_lib.rst
+++ b/doc/guides/prog_guide/graph_lib.rst
@@ -49,6 +49,7 @@ Performance tuning parameters
RTE_GRAPH_BURST_SIZE config option.
The testing shows, on x86 and arm64 servers, The sweet spot is 256 burst
size. While on arm64 embedded SoCs, it is either 64 or 128.
+- Enable the ``RTE_GRAPH_PROFILE`` config option for more profiling details.
- Disable node statistics (using ``RTE_LIBRTE_GRAPH_STATS`` config option)
if not needed.
diff --git a/lib/graph/graph_debug.c b/lib/graph/graph_debug.c
index e3b8cccdc1..427c6a6e77 100644
--- a/lib/graph/graph_debug.c
+++ b/lib/graph/graph_debug.c
@@ -93,6 +93,54 @@ rte_graph_obj_dump(FILE *f, struct rte_graph *g, bool all)
n->dispatch.total_sched_fail);
}
fprintf(f, " total_calls=%" PRId64 "\n", n->total_calls);
+ if (rte_graph_has_stats_feature())
+ fprintf(f, " total_cycles=%" PRIu64 ", avg cycles/call=%.1f\n",
+ n->total_cycles,
+ n->total_calls == 0 ? 0.0 :
+ (double)n->total_cycles / (double)n->total_calls);
+#ifdef RTE_GRAPH_PROFILE
+ int64_t calls_other = n->total_calls;
+ int64_t cycles_other = n->total_cycles;
+ int64_t objs_other = n->total_objs;
+ for (int idx = 0; idx < RTE_DIM(n->usage_stats) + 1; idx++) {
+ uint64_t calls;
+ uint64_t cycles;
+ double objs_per_call;
+ if (idx < RTE_DIM(n->usage_stats)) {
+ static_assert(RTE_DIM(n->usage_stats) == 4);
+ uint16_t idx_objs = (const uint16_t []){0, 1, 32,
+ RTE_GRAPH_BURST_SIZE} [idx];
+ fprintf(f, " objs[%u]\n", idx_objs);
+ calls = n->usage_stats[idx].calls;
+ cycles = n->usage_stats[idx].cycles;
+ objs_per_call = (double)idx_objs;
+ calls_other -= calls;
+ cycles_other -= cycles;
+ objs_other -= idx_objs * calls;
+ } else {
+ fprintf(f, " objs[other]\n");
+ if (calls_other > 0 && cycles_other > 0 && objs_other > 0) {
+ calls = calls_other;
+ cycles = cycles_other;
+ objs_per_call = (double)objs_other / (double)calls_other;
+ fprintf(f, " avg objs/call=%.1f\n", objs_per_call);
+ } else {
+ calls = 0;
+ cycles = 0;
+ objs_per_call = 0.0;
+ }
+ }
+ fprintf(f, " calls=%" PRIu64, calls);
+ if (calls != 0)
+ fprintf(f, ", cycles=%" PRIu64 ", avg cycles/call=%.1f",
+ cycles,
+ (double)cycles / (double)calls);
+ if (calls != 0 && objs_per_call != 0.0)
+ fprintf(f, ", avg cycles/obj=%.1f",
+ (double)cycles / (double)calls / objs_per_call);
+ fprintf(f, "\n");
+ }
+#endif
for (i = 0; i < n->nb_edges; i++)
fprintf(f, " edge[%d] <%s>\n", i,
n->nodes[i]->name);
diff --git a/lib/graph/node.c b/lib/graph/node.c
index 1fce3e6632..19b38881ae 100644
--- a/lib/graph/node.c
+++ b/lib/graph/node.c
@@ -110,10 +110,12 @@ __rte_node_register(const struct rte_node_register *reg)
rte_edge_t i;
size_t sz;
+#ifndef RTE_GRAPH_PROFILE
/* Limit Node specific metadata to one cacheline on 64B CL machine */
RTE_BUILD_BUG_ON((offsetof(struct rte_node, nodes) -
offsetof(struct rte_node, ctx)) !=
RTE_CACHE_LINE_MIN_SIZE);
+#endif
graph_spinlock_lock();
diff --git a/lib/graph/rte_graph_worker_common.h b/lib/graph/rte_graph_worker_common.h
index 4ab53a533e..bac0fc534e 100644
--- a/lib/graph/rte_graph_worker_common.h
+++ b/lib/graph/rte_graph_worker_common.h
@@ -121,6 +121,14 @@ struct __rte_cache_aligned rte_node {
rte_graph_off_t xstat_off; /**< Offset to xstat counters. */
/** Fast path area cache line 2. */
+#ifdef RTE_GRAPH_PROFILE
+ /** Usage when this node processed 0, 1, 32 or a full burst of objects. */
+ struct __rte_cache_aligned {
+ uint64_t calls; /**< Calls done. */
+ uint64_t cycles; /**< Cycles spent. */
+ } usage_stats[4];
+ /** Fast path area cache line 3. */
+#endif
__extension__ struct __rte_cache_aligned {
#define RTE_NODE_CTX_SZ 16
union {
@@ -148,8 +156,10 @@ struct __rte_cache_aligned rte_node {
};
};
+#ifndef RTE_GRAPH_PROFILE
static_assert(offsetof(struct rte_node, nodes) - offsetof(struct rte_node, ctx)
== RTE_CACHE_LINE_MIN_SIZE, "rte_node fast path area must fit in 64 bytes");
+#endif
/**
* @internal
@@ -197,7 +207,7 @@ void __rte_node_stream_alloc_size(struct rte_graph *graph,
static __rte_always_inline void
__rte_node_process(struct rte_graph *graph, struct rte_node *node)
{
- uint64_t start;
+ uint64_t cycles;
uint16_t rc;
void **objs;
@@ -206,11 +216,24 @@ __rte_node_process(struct rte_graph *graph, struct rte_node *node)
rte_prefetch0(objs);
if (rte_graph_has_stats_feature()) {
- start = rte_rdtsc();
+ cycles = -rte_rdtsc();
rc = node->process(graph, node, objs, node->idx);
- node->total_cycles += rte_rdtsc() - start;
+ cycles += rte_rdtsc();
+ node->total_cycles += cycles;
node->total_calls++;
node->total_objs += rc;
+#ifdef RTE_GRAPH_PROFILE
+ if (rc <= 1) {
+ node->usage_stats[rc].calls++;
+ node->usage_stats[rc].cycles += cycles;
+ } else if (rc == 32) {
+ node->usage_stats[2].calls++;
+ node->usage_stats[2].cycles += cycles;
+ } else if (rc == RTE_GRAPH_BURST_SIZE) {
+ node->usage_stats[3].calls++;
+ node->usage_stats[3].cycles += cycles;
+ }
+#endif
} else {
node->process(graph, node, objs, node->idx);
}
--
2.43.0
^ permalink raw reply related
* [PATCH v2 6/6] net/iavf: fix leak of IPsec crypto capabilities array
From: Bruce Richardson @ 2026-07-03 13:19 UTC (permalink / raw)
To: dev
Cc: Bruce Richardson, stable, Vladimir Medvedkin, Abhijit Sinha,
Jingjing Wu, Declan Doherty, Radu Nicolau
In-Reply-To: <20260703131921.4102325-1-bruce.richardson@intel.com>
The security context setup allocates a crypto capabilities array and
stores it in iavf_sctx->crypto_capabilities. However, the security
context destroy path frees iavf_sctx and sctx directly, without first
freeing that array.
Fix this by freeing iavf_sctx->crypto_capabilities in
iavf_security_ctx_destroy() before freeing the security context itself.
Fixes: 6bc987ecb860 ("net/iavf: support IPsec inline crypto")
Cc: stable@dpdk.org
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
drivers/net/intel/iavf/iavf_ipsec_crypto.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/intel/iavf/iavf_ipsec_crypto.c b/drivers/net/intel/iavf/iavf_ipsec_crypto.c
index b2e08da0aa..9c8f694de5 100644
--- a/drivers/net/intel/iavf/iavf_ipsec_crypto.c
+++ b/drivers/net/intel/iavf/iavf_ipsec_crypto.c
@@ -1572,6 +1572,8 @@ iavf_security_ctx_destroy(struct iavf_adapter *adapter)
return -ENODEV;
/* free and reset security data structures */
+ rte_free(iavf_sctx->crypto_capabilities);
+ iavf_sctx->crypto_capabilities = NULL;
rte_free(iavf_sctx);
rte_free(sctx);
--
2.53.0
^ permalink raw reply related
* [PATCH v2 5/6] net/iavf: fix leak of flex metadata extraction field
From: Bruce Richardson @ 2026-07-03 13:19 UTC (permalink / raw)
To: dev; +Cc: Bruce Richardson, stable, Vladimir Medvedkin, Haiyue Wang,
Jeff Guo
In-Reply-To: <20260703131921.4102325-1-bruce.richardson@intel.com>
Function iavf_init_proto_xtr() allocates vf->proto_xtr as part of the
device init sequence, but no shutdown function frees this memory again.
Add an appropriate free call to fix this memory leak.
Fixes: 12b435bf8f2f ("net/iavf: support flex desc metadata extraction")
Cc: stable@dpdk.org
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
drivers/net/intel/iavf/iavf_ethdev.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/intel/iavf/iavf_ethdev.c b/drivers/net/intel/iavf/iavf_ethdev.c
index 1cd8c88384..7f5b103326 100644
--- a/drivers/net/intel/iavf/iavf_ethdev.c
+++ b/drivers/net/intel/iavf/iavf_ethdev.c
@@ -2757,6 +2757,8 @@ iavf_uninit_vf(struct rte_eth_dev *dev)
vf->qos_cap = NULL;
free(vf->qtc_map);
vf->qtc_map = NULL;
+ rte_free(vf->proto_xtr);
+ vf->proto_xtr = NULL;
rte_free(vf->rss_lut);
vf->rss_lut = NULL;
--
2.53.0
^ permalink raw reply related
* [PATCH v2 4/6] net/ice: fix buffer leak in config of Tx queue TM node
From: Bruce Richardson @ 2026-07-03 13:19 UTC (permalink / raw)
To: dev; +Cc: Bruce Richardson, stable, Anatoly Burakov, Vladimir Medvedkin
In-Reply-To: <20260703131921.4102325-1-bruce.richardson@intel.com>
Only the error leg handled free of the adminq message buffer when
configuring a Tx queue traffic management node. Fix this by freeing the
buffer unconditionally after the adminq call. Also, remove the use of
dpdk-specific memory allocation, replacing it with generic alloc and
free routines.
Fixes: 715d449a965b ("net/ice: enhance Tx scheduler hierarchy support")
Cc: stable@dpdk.org
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
drivers/net/intel/ice/ice_tm.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/intel/ice/ice_tm.c b/drivers/net/intel/ice/ice_tm.c
index 94ded15fa7..2e6ef9c264 100644
--- a/drivers/net/intel/ice/ice_tm.c
+++ b/drivers/net/intel/ice/ice_tm.c
@@ -1,6 +1,8 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2022 Intel Corporation
*/
+#include <stdlib.h>
+
#include <rte_ethdev.h>
#include <rte_tm_driver.h>
@@ -714,7 +716,7 @@ ice_tm_setup_txq_node(struct ice_pf *pf, struct ice_hw *hw, uint16_t qid, uint32
uint8_t txqs_moved = 0;
uint16_t buf_size = ice_struct_size(buf, txqs, 1);
- buf = ice_malloc(hw, buf_size);
+ buf = calloc(1, buf_size);
if (buf == NULL)
return -ENOMEM;
@@ -727,9 +729,9 @@ ice_tm_setup_txq_node(struct ice_pf *pf, struct ice_hw *hw, uint16_t qid, uint32
int ret = ice_aq_move_recfg_lan_txq(hw, 1, true, false, false, false, 50,
NULL, buf, buf_size, &txqs_moved, NULL);
+ free(buf);
if (ret || txqs_moved == 0) {
PMD_DRV_LOG(ERR, "move lan queue %u failed", qid);
- ice_free(hw, buf);
return ICE_ERR_PARAM;
}
--
2.53.0
^ permalink raw reply related
* [PATCH v2 3/6] net/iavf: fix memory leak on error when adding flow parser
From: Bruce Richardson @ 2026-07-03 13:19 UTC (permalink / raw)
To: dev; +Cc: Bruce Richardson, stable, Vladimir Medvedkin, Qiming Yang,
Qi Zhang
In-Reply-To: <20260703131921.4102325-1-bruce.richardson@intel.com>
In iavf_register_flow_parser, the final "else" branch is an error leg
which returns immediately, without adding the newly allocated
parser_node to a TAILQ. Add a free call for that parser_node in the
error case to avoid leaking memory.
Fixes: ff2d0c345c3b ("net/iavf: support generic flow API")
Cc: stable@dpdk.org
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
drivers/net/intel/iavf/iavf_generic_flow.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/intel/iavf/iavf_generic_flow.c b/drivers/net/intel/iavf/iavf_generic_flow.c
index 84bb161bd1..92ca20031c 100644
--- a/drivers/net/intel/iavf/iavf_generic_flow.c
+++ b/drivers/net/intel/iavf/iavf_generic_flow.c
@@ -1911,6 +1911,7 @@ iavf_register_parser(struct iavf_flow_parser *parser,
list = &vf->dist_parser_list;
TAILQ_INSERT_HEAD(list, parser_node, node);
} else {
+ rte_free(parser_node);
return -EINVAL;
}
--
2.53.0
^ permalink raw reply related
* [PATCH v2 2/6] net/iavf: fix leak of queue to traffic class mapping data
From: Bruce Richardson @ 2026-07-03 13:19 UTC (permalink / raw)
To: dev; +Cc: Bruce Richardson, stable, Vladimir Medvedkin, Qi Zhang, Ting Xu
In-Reply-To: <20260703131921.4102325-1-bruce.richardson@intel.com>
On iavf TM hierarchy commit, the queue to traffic class mapping is
generated and stored in a pointer from the VF structure. However, that
data is never later freed. The data is also unnecessarily allocated from
hugepage memory.
Fix these issues by replacing rte_zmalloc with calloc, and then
appropriately freeing the memory at a) uninit of the device, b) at
failure of apply of the new settings and c) replacement of old data by
new.
Fixes: 3fd32df381f8 ("net/iavf: check Tx packet with correct UP and queue")
Cc: stable@dpdk.org
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
drivers/net/intel/iavf/iavf_ethdev.c | 2 ++
drivers/net/intel/iavf/iavf_tm.c | 11 ++++++++---
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/net/intel/iavf/iavf_ethdev.c b/drivers/net/intel/iavf/iavf_ethdev.c
index 80e740ef29..1cd8c88384 100644
--- a/drivers/net/intel/iavf/iavf_ethdev.c
+++ b/drivers/net/intel/iavf/iavf_ethdev.c
@@ -2755,6 +2755,8 @@ iavf_uninit_vf(struct rte_eth_dev *dev)
rte_free(vf->qos_cap);
vf->qos_cap = NULL;
+ free(vf->qtc_map);
+ vf->qtc_map = NULL;
rte_free(vf->rss_lut);
vf->rss_lut = NULL;
diff --git a/drivers/net/intel/iavf/iavf_tm.c b/drivers/net/intel/iavf/iavf_tm.c
index 5f888d654f..faa2d4b8a0 100644
--- a/drivers/net/intel/iavf/iavf_tm.c
+++ b/drivers/net/intel/iavf/iavf_tm.c
@@ -97,6 +97,9 @@ iavf_tm_conf_uninit(struct rte_eth_dev *dev)
shaper_profile, node);
rte_free(shaper_profile);
}
+
+ free(vf->qtc_map);
+ vf->qtc_map = NULL;
}
static inline struct iavf_tm_node *
@@ -801,7 +804,8 @@ static int iavf_hierarchy_commit(struct rte_eth_dev *dev,
struct virtchnl_queues_bw_cfg *q_bw = NULL;
struct iavf_tm_node_list *queue_list = &vf->tm_conf.queue_list;
struct iavf_tm_node *tm_node;
- struct iavf_qtc_map *qtc_map;
+ struct iavf_qtc_map *qtc_map = NULL;
+ struct iavf_qtc_map *old_qtc_map = vf->qtc_map; /* to free memory if new map assigned */
uint16_t size, size_q;
int index = 0, node_committed = 0;
int i, ret_val = IAVF_SUCCESS;
@@ -889,8 +893,7 @@ static int iavf_hierarchy_commit(struct rte_eth_dev *dev,
goto fail_clear;
/* store the queue TC mapping info */
- qtc_map = rte_zmalloc("qtc_map",
- sizeof(struct iavf_qtc_map) * q_tc_mapping->num_tc, 0);
+ qtc_map = calloc(q_tc_mapping->num_tc, sizeof(struct iavf_qtc_map));
if (!qtc_map) {
ret_val = IAVF_ERR_NO_MEMORY;
goto fail_clear;
@@ -910,6 +913,7 @@ static int iavf_hierarchy_commit(struct rte_eth_dev *dev,
goto fail_clear;
vf->qtc_map = qtc_map;
+ free(old_qtc_map);
if (adapter->stopped == 1)
vf->tm_conf.committed = true;
free(q_bw);
@@ -925,5 +929,6 @@ static int iavf_hierarchy_commit(struct rte_eth_dev *dev,
err:
free(q_bw);
free(q_tc_mapping);
+ free(qtc_map);
return ret_val;
}
--
2.53.0
^ permalink raw reply related
* [PATCH v2 1/6] net/iavf: fix local memory leaks in TM hierarchy commit
From: Bruce Richardson @ 2026-07-03 13:19 UTC (permalink / raw)
To: dev
Cc: Bruce Richardson, stable, Vladimir Medvedkin, Ting Xu,
Qiming Yang, Qi Zhang, Wenjun Wu
In-Reply-To: <20260703131921.4102325-1-bruce.richardson@intel.com>
The iavf_hierachy_commit function uses a number of temporary variables,
which, though small, are still leaked at function end. Clean this up by
freeing them before the function returns. Since these are not variables
that need to be in hugepage memory, also switch from using rte_zmalloc
to calloc.
Fixes: 44d0a720a538 ("net/iavf: query QoS capabilities and set queue TC mapping")
Fixes: 5779a8894d15 ("net/iavf: support queue rate limit configuration")
Cc: stable@dpdk.org
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
drivers/net/intel/iavf/iavf_tm.c | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/drivers/net/intel/iavf/iavf_tm.c b/drivers/net/intel/iavf/iavf_tm.c
index e3492ec491..5f888d654f 100644
--- a/drivers/net/intel/iavf/iavf_tm.c
+++ b/drivers/net/intel/iavf/iavf_tm.c
@@ -1,6 +1,8 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2010-2017 Intel Corporation
*/
+#include <stdlib.h>
+
#include <rte_tm_driver.h>
#include "iavf.h"
@@ -795,8 +797,8 @@ static int iavf_hierarchy_commit(struct rte_eth_dev *dev,
struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
struct iavf_adapter *adapter =
IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
- struct virtchnl_queue_tc_mapping *q_tc_mapping;
- struct virtchnl_queues_bw_cfg *q_bw;
+ struct virtchnl_queue_tc_mapping *q_tc_mapping = NULL;
+ struct virtchnl_queues_bw_cfg *q_bw = NULL;
struct iavf_tm_node_list *queue_list = &vf->tm_conf.queue_list;
struct iavf_tm_node *tm_node;
struct iavf_qtc_map *qtc_map;
@@ -832,7 +834,7 @@ static int iavf_hierarchy_commit(struct rte_eth_dev *dev,
size = sizeof(*q_tc_mapping) + sizeof(q_tc_mapping->tc[0]) *
(vf->qos_cap->num_elem - 1);
- q_tc_mapping = rte_zmalloc("q_tc", size, 0);
+ q_tc_mapping = calloc(1, size);
if (!q_tc_mapping) {
ret_val = IAVF_ERR_NO_MEMORY;
goto fail_clear;
@@ -840,7 +842,7 @@ static int iavf_hierarchy_commit(struct rte_eth_dev *dev,
size_q = sizeof(*q_bw) + sizeof(q_bw->cfg[0]) *
(vf->num_queue_pairs - 1);
- q_bw = rte_zmalloc("q_bw", size_q, 0);
+ q_bw = calloc(1, size_q);
if (!q_bw) {
ret_val = IAVF_ERR_NO_MEMORY;
goto fail_clear;
@@ -889,8 +891,10 @@ static int iavf_hierarchy_commit(struct rte_eth_dev *dev,
/* store the queue TC mapping info */
qtc_map = rte_zmalloc("qtc_map",
sizeof(struct iavf_qtc_map) * q_tc_mapping->num_tc, 0);
- if (!qtc_map)
- return IAVF_ERR_NO_MEMORY;
+ if (!qtc_map) {
+ ret_val = IAVF_ERR_NO_MEMORY;
+ goto fail_clear;
+ }
for (i = 0; i < q_tc_mapping->num_tc; i++) {
q_tc_mapping->tc[i].req.start_queue_id = index;
@@ -908,6 +912,8 @@ static int iavf_hierarchy_commit(struct rte_eth_dev *dev,
vf->qtc_map = qtc_map;
if (adapter->stopped == 1)
vf->tm_conf.committed = true;
+ free(q_bw);
+ free(q_tc_mapping);
return ret_val;
fail_clear:
@@ -917,5 +923,7 @@ static int iavf_hierarchy_commit(struct rte_eth_dev *dev,
iavf_tm_conf_init(dev);
}
err:
+ free(q_bw);
+ free(q_tc_mapping);
return ret_val;
}
--
2.53.0
^ permalink raw reply related
* [PATCH v2 0/6] Fix some small memory leaks
From: Bruce Richardson @ 2026-07-03 13:19 UTC (permalink / raw)
To: dev; +Cc: Bruce Richardson
In-Reply-To: <20260703083335.4058936-1-bruce.richardson@intel.com>
AI review of a patch to traffic management code identified a couple of
small memory leaks in that function. When fixing those, I then asked AI
to identify other similar leaks other Intel drivers, leading to this
patchset.
V2: expand from 2 patches to 6 to cover some more leaks
Bruce Richardson (6):
net/iavf: fix local memory leaks in TM hierarchy commit
net/iavf: fix leak of queue to traffic class mapping data
net/iavf: fix memory leak on error when adding flow parser
net/ice: fix buffer leak in config of Tx queue TM node
net/iavf: fix leak of flex metadata extraction field
net/iavf: fix leak of IPsec crypto capabilities array
drivers/net/intel/iavf/iavf_ethdev.c | 4 +++
drivers/net/intel/iavf/iavf_generic_flow.c | 1 +
drivers/net/intel/iavf/iavf_ipsec_crypto.c | 2 ++
drivers/net/intel/iavf/iavf_tm.c | 31 +++++++++++++++-------
drivers/net/intel/ice/ice_tm.c | 6 +++--
5 files changed, 33 insertions(+), 11 deletions(-)
--
2.53.0
^ permalink raw reply
* [PATCH v6] graph: add optional profiling stats
From: Morten Brørup @ 2026-07-03 13:18 UTC (permalink / raw)
To: dev, Jerin Jacob, Kiran Kumar K, Nithin Dabilpuram, Zhirun Yan,
Saeed Bishara
Cc: Morten Brørup
In-Reply-To: <20260619202047.2809165-1-mb@smartsharesystems.com>
Added graph node profiling stats, build time configurable by enabling
RTE_GRAPH_PROFILE in rte_config.h.
Signed-off-by: Morten Brørup <mb@smartsharesystems.com>
---
v6:
* Consolidate the four histogram entries into one array. (Saeed Bishara)
* Sample at 32 objs instead of RTE_GRAPH_BURST_SIZE/2. (Saeed Bishara)
* Moved stats to different location in rte_node structure. (Jerin)
* Minor details to please checkpatch.
v5:
* Added stats for a half burst and a full burst.
v4:
* Added documentation. (AI)
* Added more comments. (AI)
* Improved dump. (AI)
* Debug shows both cycles/call and cycles/obj.
v3:
* Debug shows cycles/obj instead of cycles/call.
* Fixed missing --in-reply-to.
v2:
* Fixed indentation.
---
config/rte_config.h | 1 +
doc/guides/prog_guide/graph_lib.rst | 1 +
lib/graph/graph_debug.c | 47 +++++++++++++++++++++++++++++
lib/graph/node.c | 2 ++
lib/graph/rte_graph_worker_common.h | 29 ++++++++++++++++--
5 files changed, 77 insertions(+), 3 deletions(-)
diff --git a/config/rte_config.h b/config/rte_config.h
index 0447cdf2ad..f5eff3d6dc 100644
--- a/config/rte_config.h
+++ b/config/rte_config.h
@@ -106,6 +106,7 @@
/* rte_graph defines */
#define RTE_GRAPH_BURST_SIZE 256
#define RTE_LIBRTE_GRAPH_STATS 1
+// RTE_GRAPH_PROFILE is not set
/****** driver defines ********/
diff --git a/doc/guides/prog_guide/graph_lib.rst b/doc/guides/prog_guide/graph_lib.rst
index 8dd49c19d2..bc36042296 100644
--- a/doc/guides/prog_guide/graph_lib.rst
+++ b/doc/guides/prog_guide/graph_lib.rst
@@ -49,6 +49,7 @@ Performance tuning parameters
RTE_GRAPH_BURST_SIZE config option.
The testing shows, on x86 and arm64 servers, The sweet spot is 256 burst
size. While on arm64 embedded SoCs, it is either 64 or 128.
+- Enable the ``RTE_GRAPH_PROFILE`` config option for more profiling details.
- Disable node statistics (using ``RTE_LIBRTE_GRAPH_STATS`` config option)
if not needed.
diff --git a/lib/graph/graph_debug.c b/lib/graph/graph_debug.c
index e3b8cccdc1..145649db65 100644
--- a/lib/graph/graph_debug.c
+++ b/lib/graph/graph_debug.c
@@ -93,6 +93,53 @@ rte_graph_obj_dump(FILE *f, struct rte_graph *g, bool all)
n->dispatch.total_sched_fail);
}
fprintf(f, " total_calls=%" PRId64 "\n", n->total_calls);
+ if (rte_graph_has_stats_feature()) {
+ fprintf(f, " total_cycles=%" PRIu64 ", avg cycles/call=%.1f\n",
+ n->total_cycles,
+ n->total_calls == 0 ? (double)0 :
+ (double)n->total_cycles / (double)n->total_calls);
+ }
+#ifdef RTE_GRAPH_PROFILE
+ int64_t calls_other = n->total_calls;
+ int64_t cycles_other = n->total_cycles;
+ int64_t objs_other = n->total_objs;
+ for (int idx = 0; idx <= 4; idx++) {
+ uint64_t calls;
+ uint64_t cycles;
+ double objs_per_call;
+ if (idx <= 3) {
+ uint16_t idx_objs = (const uint16_t []){0, 1, 32, RTE_GRAPH_BURST_SIZE}[idx];
+ fprintf(f, " objs[%u]\n", idx_objs);
+ calls = n->usage_stats[idx].calls;
+ cycles = n->usage_stats[idx].cycles;
+ objs_per_call = (double)idx_objs;
+ calls_other -= calls;
+ cycles_other -= cycles;
+ objs_other -= idx_objs * calls;
+ } else {
+ fprintf(f, " objs[other]\n");
+ if (calls_other > 0 && cycles_other > 0 && objs_other > 0) {
+ calls = calls_other;
+ cycles = cycles_other;
+ objs_per_call = (double)objs_other / (double)calls_other;
+ fprintf(f, " avg objs/call=%.1f\n", objs_per_call);
+ } else {
+ calls = 0;
+ cycles = 0;
+ objs_per_call = 0.0;
+ }
+ }
+ fprintf(f, " calls=%" PRIu64, calls);
+ if (calls != 0)
+ fprintf(f, ", cycles=%" PRIu64 ", avg cycles/call=%.1f",
+ cycles,
+ (double)cycles / (double)calls);
+ if (calls != 0 && objs_per_call != 0.0)
+ fprintf(f, ", avg cycles/obj=%.1f",
+ (double)cycles / (double)calls / objs_per_call);
+ fprintf(f, "\n");
+ }
+#endif
for (i = 0; i < n->nb_edges; i++)
fprintf(f, " edge[%d] <%s>\n", i,
n->nodes[i]->name);
diff --git a/lib/graph/node.c b/lib/graph/node.c
index 1fce3e6632..19b38881ae 100644
--- a/lib/graph/node.c
+++ b/lib/graph/node.c
@@ -110,10 +110,12 @@ __rte_node_register(const struct rte_node_register *reg)
rte_edge_t i;
size_t sz;
+#ifndef RTE_GRAPH_PROFILE
/* Limit Node specific metadata to one cacheline on 64B CL machine */
RTE_BUILD_BUG_ON((offsetof(struct rte_node, nodes) -
offsetof(struct rte_node, ctx)) !=
RTE_CACHE_LINE_MIN_SIZE);
+#endif
graph_spinlock_lock();
diff --git a/lib/graph/rte_graph_worker_common.h b/lib/graph/rte_graph_worker_common.h
index 4ab53a533e..bac0fc534e 100644
--- a/lib/graph/rte_graph_worker_common.h
+++ b/lib/graph/rte_graph_worker_common.h
@@ -121,6 +121,14 @@ struct __rte_cache_aligned rte_node {
rte_graph_off_t xstat_off; /**< Offset to xstat counters. */
/** Fast path area cache line 2. */
+#ifdef RTE_GRAPH_PROFILE
+ /** Usage when this node processed 0, 1, 32 or a full burst of objects. */
+ struct __rte_cache_aligned {
+ uint64_t calls; /**< Calls done. */
+ uint64_t cycles; /**< Cycles spent. */
+ } usage_stats[4];
+ /** Fast path area cache line 3. */
+#endif
__extension__ struct __rte_cache_aligned {
#define RTE_NODE_CTX_SZ 16
union {
@@ -148,8 +156,10 @@ struct __rte_cache_aligned rte_node {
};
};
+#ifndef RTE_GRAPH_PROFILE
static_assert(offsetof(struct rte_node, nodes) - offsetof(struct rte_node, ctx)
== RTE_CACHE_LINE_MIN_SIZE, "rte_node fast path area must fit in 64 bytes");
+#endif
/**
* @internal
@@ -197,7 +207,7 @@ void __rte_node_stream_alloc_size(struct rte_graph *graph,
static __rte_always_inline void
__rte_node_process(struct rte_graph *graph, struct rte_node *node)
{
- uint64_t start;
+ uint64_t cycles;
uint16_t rc;
void **objs;
@@ -206,11 +216,24 @@ __rte_node_process(struct rte_graph *graph, struct rte_node *node)
rte_prefetch0(objs);
if (rte_graph_has_stats_feature()) {
- start = rte_rdtsc();
+ cycles = -rte_rdtsc();
rc = node->process(graph, node, objs, node->idx);
- node->total_cycles += rte_rdtsc() - start;
+ cycles += rte_rdtsc();
+ node->total_cycles += cycles;
node->total_calls++;
node->total_objs += rc;
+#ifdef RTE_GRAPH_PROFILE
+ if (rc <= 1) {
+ node->usage_stats[rc].calls++;
+ node->usage_stats[rc].cycles += cycles;
+ } else if (rc == 32) {
+ node->usage_stats[2].calls++;
+ node->usage_stats[2].cycles += cycles;
+ } else if (rc == RTE_GRAPH_BURST_SIZE) {
+ node->usage_stats[3].calls++;
+ node->usage_stats[3].cycles += cycles;
+ }
+#endif
} else {
node->process(graph, node, objs, node->idx);
}
--
2.43.0
^ permalink raw reply related
* [PATCH v2 9/9] net/gve: restrict max ring size in GQ QPL to 2K
From: Joshua Washington @ 2026-07-03 13:13 UTC (permalink / raw)
To: Jeroen de Borst, Joshua Washington, Harshitha Ramamurthy,
Rushil Gupta
Cc: dev, stable, Jasper Tran O'Leary
In-Reply-To: <20260703131308.2507403-1-joshwash@google.com>
The GQ QPL queue format has a maximum supported ring size of 2k.
However, it is possible in some cases for the device to pass a larger
ring size as the max ring size. Restrict the ring size in the driver to
ensure that rings with invalid queue depths are not created.
Fixes: cde01d164f8f ("net/gve: support modifying ring size in GQ format")
Cc: stable@dpdk.org
Signed-off-by: Joshua Washington <joshwash@google.com>
Reviewed-by: Jasper Tran O'Leary <jtranoleary@google.com>
---
drivers/net/gve/base/gve_adminq.c | 12 +++++++++---
drivers/net/gve/gve_ethdev.h | 1 +
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/net/gve/base/gve_adminq.c b/drivers/net/gve/base/gve_adminq.c
index 2b25c7f390..315e2456fd 100644
--- a/drivers/net/gve/base/gve_adminq.c
+++ b/drivers/net/gve/base/gve_adminq.c
@@ -6,6 +6,7 @@
#include "../gve_ethdev.h"
#include "gve_adminq.h"
#include "gve_register.h"
+#include "rte_common.h"
#define GVE_MAX_ADMINQ_RELEASE_CHECK 500
#define GVE_ADMINQ_SLEEP_LEN 20
@@ -946,15 +947,20 @@ static void
gve_set_max_desc_cnt(struct gve_priv *priv,
const struct gve_device_option_modify_ring *modify_ring)
{
+ priv->max_rx_desc_cnt = be16_to_cpu(modify_ring->max_ring_size.rx);
+ priv->max_tx_desc_cnt = be16_to_cpu(modify_ring->max_ring_size.tx);
+
if (priv->queue_format == GVE_DQO_RDA_FORMAT) {
PMD_DRV_LOG(DEBUG, "Overriding max ring size from device for DQ "
"queue format to 4096.");
priv->max_rx_desc_cnt = GVE_MAX_QUEUE_SIZE_DQO;
priv->max_tx_desc_cnt = GVE_MAX_QUEUE_SIZE_DQO;
- return;
+ } else if (priv->queue_format == GVE_GQI_QPL_FORMAT) {
+ priv->max_rx_desc_cnt = RTE_MIN(priv->max_rx_desc_cnt,
+ GVE_MAX_RING_SIZE_GQ_QPL);
+ priv->max_tx_desc_cnt = RTE_MIN(priv->max_tx_desc_cnt,
+ GVE_MAX_RING_SIZE_GQ_QPL);
}
- priv->max_rx_desc_cnt = be16_to_cpu(modify_ring->max_ring_size.rx);
- priv->max_tx_desc_cnt = be16_to_cpu(modify_ring->max_ring_size.tx);
}
static void gve_enable_supported_features(struct gve_priv *priv,
diff --git a/drivers/net/gve/gve_ethdev.h b/drivers/net/gve/gve_ethdev.h
index 4a7e5ecdf3..c9a176ff17 100644
--- a/drivers/net/gve/gve_ethdev.h
+++ b/drivers/net/gve/gve_ethdev.h
@@ -21,6 +21,7 @@
#define DQO_TX_MULTIPLIER 4
#define GVE_DEFAULT_MAX_RING_SIZE 1024
+#define GVE_MAX_RING_SIZE_GQ_QPL 2048
#define GVE_DEFAULT_MIN_RX_RING_SIZE 512
#define GVE_DEFAULT_MIN_TX_RING_SIZE 256
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related
* [PATCH v2 8/9] net/gve: don't reset ring size bounds to default on reset
From: Joshua Washington @ 2026-07-03 13:13 UTC (permalink / raw)
To: Jeroen de Borst, Joshua Washington, Jasper Tran O'Leary; +Cc: dev, stable
In-Reply-To: <20260703131308.2507403-1-joshwash@google.com>
On device reset, GVE skips describe_device functionality, as the device
is not expected to change on a reset. However, before skipping the
describe_device functionality, GVE still sets the ring sizes to their
default values. This effectively removes the ability to create queues
with higher-than-default descriptor counts after a reset.
Fix this behavior by only setting the default ring size bounds is
describe_device is being executed.
Fixes: 1bf64edce3c4 ("net/gve: add reset path")
Cc: stable@dpdk.org
Signed-off-by: Joshua Washington <joshwash@google.com>
Reviewed-by: Jasper Tran O'Leary <jtranoleary@google.com>
---
drivers/net/gve/gve_ethdev.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/gve/gve_ethdev.c b/drivers/net/gve/gve_ethdev.c
index f73784a109..c990920a4d 100644
--- a/drivers/net/gve/gve_ethdev.c
+++ b/drivers/net/gve/gve_ethdev.c
@@ -1579,12 +1579,12 @@ gve_init_priv(struct gve_priv *priv, bool skip_describe_device)
goto free_adminq;
}
- /* Set default descriptor counts */
- gve_set_default_ring_size_bounds(priv);
-
if (skip_describe_device)
goto setup_device;
+ /* Set default descriptor counts */
+ gve_set_default_ring_size_bounds(priv);
+
/* Get the initial information we need from the device */
err = gve_adminq_describe_device(priv);
if (err) {
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related
* [PATCH v2 7/9] net/gve: increase range of DMA memzone ids to 64 bits
From: Joshua Washington @ 2026-07-03 13:13 UTC (permalink / raw)
To: Jeroen de Borst, Joshua Washington, Xiaoyun Li, Junfeng Guo,
Haiyue Wang
Cc: dev, stable, Jasper Tran O'Leary
In-Reply-To: <20260703131308.2507403-1-joshwash@google.com>
Long running programs can very easily eclipse this 16-bit range, leading
to name collisions and failed DMA region allocations despite there being
plenty of available memory.
Fixes: c9ba2caf6302 ("net/gve/base: add OS-specific implementation")
Cc: stable@dpdk.org
Signed-off-by: Joshua Washington <joshwash@google.com>
Reviewed-by: Jasper Tran O'Leary <jtranoleary@google.com>
---
drivers/net/gve/base/gve_osdep.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/gve/base/gve_osdep.h b/drivers/net/gve/base/gve_osdep.h
index c47ce4da85..55629a0e1a 100644
--- a/drivers/net/gve/base/gve_osdep.h
+++ b/drivers/net/gve/base/gve_osdep.h
@@ -175,14 +175,14 @@ struct gve_dma_mem {
static inline void *
gve_alloc_dma_mem(struct gve_dma_mem *mem, u64 size)
{
- static RTE_ATOMIC(uint16_t) gve_dma_memzone_id;
+ static RTE_ATOMIC(uint64_t) gve_dma_memzone_id;
const struct rte_memzone *mz = NULL;
char z_name[RTE_MEMZONE_NAMESIZE];
if (!mem)
return NULL;
- snprintf(z_name, sizeof(z_name), "gve_dma_%u",
+ snprintf(z_name, sizeof(z_name), "gve_dma_%" PRIu64,
rte_atomic_fetch_add_explicit(&gve_dma_memzone_id, 1, rte_memory_order_relaxed));
mz = rte_memzone_reserve_aligned(z_name, size, SOCKET_ID_ANY,
RTE_MEMZONE_IOVA_CONTIG,
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related
* [PATCH v2 6/9] net/gve: free ctx mbuf if packet dropped after first segment
From: Joshua Washington @ 2026-07-03 13:13 UTC (permalink / raw)
To: Jeroen de Borst, Joshua Washington, Rushil Gupta, Junfeng Guo
Cc: dev, stable, Jasper Tran O'Leary
In-Reply-To: <20260703131308.2507403-1-joshwash@google.com>
GVE GQ has support for multi-descriptor RX. It is possible for a packet
to be dropped after the first descriptor has been processed an mbuf has
been added to the context. In such a case, the mbuf head should be freed
before clearing the context so that mbufs aren't leaked.
In addition, clear mbuf from sw_ring after adding the packet to the
context to avoid double-freeing buffers that have not been reposted, but
have been reported to the application.
Fixes: 496d4d2c8b54 ("net/gve: support jumbo frame for GQI")
Cc: stable@dpdk.org
Signed-off-by: Joshua Washington <joshwash@google.com>
Reviewed-by: Jasper Tran O'Leary <jtranoleary@google.com>
---
drivers/net/gve/gve_rx.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/gve/gve_rx.c b/drivers/net/gve/gve_rx.c
index cda87af294..567b82d020 100644
--- a/drivers/net/gve/gve_rx.c
+++ b/drivers/net/gve/gve_rx.c
@@ -205,6 +205,8 @@ gve_rx_burst(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
if (gve_rx(rxq, rxd, rx_id)) {
if (!ctx->drop_pkt)
rx_pkts[nb_rx++] = ctx->mbuf_head;
+ else if (ctx->mbuf_head != NULL)
+ rte_pktmbuf_free(ctx->mbuf_head);
rxq->nb_avail += ctx->total_frags;
gve_rx_ctx_clear(ctx);
}
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related
* [PATCH v2 5/9] net/gve: set mbuf to null in software ring after use
From: Joshua Washington @ 2026-07-03 13:13 UTC (permalink / raw)
To: Jeroen de Borst, Joshua Washington, Junfeng Guo, Xiaoyun Li,
Rushil Gupta
Cc: dev, stable, Jasper Tran O'Leary
In-Reply-To: <20260703131308.2507403-1-joshwash@google.com>
Currently, it is possible for mbufs to be uncleared in the sw_ring after
being returned to the application. This causes an erroneous
dual-ownership over the buffer until GVE cleans the buffer queue and
posts new mbufs, overwriting the older pointers. It is possible in such
a case for a double free to occur while tearing down rings, as both
the application and the driver could attempt to free the same mbuf.
Release ownership of the mbuf from the sw_ring as soon as appropriate to
avoid such a scenario.
Fixes: a46583cf43c8 ("net/gve: support Rx/Tx")
Fixes: 45da16b5b181 ("net/gve: support basic Rx data path for DQO")
Cc: stable@dpdk.org
Signed-off-by: Joshua Washington <joshwash@google.com>
Reviewed-by: Jasper Tran O'Leary <jtranoleary@google.com>
---
drivers/net/gve/gve_rx.c | 1 +
drivers/net/gve/gve_rx_dqo.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/drivers/net/gve/gve_rx.c b/drivers/net/gve/gve_rx.c
index 625649cdcf..cda87af294 100644
--- a/drivers/net/gve/gve_rx.c
+++ b/drivers/net/gve/gve_rx.c
@@ -152,6 +152,7 @@ gve_rx(struct gve_rx_queue *rxq, volatile struct gve_rx_desc *rxd, uint16_t rx_i
rxe = rxq->sw_ring[rx_id];
gve_rx_mbuf(rxq, rxe, frag_size, rx_id);
+ rxq->sw_ring[rx_id] = NULL;
rxq->stats.bytes += frag_size;
if (is_first_frag) {
diff --git a/drivers/net/gve/gve_rx_dqo.c b/drivers/net/gve/gve_rx_dqo.c
index c4e2d32067..3665d9e4cd 100644
--- a/drivers/net/gve/gve_rx_dqo.c
+++ b/drivers/net/gve/gve_rx_dqo.c
@@ -207,6 +207,7 @@ gve_rx_burst_dqo(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
rxm = rxq->sw_ring[rx_buf_id];
gve_completed_buf_list_push(rxq, rx_buf_id);
+ rxq->sw_ring[rx_buf_id] = NULL;
/* Free buffer and report error. */
if (unlikely(rx_desc->rx_error)) {
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related
* [PATCH v2 4/9] net/gve: validate buf ID before processing Rx packet
From: Joshua Washington @ 2026-07-03 13:13 UTC (permalink / raw)
To: Jeroen de Borst, Joshua Washington, Ankit Garg
Cc: dev, stable, Jasper Tran O'Leary
In-Reply-To: <20260703131308.2507403-1-joshwash@google.com>
The buffer id is part of the RX completion descriptor for packets in the
DQ format. This value can technically go up to 64K, while the max RX
ring size is 4K, meaning that there could similarly be an expected 4K RX
buffer IDs. Validate that the RX buffer ID is valid before attempting to
access it in the sw_ring to prevent a potential out of bounds in the
event of a hardware error.
Fixes: 1aed73b23ac0 ("net/gve: support out-of-order completions on DQ Rx")
Cc: stable@dpdk.org
Signed-off-by: Joshua Washington <joshwash@google.com>
Reviewed-by: Jasper Tran O'Leary <jtranoleary@google.com>
---
drivers/net/gve/gve_rx_dqo.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/net/gve/gve_rx_dqo.c b/drivers/net/gve/gve_rx_dqo.c
index cc343f3fd8..c4e2d32067 100644
--- a/drivers/net/gve/gve_rx_dqo.c
+++ b/drivers/net/gve/gve_rx_dqo.c
@@ -200,6 +200,11 @@ gve_rx_burst_dqo(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
}
rx_buf_id = rte_le_to_cpu_16(rx_desc->buf_id);
+ if (unlikely(rx_buf_id >= rxq->nb_rx_desc)) {
+ PMD_DRV_DP_LOG(ERR, "Invalid buf_id %d", rx_buf_id);
+ continue;
+ }
+
rxm = rxq->sw_ring[rx_buf_id];
gve_completed_buf_list_push(rxq, rx_buf_id);
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related
* [PATCH v2 3/9] net/gve: copy data to QPL buffer when mbuf read does not
From: Joshua Washington @ 2026-07-03 13:13 UTC (permalink / raw)
To: Jeroen de Borst, Joshua Washington, Xiaoyun Li, Junfeng Guo
Cc: dev, stable, Jasper Tran O'Leary
In-Reply-To: <20260703131308.2507403-1-joshwash@google.com>
The rte_pktmbuf_read method does not guarantee that data will be copied
from an mbuf. If the requested data is all contiguous, the method will
instead return a pointer to the memory location within the buffer that
should be read from, leaving the destination buffer empty.
This is problematic for TSO/multi-segment TX packets which only make use
of two mbufs. If all data in the second mbuf is contiguous, the data
will not be read to QPL memory.
Update the QPL copy logic to copy if the rte_pktmbuf_read does not.
Fixes: a46583cf43c8 ("net/gve: support Rx/Tx")
Cc: stable@dpdk.org
Signed-off-by: Joshua Washington <joshwash@google.com>
Reviewed-by: Jasper Tran O'Leary <jtranoleary@google.com>
---
v2:
Removed unused declaration and definition of addr
drivers/net/gve/gve_tx.c | 38 +++++++++++++++++++++++---------------
1 file changed, 23 insertions(+), 15 deletions(-)
diff --git a/drivers/net/gve/gve_tx.c b/drivers/net/gve/gve_tx.c
index 59c82b04ed..d220d5167a 100644
--- a/drivers/net/gve/gve_tx.c
+++ b/drivers/net/gve/gve_tx.c
@@ -255,10 +255,10 @@ gve_tx_burst_qpl(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
struct rte_mbuf **sw_ring = txq->sw_ring;
uint16_t mask = txq->nb_tx_desc - 1;
uint16_t tx_id = txq->tx_tail & mask;
- uint64_t ol_flags, addr, fifo_addr;
uint32_t tx_tail = txq->tx_tail;
struct rte_mbuf *tx_pkt, *first;
uint16_t sw_id = txq->sw_tail;
+ uint64_t ol_flags, fifo_addr;
uint16_t nb_used, i;
uint64_t bytes = 0;
uint16_t nb_tx = 0;
@@ -273,6 +273,9 @@ gve_tx_burst_qpl(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
gve_tx_clean_swr_qpl(txq);
for (nb_tx = 0; nb_tx < nb_pkts; nb_tx++) {
+ const void *mbuf_header_addr;
+ void *qpl_write_addr;
+
tx_pkt = *tx_pkts++;
ol_flags = tx_pkt->ol_flags;
@@ -306,7 +309,6 @@ gve_tx_burst_qpl(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
if (!is_fifo_avail(txq, hlen))
goto end_of_tx;
}
- addr = (uint64_t)(tx_pkt->buf_addr) + tx_pkt->data_off;
fifo_addr = gve_tx_alloc_from_fifo(txq, tx_id, hlen);
/* For TSO, check if there's enough fifo space for data first */
@@ -317,26 +319,32 @@ gve_tx_burst_qpl(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
goto end_of_tx;
}
}
- if (tx_pkt->nb_segs == 1 || ol_flags & RTE_MBUF_F_TX_TCP_SEG)
- rte_memcpy((void *)(size_t)(fifo_addr + txq->fifo_base),
- (void *)(size_t)addr, hlen);
- else
- rte_pktmbuf_read(tx_pkt, 0, hlen,
- (void *)(size_t)(fifo_addr + txq->fifo_base));
+
+ qpl_write_addr = (void *)(size_t)(fifo_addr + txq->fifo_base);
+ mbuf_header_addr = rte_pktmbuf_read(tx_pkt, 0, hlen, qpl_write_addr);
+
+ /* Header data is linear in the mbuf head. Copy directly. */
+ if (mbuf_header_addr != qpl_write_addr)
+ rte_memcpy(qpl_write_addr, mbuf_header_addr, hlen);
+
gve_tx_fill_pkt_desc(txd, tx_pkt, nb_used, hlen, fifo_addr);
if (ol_flags & RTE_MBUF_F_TX_TCP_SEG) {
+ const void *mbuf_payload_addr;
+
tx_id = (tx_id + 1) & mask;
txd = &txr[tx_id];
- addr = (uint64_t)(tx_pkt->buf_addr) + tx_pkt->data_off + hlen;
fifo_addr = gve_tx_alloc_from_fifo(txq, tx_id, tx_pkt->pkt_len - hlen);
- if (tx_pkt->nb_segs == 1)
- rte_memcpy((void *)(size_t)(fifo_addr + txq->fifo_base),
- (void *)(size_t)addr,
+ qpl_write_addr = (void *)(txq->fifo_base + fifo_addr);
+ mbuf_payload_addr = rte_pktmbuf_read(tx_pkt, hlen, tx_pkt->pkt_len - hlen,
+ qpl_write_addr);
+
+ /* Payload data is contiguous. Take the offset from the
+ * read request and copy from there.
+ */
+ if (mbuf_payload_addr != qpl_write_addr)
+ rte_memcpy(qpl_write_addr, mbuf_payload_addr,
tx_pkt->pkt_len - hlen);
- else
- rte_pktmbuf_read(tx_pkt, hlen, tx_pkt->pkt_len - hlen,
- (void *)(size_t)(fifo_addr + txq->fifo_base));
gve_tx_fill_seg_desc(txd, ol_flags, tx_offload,
tx_pkt->pkt_len - hlen, fifo_addr);
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related
* [PATCH v2 2/9] net/gve: delay adding mbuf head to software ring
From: Joshua Washington @ 2026-07-03 13:12 UTC (permalink / raw)
To: Jeroen de Borst, Joshua Washington, Junfeng Guo, Xiaoyun Li
Cc: dev, stable, Jasper Tran O'Leary
In-Reply-To: <20260703131308.2507403-1-joshwash@google.com>
The GQ TX datapath was set up to write the mbuf head into the sw_ring
before writing the descriptors. This poses a problem because it's
possible for the packet to be dropped due to lacking the FIFO space to
do a proper TX. In such a case, the packet won't be sent, and will lead
to leaked mbufs in the subsequent segments.
There is also no real reason that the head mbuf must be set in the
sw_ring separately from the others; the mbuf chain is not actually
walked as part of GQ TX.
Fixes: a46583cf43c8 ("net/gve: support Rx/Tx")
Cc: stable@dpdk.org
Signed-off-by: Joshua Washington <joshwash@google.com>
Reviewed-by: Jasper Tran O'Leary <jtranoleary@google.com>
---
drivers/net/gve/gve_tx.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/gve/gve_tx.c b/drivers/net/gve/gve_tx.c
index 5c73c21b8d..59c82b04ed 100644
--- a/drivers/net/gve/gve_tx.c
+++ b/drivers/net/gve/gve_tx.c
@@ -301,7 +301,6 @@ gve_tx_burst_qpl(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
(uint32_t)(tx_offload.l2_len + tx_offload.l3_len + tx_offload.l4_len) :
tx_pkt->pkt_len;
- sw_ring[sw_id] = tx_pkt;
if (!is_fifo_avail(txq, hlen)) {
gve_tx_clean(txq);
if (!is_fifo_avail(txq, hlen))
@@ -344,13 +343,14 @@ gve_tx_burst_qpl(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
}
/* record mbuf in sw_ring for free */
- for (i = 1; i < first->nb_segs; i++) {
+ for (i = 0; i < first->nb_segs; i++) {
+ if (!tx_pkt)
+ break;
+ sw_ring[sw_id] = tx_pkt;
sw_id = (sw_id + 1) & mask;
tx_pkt = tx_pkt->next;
- sw_ring[sw_id] = tx_pkt;
}
- sw_id = (sw_id + 1) & mask;
tx_id = (tx_id + 1) & mask;
txq->nb_free -= nb_used;
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related
* [PATCH v2 1/9] net/gve: clear out shared memory region for stats report
From: Joshua Washington @ 2026-07-03 13:12 UTC (permalink / raw)
To: Jeroen de Borst, Joshua Washington, Ferruh Yigit, Rushil Gupta
Cc: dev, stable, Mark Blasko
In-Reply-To: <20260703131308.2507403-1-joshwash@google.com>
The stats report memzone is allocated from hugepage memory which could
possibly have had sensitive data from a previous DPDK invocation.
Clear out the buffer before sharing the memory region with the virtual
device to protect guest memory.
Fixes: 458b53dec01e ("net/gve: enable imissed stats for GQ format")
Cc: stable@dpdk.org
Signed-off-by: Joshua Washington <joshwash@google.com>
Reviewed-by: Mark Blasko <blasko@google.com>
---
drivers/net/gve/gve_ethdev.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/gve/gve_ethdev.c b/drivers/net/gve/gve_ethdev.c
index 0b02dcb3ad..f73784a109 100644
--- a/drivers/net/gve/gve_ethdev.c
+++ b/drivers/net/gve/gve_ethdev.c
@@ -306,6 +306,8 @@ gve_alloc_stats_report(struct gve_priv *priv,
if (!priv->stats_report_mem)
return -ENOMEM;
+ memset(priv->stats_report_mem->addr, 0, priv->stats_report_mem->len);
+
/* offset by skipping stats written by gve. */
priv->stats_start_idx = (GVE_TX_STATS_REPORT_NUM * nb_tx_queues) +
(GVE_RX_STATS_REPORT_NUM * nb_rx_queues);
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related
* [PATCH v2 0/9] Stability fixes for GVE
From: Joshua Washington @ 2026-07-03 13:12 UTC (permalink / raw)
Cc: dev, Joshua Washington
This patch series consists of mostly unrelated fixes in the GVE driver.
Joshua Washington (9):
net/gve: clear out shared memory region for stats report
net/gve: delay adding mbuf head to software ring
net/gve: copy data to QPL buffer when mbuf read does not
net/gve: validate buf ID before processing Rx packet
net/gve: set mbuf to null in software ring after use
net/gve: free ctx mbuf if packet dropped after first segment
net/gve: increase range of DMA memzone ids to 64 bits
net/gve: don't reset ring size bounds to default on reset
net/gve: restrict max ring size in GQ QPL to 2K
drivers/net/gve/base/gve_adminq.c | 12 ++++++--
drivers/net/gve/base/gve_osdep.h | 4 +--
drivers/net/gve/gve_ethdev.c | 8 ++++--
drivers/net/gve/gve_ethdev.h | 1 +
drivers/net/gve/gve_rx.c | 3 ++
drivers/net/gve/gve_rx_dqo.c | 6 ++++
drivers/net/gve/gve_tx.c | 46 ++++++++++++++++++-------------
7 files changed, 53 insertions(+), 27 deletions(-)
---
v2:
* Remove unused definition
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply
* Re: [PATCH v6 00/19] DPAA bus/net/mempool/DMA driver fixes and improvements
From: Hemant Agrawal @ 2026-07-03 12:50 UTC (permalink / raw)
To: Stephen Hemminger, Hemant Agrawal; +Cc: david.marchand, dev
In-Reply-To: <20260702093259.33f2151f@phoenix.local>
> Thank you for the thorough review. All findings were valid. Here is a
> summary of changes made for v7:
>
> > patch 04: s_data_validation, s_sg_enable, s_pci_read are used in
> > this patch but are declared only in patch 18 -- bisect break.
>
> Fixed. The three static variable declarations have been moved into
> patch 04, where they are first used. Patch 18 no longer re-declares
> them.
>
> > patch 03: BMI Tx counters are read from the wrong buffer in
> > dpaa_xstats_get_by_id() (copies from values_copy which was filled by
> > fman_if_stats_get_all, not by fman_if_bmi_stats_get_all). Also,
> > bmi_count = sizeof(struct dpaa_if_rx_bmi_stats) / 4 omits the 4 Tx
> > BMI entries.
>
> Fixed. A separate bmi_values[] array sized for both Rx and Tx BMI
> stats is now used in both xstats_get() and xstats_get_by_id(). A new
> function fman_if_tx_bmi_stats_get_all() fills the Tx half.
>
> > patch 13: dpaa_bus_dev_compare() has side effects -- sets
> > dpaa_bus.detected and calls pthread_key_create -- but returns 0 for
> > all calls after the first, breaking multi-device enumeration.
>
> Fixed. dpaa_bus_dev_compare() is now a pure comparator using
> rte_dpaa_bus_parse() + strncmp(). The detection block remains only in
> rte_dpaa_bus_scan() where it has always lived.
>
> > patch 08: unreachable "return -ENODEV" after do { } while (1) in
> > qman_find_fq_by_cgrid().
>
> Fixed. The dead return statement has been removed.
>
> > patch 17: RTE_PRIORITY_104 is defined but RTE_FINI_PRIO uses the
> > literal 104 directly.
>
> Fixed. RTE_FINI_PRIO now uses RTE_PRIORITY_104.
>
> > patch 18: s_hw_err_check changed from bool to int without
> > justification.
>
> Fixed. Reverted to bool.
>
> > patch 19: commit message says "add ONIC port checks" but the patch
> > also changes dpaa_port_vsp_cleanup() signature and refactors
> > dpaa_flow.c.
>
> Fixed. The commit message now also describes the fif parameter removal
> from dpaa_port_vsp_cleanup() and the dpaa_flow.c refactor.
>
> The series is now 16 patches (v6 had 19; three patches whose content
> was subsumed by conflict resolution with adjacent changes have been
> consolidated).
>
^ permalink raw reply
* [PATCH v7 16/16] dma/dpaa: add SG data validation and ERR050757 fix
From: Hemant Agrawal @ 2026-07-03 12:49 UTC (permalink / raw)
To: stephen, david.marchand, dev; +Cc: Gagandeep Singh
In-Reply-To: <20260703124950.1895871-1-hemant.agrawal@nxp.com>
From: Gagandeep Singh <g.singh@nxp.com>
Add scatter-gather (SG) support to the QDMA driver, enabled by default
via the s_sg_enable flag. Add optional data validation mode controlled
by the s_data_validation flag for debugging transfer correctness.
Add a workaround for hardware errata ERR050757: when
RTE_DMA_DPAA_ERRATA_ERR050757 is defined, configure the source frame
descriptor with stride settings (sss/ssd = FSL_QDMA_CMD_SS_ERR050757_LEN)
to force PCI read transactions to stay within the errata-safe length
limit, preventing data corruption on affected silicon.
Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
drivers/dma/dpaa/dpaa_qdma.c | 73 ++++++++++++++++++++++++------------
1 file changed, 49 insertions(+), 24 deletions(-)
diff --git a/drivers/dma/dpaa/dpaa_qdma.c b/drivers/dma/dpaa/dpaa_qdma.c
index 6a4022c652..14ab102a90 100644
--- a/drivers/dma/dpaa/dpaa_qdma.c
+++ b/drivers/dma/dpaa/dpaa_qdma.c
@@ -17,7 +17,6 @@ static uint32_t s_sg_max_entry_sz = 2000;
#ifdef RTE_DMA_DPAA_ERRATA_ERR050757
static int s_pci_read = 1;
#endif
-
#define DPAA_DMA_ERROR_CHECK "dpaa_dma_err_check"
static inline void
@@ -118,7 +117,8 @@ dma_pool_alloc(char *nm, int size, int aligned, dma_addr_t *phy_addr)
if (!virt_addr)
return NULL;
- *phy_addr = rte_mem_virt2iova(virt_addr);
+ if (phy_addr)
+ *phy_addr = rte_mem_virt2iova(virt_addr);
return virt_addr;
}
@@ -398,6 +398,8 @@ fsl_qdma_data_validation(struct fsl_qdma_desc *desc[],
char err_msg[512];
int offset;
+ if (likely(!s_data_validation))
+ return;
offset = sprintf(err_msg, "Fatal TC%d/queue%d: ",
fsl_queue->block_id,
@@ -722,19 +724,21 @@ fsl_qdma_enqueue_desc_single(struct fsl_qdma_queue *fsl_queue,
ft = fsl_queue->ft[fsl_queue->ci];
#ifdef RTE_DMA_DPAA_ERRATA_ERR050757
- sdf = &ft->df.sdf;
- sdf->srttype = FSL_QDMA_CMD_RWTTYPE;
+ if (s_pci_read) {
+ sdf = &ft->df.sdf;
+ sdf->srttype = FSL_QDMA_CMD_RWTTYPE;
#ifdef RTE_DMA_DPAA_ERRATA_ERR050265
- sdf->prefetch = 1;
+ sdf->prefetch = 1;
#endif
- if (len > FSL_QDMA_CMD_SS_ERR050757_LEN) {
- sdf->ssen = 1;
- sdf->sss = FSL_QDMA_CMD_SS_ERR050757_LEN;
- sdf->ssd = FSL_QDMA_CMD_SS_ERR050757_LEN;
- } else {
- sdf->ssen = 0;
- sdf->sss = 0;
- sdf->ssd = 0;
+ if (len > FSL_QDMA_CMD_SS_ERR050757_LEN) {
+ sdf->ssen = 1;
+ sdf->sss = FSL_QDMA_CMD_SS_ERR050757_LEN;
+ sdf->ssd = FSL_QDMA_CMD_SS_ERR050757_LEN;
+ } else {
+ sdf->ssen = 0;
+ sdf->sss = 0;
+ sdf->ssd = 0;
+ }
}
#endif
csgf_src = &ft->desc_sbuf;
@@ -838,19 +842,21 @@ fsl_qdma_enqueue_desc_sg(struct fsl_qdma_queue *fsl_queue)
csgf_src->length = total_len;
csgf_dest->length = total_len;
#ifdef RTE_DMA_DPAA_ERRATA_ERR050757
- sdf = &ft->df.sdf;
- sdf->srttype = FSL_QDMA_CMD_RWTTYPE;
+ if (s_pci_read) {
+ sdf = &ft->df.sdf;
+ sdf->srttype = FSL_QDMA_CMD_RWTTYPE;
#ifdef RTE_DMA_DPAA_ERRATA_ERR050265
- sdf->prefetch = 1;
+ sdf->prefetch = 1;
#endif
- if (total_len > FSL_QDMA_CMD_SS_ERR050757_LEN) {
- sdf->ssen = 1;
- sdf->sss = FSL_QDMA_CMD_SS_ERR050757_LEN;
- sdf->ssd = FSL_QDMA_CMD_SS_ERR050757_LEN;
- } else {
- sdf->ssen = 0;
- sdf->sss = 0;
- sdf->ssd = 0;
+ if (total_len > FSL_QDMA_CMD_SS_ERR050757_LEN) {
+ sdf->ssen = 1;
+ sdf->sss = FSL_QDMA_CMD_SS_ERR050757_LEN;
+ sdf->ssd = FSL_QDMA_CMD_SS_ERR050757_LEN;
+ } else {
+ sdf->ssen = 0;
+ sdf->sss = 0;
+ sdf->ssd = 0;
+ }
}
#endif
ret = fsl_qdma_enqueue_desc_to_ring(fsl_queue, num);
@@ -889,6 +895,25 @@ fsl_qdma_enqueue_desc(struct fsl_qdma_queue *fsl_queue)
fsl_queue->pending_num = 0;
}
return ret;
+ } else if (!s_sg_enable) {
+ while (fsl_queue->pending_num > 0) {
+ ret = fsl_qdma_enqueue_desc_single(fsl_queue,
+ fsl_queue->pending_desc[start].dst,
+ fsl_queue->pending_desc[start].src,
+ fsl_queue->pending_desc[start].len);
+ if (!ret) {
+ start = (start + 1) &
+ (fsl_queue->pending_max - 1);
+ fsl_queue->pending_start = start;
+ fsl_queue->pending_num--;
+ } else {
+ DPAA_QDMA_ERR("Eq pending desc failed(%d)",
+ ret);
+ return -EIO;
+ }
+ }
+
+ return 0;
}
return fsl_qdma_enqueue_desc_sg(fsl_queue);
--
2.25.1
^ permalink raw reply related
* [PATCH v7 15/16] drivers: release DPAA bpid on driver destructor
From: Hemant Agrawal @ 2026-07-03 12:49 UTC (permalink / raw)
To: stephen, david.marchand, dev; +Cc: Jun Yang
In-Reply-To: <20260703124950.1895871-1-hemant.agrawal@nxp.com>
From: Jun Yang <jun.yang@nxp.com>
Track allocated BPIDs in a static per-BPID flag table and register a
driver destructor that releases any BPIDs still marked as in use at
process exit. This prevents BPID leaks when an application exits without
calling rte_mempool_free(). Also tune the per-lcore mempool cache flush
threshold to match the hardware bulk release size (DPAA_MBUF_MAX_ACQ_REL)
so that buffers are returned to HW in optimal burst sizes.
Signed-off-by: Jun Yang <jun.yang@nxp.com>
---
drivers/bus/dpaa/base/qbman/bman.c | 8 +++
drivers/bus/dpaa/dpaa_bus_base_symbols.c | 1 +
drivers/bus/dpaa/include/fsl_bman.h | 3 ++
drivers/mempool/dpaa/dpaa_mempool.c | 67 ++++++++++++++++++++++--
drivers/mempool/dpaa/dpaa_mempool.h | 3 +-
5 files changed, 78 insertions(+), 4 deletions(-)
diff --git a/drivers/bus/dpaa/base/qbman/bman.c b/drivers/bus/dpaa/base/qbman/bman.c
index 225a8a9fd7..4286e6df6a 100644
--- a/drivers/bus/dpaa/base/qbman/bman.c
+++ b/drivers/bus/dpaa/base/qbman/bman.c
@@ -237,6 +237,14 @@ void bman_free_pool(struct bman_pool *pool)
kfree(pool);
}
+void bman_free_bpid(u8 bpid, u32 flags)
+{
+ if (flags & BMAN_POOL_FLAG_THRESH)
+ bm_pool_set(bpid, zero_thresholds);
+ if (flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
+ bman_release_bpid(bpid);
+}
+
const struct bman_pool_params *bman_get_params(const struct bman_pool *pool)
{
return &pool->params;
diff --git a/drivers/bus/dpaa/dpaa_bus_base_symbols.c b/drivers/bus/dpaa/dpaa_bus_base_symbols.c
index d5609bc40d..266fc88517 100644
--- a/drivers/bus/dpaa/dpaa_bus_base_symbols.c
+++ b/drivers/bus/dpaa/dpaa_bus_base_symbols.c
@@ -58,6 +58,7 @@ RTE_EXPORT_INTERNAL_SYMBOL(qman_alloc_cgrid_range)
RTE_EXPORT_INTERNAL_SYMBOL(qman_release_cgrid_range)
RTE_EXPORT_INTERNAL_SYMBOL(dpaa_get_qm_channel_pool_num)
RTE_EXPORT_INTERNAL_SYMBOL(qman_find_fq_by_cgrid)
+RTE_EXPORT_INTERNAL_SYMBOL(bman_free_bpid)
RTE_EXPORT_INTERNAL_SYMBOL(dpaa_intr_enable)
RTE_EXPORT_INTERNAL_SYMBOL(dpaa_intr_disable)
RTE_EXPORT_INTERNAL_SYMBOL(dpaa_get_ioctl_version_number)
diff --git a/drivers/bus/dpaa/include/fsl_bman.h b/drivers/bus/dpaa/include/fsl_bman.h
index 67a7a09618..6079eedff5 100644
--- a/drivers/bus/dpaa/include/fsl_bman.h
+++ b/drivers/bus/dpaa/include/fsl_bman.h
@@ -317,6 +317,9 @@ struct bman_pool *bman_new_pool(const struct bman_pool_params *params);
__rte_internal
void bman_free_pool(struct bman_pool *pool);
+__rte_internal
+void bman_free_bpid(u8 bpid, u32 flags);
+
/**
* bman_get_params - Returns a pool object's parameters.
* @pool: the pool object
diff --git a/drivers/mempool/dpaa/dpaa_mempool.c b/drivers/mempool/dpaa/dpaa_mempool.c
index 3fdbcba646..25f37bab51 100644
--- a/drivers/mempool/dpaa/dpaa_mempool.c
+++ b/drivers/mempool/dpaa/dpaa_mempool.c
@@ -25,10 +25,22 @@
#include <rte_eal.h>
#include <rte_malloc.h>
#include <rte_ring.h>
+#include <rte_common.h>
#include <dpaa_mempool.h>
#include <dpaax_iova_table.h>
+struct dpaa_bpid_flag {
+ uint32_t flags;
+ int used;
+};
+
+/** Be referenced in destructor to release bpid allocated.
+ * Destructor can't access bman_pool from eal mem,
+ * we release ID with flag directly.
+ */
+static struct dpaa_bpid_flag s_dpaa_bpid_allocated_flag[DPAA_MAX_BPOOLS];
+
#define FMAN_ERRATA_BOUNDARY ((uint64_t)4096)
#define FMAN_ERRATA_BOUNDARY_MASK (~(FMAN_ERRATA_BOUNDARY - 1))
@@ -58,6 +70,8 @@ dpaa_mbuf_create_pool(struct rte_mempool *mp)
struct bman_pool_params params = {
.flags = BMAN_POOL_FLAG_DYNAMIC_BPID
};
+ unsigned int lcore_id;
+ struct rte_mempool_cache *cache;
MEMPOOL_INIT_FUNC_TRACE();
@@ -115,7 +129,7 @@ dpaa_mbuf_create_pool(struct rte_mempool *mp)
rte_dpaa_bpid_info[bpid].ptov_off = 0;
rte_dpaa_bpid_info[bpid].flags = 0;
- bp_info = rte_malloc(NULL,
+ bp_info = rte_zmalloc(NULL,
sizeof(struct dpaa_bp_info),
RTE_CACHE_LINE_SIZE);
if (!bp_info) {
@@ -127,6 +141,20 @@ dpaa_mbuf_create_pool(struct rte_mempool *mp)
rte_memcpy(bp_info, (void *)&rte_dpaa_bpid_info[bpid],
sizeof(struct dpaa_bp_info));
mp->pool_data = (void *)bp_info;
+ s_dpaa_bpid_allocated_flag[bpid].flags = params.flags;
+ s_dpaa_bpid_allocated_flag[bpid].used = true;
+ /* Update per core mempool cache threshold to optimal value which is
+ * number of buffers that can be released to HW buffer pool in
+ * a single API call.
+ */
+ for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
+ cache = &mp->local_cache[lcore_id];
+ DPAA_MEMPOOL_DEBUG("lCore %d: cache->flushthresh %d -> %d",
+ lcore_id, cache->flushthresh,
+ (uint32_t)(cache->size + DPAA_MBUF_MAX_ACQ_REL));
+ if (cache->flushthresh)
+ cache->flushthresh = cache->size + DPAA_MBUF_MAX_ACQ_REL;
+ }
DPAA_MEMPOOL_INFO("BMAN pool created for bpid =%d", bpid);
return 0;
@@ -136,6 +164,7 @@ static void
dpaa_mbuf_free_pool(struct rte_mempool *mp)
{
struct dpaa_bp_info *bp_info = DPAA_MEMPOOL_TO_POOL_INFO(mp);
+ uint16_t i;
MEMPOOL_INIT_FUNC_TRACE();
@@ -143,10 +172,25 @@ dpaa_mbuf_free_pool(struct rte_mempool *mp)
bman_free_pool(bp_info->bp);
DPAA_MEMPOOL_INFO("BMAN pool freed for bpid =%d",
bp_info->bpid);
- rte_free(mp->pool_data);
- bp_info->bp = NULL;
+ rte_dpaa_bpid_info[bp_info->bpid].mp = NULL;
+ rte_dpaa_bpid_info[bp_info->bpid].bp = NULL;
+ s_dpaa_bpid_allocated_flag[bp_info->bpid].used = false;
+ rte_free(bp_info);
mp->pool_data = NULL;
}
+
+ if (!rte_dpaa_bpid_info)
+ return;
+
+ for (i = 0; i < DPAA_MAX_BPOOLS; i++) {
+ if (rte_dpaa_bpid_info[i].mp)
+ break;
+ }
+
+ if (i == DPAA_MAX_BPOOLS) {
+ rte_free(rte_dpaa_bpid_info);
+ rte_dpaa_bpid_info = NULL;
+ }
}
static int
@@ -481,4 +525,21 @@ static const struct rte_mempool_ops dpaa_mpool_ops = {
.populate = dpaa_populate,
};
+#define RTE_PRIORITY_104 104
+
+RTE_FINI_PRIO(dpaa_mpool_finish, RTE_PRIORITY_104)
+{
+ uint16_t bpid;
+
+ for (bpid = 0; bpid < DPAA_MAX_BPOOLS; bpid++) {
+ if (s_dpaa_bpid_allocated_flag[bpid].used) {
+ bman_free_bpid(bpid, s_dpaa_bpid_allocated_flag[bpid].flags);
+ s_dpaa_bpid_allocated_flag[bpid].used = false;
+ }
+ }
+ /** The rte_dpaa_bpid_info and bman_pool from EAL mem have been released
+ * with EAL mem pool being destroyed.
+ */
+}
+
RTE_MEMPOOL_REGISTER_OPS(dpaa_mpool_ops);
diff --git a/drivers/mempool/dpaa/dpaa_mempool.h b/drivers/mempool/dpaa/dpaa_mempool.h
index 865b533b8f..d7ee49b557 100644
--- a/drivers/mempool/dpaa/dpaa_mempool.h
+++ b/drivers/mempool/dpaa/dpaa_mempool.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
*
- * Copyright 2017,2019,2024 -2025 NXP
+ * Copyright 2017,2019,2024 -2026 NXP
*
*/
#ifndef __DPAA_MEMPOOL_H__
@@ -24,6 +24,7 @@
/* total number of bpools on SoC */
#define DPAA_MAX_BPOOLS 256
+#define DPAA_INVALID_BPID DPAA_MAX_BPOOLS
/* Maximum release/acquire from BMAN */
#define DPAA_MBUF_MAX_ACQ_REL FSL_BM_BURST_MAX
--
2.25.1
^ permalink raw reply related
* [PATCH v7 14/16] drivers: optimize DPAA multi-entry buffer pool operations
From: Hemant Agrawal @ 2026-07-03 12:49 UTC (permalink / raw)
To: stephen, david.marchand, dev; +Cc: Jun Yang
In-Reply-To: <20260703124950.1895871-1-hemant.agrawal@nxp.com>
From: Jun Yang <jun.yang@nxp.com>
Replace the hardcoded buffer acquire count of 8 with the FSL_BM_BURST_MAX
constant when acquiring buffers from the buffer pool. Use a single
bm_hw_buf_desc structure for HW initialization of the first entry and copy
it to remaining entries, ensuring consistent HW descriptor state across
all entries in the pool.
Signed-off-by: Jun Yang <jun.yang@nxp.com>
---
drivers/bus/dpaa/base/qbman/bman.c | 51 +++++++----------------------
drivers/bus/dpaa/include/fsl_bman.h | 46 +++++++++++++++++++++-----
drivers/mempool/dpaa/dpaa_mempool.c | 8 ++---
3 files changed, 54 insertions(+), 51 deletions(-)
diff --git a/drivers/bus/dpaa/base/qbman/bman.c b/drivers/bus/dpaa/base/qbman/bman.c
index ee4232d0a0..225a8a9fd7 100644
--- a/drivers/bus/dpaa/base/qbman/bman.c
+++ b/drivers/bus/dpaa/base/qbman/bman.c
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
*
* Copyright 2008-2016 Freescale Semiconductor Inc.
- * Copyright 2017, 2024 NXP
+ * Copyright 2017, 2024-2026 NXP
*
*/
#include <rte_memcpy.h>
@@ -17,20 +17,6 @@
#define IRQNAME "BMan portal %d"
#define MAX_IRQNAME 16 /* big enough for "BMan portal %d" */
-
-#define MAX_U16 UINT16_MAX
-#define MAX_U32 UINT32_MAX
-#ifndef BIT_SIZE
-#define BIT_SIZE(t) (sizeof(t) * 8)
-#endif
-#define MAX_U48 \
- ((((uint64_t)MAX_U16) << BIT_SIZE(uint32_t)) | MAX_U32)
-#define HI16_OF_U48(x) \
- (((x) >> BIT_SIZE(rte_be32_t)) & MAX_U16)
-#define LO32_OF_U48(x) ((x) & MAX_U32)
-#define U48_BY_HI16_LO32(hi, lo) \
- (((hi) << BIT_SIZE(uint32_t)) | (lo))
-
struct bman_portal {
struct bm_portal p;
/* 2-element array. pools[0] is mask, pools[1] is snapshot. */
@@ -273,7 +259,7 @@ bman_release_fast(struct bman_pool *pool, const uint64_t *bufs,
struct bm_rcr_entry *r;
uint8_t i, avail;
uint64_t bpid = pool->params.bpid;
- struct bm_hw_buf_desc bm_bufs[FSL_BM_BURST_MAX];
+ struct bm_buffer bm_bufs[FSL_BM_BURST_MAX];
#ifdef RTE_LIBRTE_DPAA_HWDEBUG
if (!num || (num > FSL_BM_BURST_MAX))
@@ -290,19 +276,17 @@ bman_release_fast(struct bman_pool *pool, const uint64_t *bufs,
if (unlikely(!r))
return -EBUSY;
+ bm_bufs[0].be_desc.bpid = bpid;
+ for (i = 0; i < num; i++)
+ bm_buffer_set64_to_be(&bm_bufs[i], bufs[i]);
/*
* we can copy all but the first entry, as this can trigger badness
* with the valid-bit
*/
- bm_bufs[0].bpid = bpid;
- bm_bufs[0].hi_addr = cpu_to_be16(HI16_OF_U48(bufs[0]));
- bm_bufs[0].lo_addr = cpu_to_be32(LO32_OF_U48(bufs[0]));
- for (i = 1; i < num; i++) {
- bm_bufs[i].hi_addr = cpu_to_be16(HI16_OF_U48(bufs[i]));
- bm_bufs[i].lo_addr = cpu_to_be32(LO32_OF_U48(bufs[i]));
- }
-
- memcpy(r->bufs, bm_bufs, sizeof(struct bm_buffer) * num);
+ r->bufs[0].opaque = bm_bufs[0].opaque;
+ if (num > 1)
+ memcpy(&r->bufs[1], &bm_bufs[1],
+ sizeof(struct bm_buffer) * (num - 1));
bm_rcr_pvb_commit(&p->p, BM_RCR_VERB_CMD_BPID_SINGLE |
(num & BM_RCR_VERB_BUFCOUNT_MASK));
@@ -360,16 +344,6 @@ __rte_unused bman_extract_addr(struct bm_buffer *buf)
return buf->addr;
}
-static inline uint64_t
-bman_hw_extract_addr(struct bm_hw_buf_desc *buf)
-{
- uint64_t hi, lo;
-
- hi = be16_to_cpu(buf->hi_addr);
- lo = be32_to_cpu(buf->lo_addr);
- return U48_BY_HI16_LO32(hi, lo);
-}
-
RTE_EXPORT_INTERNAL_SYMBOL(bman_acquire_fast)
int
bman_acquire_fast(struct bman_pool *pool, uint64_t *bufs, uint8_t num)
@@ -378,7 +352,7 @@ bman_acquire_fast(struct bman_pool *pool, uint64_t *bufs, uint8_t num)
struct bm_mc_command *mcc;
struct bm_mc_result *mcr;
uint8_t i, rst;
- struct bm_hw_buf_desc bm_bufs[FSL_BM_BURST_MAX];
+ struct bm_buffer bm_bufs[FSL_BM_BURST_MAX];
#ifdef RTE_LIBRTE_DPAA_HWDEBUG
if (!num || (num > FSL_BM_BURST_MAX))
@@ -397,11 +371,10 @@ bman_acquire_fast(struct bman_pool *pool, uint64_t *bufs, uint8_t num)
if (unlikely(rst < 1 || rst > FSL_BM_BURST_MAX))
return -EINVAL;
- rte_memcpy(bm_bufs, mcr->acquire.bufs,
- sizeof(struct bm_buffer) * rst);
+ rte_memcpy(bm_bufs, mcr->acquire.bufs, sizeof(struct bm_buffer) * rst);
for (i = 0; i < rst; i++)
- bufs[i] = bman_hw_extract_addr(&bm_bufs[i]);
+ bufs[i] = bm_buffer_get64_from_be(&bm_bufs[i]);
return rst;
}
diff --git a/drivers/bus/dpaa/include/fsl_bman.h b/drivers/bus/dpaa/include/fsl_bman.h
index 2d24b89889..67a7a09618 100644
--- a/drivers/bus/dpaa/include/fsl_bman.h
+++ b/drivers/bus/dpaa/include/fsl_bman.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
*
* Copyright 2008-2012 Freescale Semiconductor, Inc.
- * Copyright 2024 NXP
+ * Copyright 2024-2026 NXP
*
*/
@@ -42,6 +42,13 @@ struct bm_mc_result; /* MC result */
* pool id specific to this buffer is needed (BM_RCR_VERB_CMD_BPID_MULTI,
* BM_MCC_VERB_ACQUIRE), the 'bpid' field is used.
*/
+struct __rte_packed_begin bm_hw_buf_desc {
+ uint8_t rsv;
+ uint8_t bpid;
+ rte_be16_t hi; /* High 16-bits of 48-bit address */
+ rte_be32_t lo; /* Low 32-bits of 48-bit address */
+} __rte_packed_end;
+
struct __rte_aligned(8) bm_buffer {
union {
struct {
@@ -66,17 +73,11 @@ struct __rte_aligned(8) bm_buffer {
u64 __notaddress:16;
#endif
};
+ struct bm_hw_buf_desc be_desc;
u64 opaque;
};
};
-struct __rte_packed_begin bm_hw_buf_desc {
- uint8_t rsv;
- uint8_t bpid;
- rte_be16_t hi_addr; /* High 16-bits of 48-bit address */
- rte_be32_t lo_addr; /* Low 32-bits of 48-bit address */
-} __rte_packed_end;
-
static inline u64 bm_buffer_get64(const struct bm_buffer *buf)
{
return buf->addr;
@@ -87,6 +88,17 @@ static inline dma_addr_t bm_buf_addr(const struct bm_buffer *buf)
return (dma_addr_t)buf->addr;
}
+#ifndef BIT_SIZE
+#define BIT_SIZE(t) (sizeof(t) * 8)
+#endif
+#define MAX_U48 \
+ ((((uint64_t)UINT16_MAX) << BIT_SIZE(uint32_t)) | UINT32_MAX)
+#define HI16_OF_U48(x) \
+ (((x) >> BIT_SIZE(uint32_t)) & UINT16_MAX)
+#define LO32_OF_U48(x) ((x) & UINT32_MAX)
+#define U48_BY_HI16_LO32(hi, lo) \
+ (((hi) << BIT_SIZE(uint32_t)) | (lo))
+
#define bm_buffer_set64(buf, v) \
do { \
struct bm_buffer *__buf931 = (buf); \
@@ -94,6 +106,24 @@ static inline dma_addr_t bm_buf_addr(const struct bm_buffer *buf)
__buf931->lo = lower_32_bits(v); \
} while (0)
+#define bm_buffer_set64_to_be(buf, v) \
+ do { \
+ struct bm_buffer *__buf931 = (buf); \
+ \
+ __buf931->be_desc.hi = cpu_to_be16(HI16_OF_U48(v)); \
+ __buf931->be_desc.lo = cpu_to_be32(LO32_OF_U48(v)); \
+ } while (0)
+
+#define bm_buffer_get64_from_be(buf) \
+ ({ \
+ uint64_t hi, lo; \
+ struct bm_buffer *__buf931 = (buf); \
+ \
+ hi = be16_to_cpu(__buf931->be_desc.hi); \
+ lo = be32_to_cpu(__buf931->be_desc.lo); \
+ U48_BY_HI16_LO32(hi, lo); \
+ })
+
#define FSL_BM_BURST_MAX 8
/* See 1.5.3.5.4: "Release Command" */
diff --git a/drivers/mempool/dpaa/dpaa_mempool.c b/drivers/mempool/dpaa/dpaa_mempool.c
index 2f8555a026..3fdbcba646 100644
--- a/drivers/mempool/dpaa/dpaa_mempool.c
+++ b/drivers/mempool/dpaa/dpaa_mempool.c
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
*
- * Copyright 2017,2019,2023-2025 NXP
+ * Copyright 2017,2019,2023-2026 NXP
*
*/
@@ -50,7 +50,7 @@ static int
dpaa_mbuf_create_pool(struct rte_mempool *mp)
{
struct bman_pool *bp;
- struct bm_buffer bufs[8];
+ struct bm_buffer bufs[FSL_BM_BURST_MAX];
struct dpaa_bp_info *bp_info;
uint8_t bpid;
int num_bufs = 0, ret = 0;
@@ -83,8 +83,8 @@ dpaa_mbuf_create_pool(struct rte_mempool *mp)
* then in 1s for the remainder.
*/
if (ret != 1)
- ret = bman_acquire(bp, bufs, 8, 0);
- if (ret < 8)
+ ret = bman_acquire(bp, bufs, FSL_BM_BURST_MAX, 0);
+ if (ret < FSL_BM_BURST_MAX)
ret = bman_acquire(bp, bufs, 1, 0);
if (ret > 0)
num_bufs += ret;
--
2.25.1
^ permalink raw reply related
* [PATCH v7 13/16] net/dpaa: optimize FMC MAC type parsing
From: Hemant Agrawal @ 2026-07-03 12:49 UTC (permalink / raw)
To: stephen, david.marchand, dev; +Cc: Jun Yang
In-Reply-To: <20260703124950.1895871-1-hemant.agrawal@nxp.com>
From: Jun Yang <jun.yang@nxp.com>
For ls104xa, MAC9 and MAC10's type could be either of 10G/2.5G/1G
up to serdes configuration, MAC index should be identified by
port name instead of parsing MAC type and port number.
Signed-off-by: Jun Yang <jun.yang@nxp.com>
---
drivers/net/dpaa/dpaa_fmc.c | 73 ++++++++++++++++++++++---------------
1 file changed, 44 insertions(+), 29 deletions(-)
diff --git a/drivers/net/dpaa/dpaa_fmc.c b/drivers/net/dpaa/dpaa_fmc.c
index 7dc42f6e23..3034f534a5 100644
--- a/drivers/net/dpaa/dpaa_fmc.c
+++ b/drivers/net/dpaa/dpaa_fmc.c
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright 2017-2023 NXP
+ * Copyright 2017-2026 NXP
*/
/* System headers */
@@ -204,6 +204,36 @@ struct fmc_model_t {
struct fmc_model_t *g_fmc_model;
+static int
+dpaa_port_fmc_get_idx_from_name(const char *name)
+{
+ const char *found;
+ int idx_str_start = -1, idx;
+
+#define FMC_PORT_NAME_MAC "MAC/"
+#define FMC_PORT_NAME_OFFLINE "OFFLINE/"
+
+ found = strstr(name, FMC_PORT_NAME_MAC);
+ if (!found) {
+ found = strstr(name, FMC_PORT_NAME_OFFLINE);
+ if (found)
+ idx_str_start = strlen(FMC_PORT_NAME_OFFLINE);
+ } else {
+ idx_str_start = strlen(FMC_PORT_NAME_MAC);
+ }
+
+ if (!found) {
+ DPAA_PMD_ERR("Invalid fmc port name: %s", name);
+ return -EINVAL;
+ }
+
+ idx = atoi(&found[idx_str_start]);
+
+ DPAA_PMD_INFO("MAC index of %s is %d", name, idx);
+
+ return idx;
+}
+
static int
dpaa_port_fmc_port_parse(struct fman_if *fif,
const struct fmc_model_t *fmc_model,
@@ -211,7 +241,10 @@ dpaa_port_fmc_port_parse(struct fman_if *fif,
{
int current_port = fmc_model->apply_order[apply_idx].index;
const fmc_port *pport = &fmc_model->port[current_port];
- uint32_t num;
+ int num = dpaa_port_fmc_get_idx_from_name(pport->name);
+
+ if (num < 0)
+ return num;
if (pport->type == e_FM_PORT_TYPE_OH_OFFLINE_PARSING &&
pport->number == fif->mac_idx &&
@@ -219,40 +252,22 @@ dpaa_port_fmc_port_parse(struct fman_if *fif,
fif->mac_type == fman_onic))
return current_port;
- if (fif->mac_type == fman_mac_1g) {
- if (pport->type != e_FM_PORT_TYPE_RX)
- return -ENODEV;
- num = pport->number + DPAA_1G_MAC_START_IDX;
- if (fif->mac_idx == num)
- return current_port;
-
+ if (fif->mac_type == fman_mac_1g &&
+ pport->type != e_FM_PORT_TYPE_RX)
return -ENODEV;
- }
-
- if (fif->mac_type == fman_mac_2_5g) {
- if (pport->type != e_FM_PORT_TYPE_RX_2_5G)
- return -ENODEV;
- num = pport->number + DPAA_2_5G_MAC_START_IDX;
- if (fif->mac_idx == num)
- return current_port;
+ if (fif->mac_type == fman_mac_2_5g &&
+ pport->type != e_FM_PORT_TYPE_RX_2_5G)
return -ENODEV;
- }
-
- if (fif->mac_type == fman_mac_10g) {
- if (pport->type != e_FM_PORT_TYPE_RX_10G)
- return -ENODEV;
- num = pport->number + DPAA_10G_MAC_START_IDX;
- if (fif->mac_idx == num)
- return current_port;
+ if (fif->mac_type == fman_mac_10g &&
+ pport->type != e_FM_PORT_TYPE_RX_10G)
return -ENODEV;
- }
- DPAA_PMD_ERR("Invalid MAC(mac_idx=%d) type(%d)",
- fif->mac_idx, fif->mac_type);
+ if (fif->mac_idx == num)
+ return current_port;
- return -EINVAL;
+ return -ENODEV;
}
static int
--
2.25.1
^ permalink raw reply related
* [PATCH v7 12/16] bus/dpaa: improve log macro and fix bus detection
From: Hemant Agrawal @ 2026-07-03 12:49 UTC (permalink / raw)
To: stephen, david.marchand, dev
In-Reply-To: <20260703124950.1895871-1-hemant.agrawal@nxp.com>
Replace DPAA_BUS_LOG(LEVEL, ...) calls with shorthand macros
(DPAA_BUS_INFO, DPAA_BUS_ERR, DPAA_BUS_WARN, DPAA_BUS_DEBUG) for
consistency across the driver.
Make dpaa_bus_dev_compare() a pure comparator: move the sysfs path
check, dpaa_bus.detected assignment, and pthread_key_create() call
back to rte_dpaa_bus_scan() where they belong. Having side effects
in a comparator causes incorrect behavior when the function is called
multiple times -- it returns 0 (match) for all calls after the first.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/dpaa/base/fman/fman.c | 9 ++++-----
drivers/bus/dpaa/dpaa_bus.c | 12 ++++++------
2 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/drivers/bus/dpaa/base/fman/fman.c b/drivers/bus/dpaa/base/fman/fman.c
index 55f466d751..67f77265ca 100644
--- a/drivers/bus/dpaa/base/fman/fman.c
+++ b/drivers/bus/dpaa/base/fman/fman.c
@@ -119,7 +119,7 @@ _fman_init(const struct device_node *fman_node, int fd)
ip_rev_1 = in_be32((uint8_t *)fman->ccsr_vir + FMAN_IP_REV_1);
fman->ip_rev = ip_rev_1 >> FMAN_IP_REV_1_MAJOR_SHIFT;
fman->ip_rev &= FMAN_IP_REV_1_MAJOR_MASK;
- DPAA_BUS_LOG(NOTICE, "FMan version is 0x%02x", fman->ip_rev);
+ DPAA_BUS_INFO("FMan version is 0x%02x", fman->ip_rev);
if (fman->ip_rev >= FMAN_V3) {
/*
@@ -795,8 +795,7 @@ fman_if_init(const struct device_node *dpa_node, int fd)
fman_if_vsp_init(__if);
/* Parsing of the network interface is complete, add it to the list */
- DPAA_BUS_LOG(DEBUG, "Found %s, Tx Channel = %x, FMAN = %x,"
- "Port ID = %x",
+ DPAA_BUS_DEBUG("Found %s, Tx Channel = %x, FMAN = %x, Port ID = %x",
dname, __if->__if.tx_channel_id, __if->__if.fman->idx,
__if->__if.mac_idx);
@@ -1109,14 +1108,14 @@ fman_init(void)
fd = open(FMAN_DEVICE_PATH, O_RDWR);
if (unlikely(fd < 0)) {
- DPAA_BUS_LOG(ERR, "Unable to open %s: %s", FMAN_DEVICE_PATH, strerror(errno));
+ DPAA_BUS_ERR("Unable to open %s: %s", FMAN_DEVICE_PATH, strerror(errno));
return fd;
}
fman_ccsr_map_fd = fd;
parent_node = of_find_compatible_node(NULL, NULL, "fsl,dpaa");
if (!parent_node) {
- DPAA_BUS_LOG(ERR, "Unable to find fsl,dpaa node");
+ DPAA_BUS_ERR("Unable to find fsl,dpaa node");
return -ENODEV;
}
diff --git a/drivers/bus/dpaa/dpaa_bus.c b/drivers/bus/dpaa/dpaa_bus.c
index 54779f82f7..73a7e73a0b 100644
--- a/drivers/bus/dpaa/dpaa_bus.c
+++ b/drivers/bus/dpaa/dpaa_bus.c
@@ -54,6 +54,9 @@
/* At present we allow up to 4 push mode queues as default - as each of
* this queue need dedicated portal and we are short of portals.
*/
+#define DPAA_DEV_PATH1 "/sys/devices/platform/soc/soc:fsl,dpaa"
+#define DPAA_DEV_PATH2 "/sys/devices/platform/fsl,dpaa"
+
#define DPAA_MAX_PUSH_MODE_QUEUE 8
#define DPAA_DEFAULT_PUSH_MODE_QUEUE 4
@@ -667,8 +670,6 @@ static int rte_dpaa_setup_intr(struct rte_intr_handle *intr_handle)
return 0;
}
-#define DPAA_DEV_PATH1 "/sys/devices/platform/soc/soc:fsl,dpaa"
-#define DPAA_DEV_PATH2 "/sys/devices/platform/fsl,dpaa"
static int
rte_dpaa_bus_scan(void)
@@ -715,12 +716,11 @@ rte_dpaa_bus_scan(void)
dpaa_bus.svr_ver = 0;
}
if (dpaa_bus.svr_ver == SVR_LS1046A_FAMILY) {
- DPAA_BUS_LOG(INFO, "This is LS1046A family SoC.");
+ DPAA_BUS_INFO("This is LS1046A family SoC.");
} else if (dpaa_bus.svr_ver == SVR_LS1043A_FAMILY) {
- DPAA_BUS_LOG(INFO, "This is LS1043A family SoC.");
+ DPAA_BUS_INFO("This is LS1043A family SoC.");
} else {
- DPAA_BUS_LOG(WARNING,
- "This is Unknown(%08x) DPAA1 family SoC.",
+ DPAA_BUS_WARN("This is Unknown(%08x) DPAA1 family SoC.",
dpaa_bus.svr_ver);
}
--
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