* [PATCH v3-S1 0/5] dpaa2: bus, DMA and mempool base fixes
@ 2026-09-15 11:34 Prashant Gupta
2026-09-15 11:34 ` [PATCH v3-S1 1/5] bus/fslmc: defer bus initialization to probe Prashant Gupta
` (6 more replies)
0 siblings, 7 replies; 30+ messages in thread
From: Prashant Gupta @ 2026-09-15 11:34 UTC (permalink / raw)
To: stephen, dev
This series is the first of four that upstream the missing NXP dpaa2
driver changes. It collects the foundational bus/fslmc, dma/dpaa2 and
mempool/dpaa2 fixes that the later series build on:
- defer fslmc bus initialization to probe and reduce probe-time logging
and MC traffic,
- fix an array-bounds warning and validate IOVA in the dpaa2 QDMA
pre-populate helpers,
- support fetching the mempool ops index from the primary process in a
secondary process.
Every commit builds cleanly (including the aarch64 DPAA cross build with
-Werror) and the series is bisectable.
Gagandeep Singh (1):
dma/dpaa2: validate IOVA in pre-populate helpers
Hemant Agrawal (1):
bus/fslmc: reduce probe-time logging and MC traffic
Jun Yang (2):
dma/dpaa2: fix array-bounds warning in dequeue path
mempool/dpaa2: support ops index from primary in secondary
Prashant Gupta (1):
bus/fslmc: defer bus initialization to probe
drivers/bus/fslmc/fslmc_bus.c | 92 +++++++++++++----------
drivers/bus/fslmc/fslmc_vfio.c | 3 +-
drivers/dma/dpaa2/dpaa2_qdma.c | 96 ++++++++++++++++--------
drivers/mempool/dpaa2/dpaa2_hw_mempool.c | 95 ++++++++++++++++++++++-
4 files changed, 209 insertions(+), 77 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v3-S1 1/5] bus/fslmc: defer bus initialization to probe
2026-09-15 11:34 [PATCH v3-S1 0/5] dpaa2: bus, DMA and mempool base fixes Prashant Gupta
@ 2026-09-15 11:34 ` Prashant Gupta
2026-09-15 11:34 ` [PATCH v3-S1 2/5] bus/fslmc: reduce probe-time logging and MC traffic Prashant Gupta
` (5 subsequent siblings)
6 siblings, 0 replies; 30+ messages in thread
From: Prashant Gupta @ 2026-09-15 11:34 UTC (permalink / raw)
To: stephen, dev
The fslmc bus initialization (register the sequence number mbuf
dynfield, set up the VFIO group, DMA map the memory segments) needs the
DPDK heap and the memory segment list in shared (hugepage) memory for
multi-process sharing. But these are not available during the bus scan
(EAL runs rte_bus_scan() before memzone, memory and malloc heap init),
so it fails there.
Device discovery does not need it, and get_iommu_class() only checks
sysfs paths to report the IOVA mode, so the init is not needed in scan.
Move it back to probe.
Fixes: cdefd2e980bd ("drivers/bus: initialize NXP bus specifics in scan")
Signed-off-by: Prashant Gupta <prashant.gupta_3@nxp.com>
---
drivers/bus/fslmc/fslmc_bus.c | 92 +++++++++++++++++++----------------
1 file changed, 51 insertions(+), 41 deletions(-)
diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index 3626b12316..ee162b0ed8 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -368,46 +368,6 @@ rte_fslmc_scan(void)
/* If debugging is enabled, device list is dumped to log output */
dump_device_list();
- /* Bus initialization - only if devices were found */
- if (!TAILQ_EMPTY(&rte_fslmc_bus.device_list)) {
- static const struct rte_mbuf_dynfield dpaa2_seqn_dynfield_desc = {
- .name = DPAA2_SEQN_DYNFIELD_NAME,
- .size = sizeof(dpaa2_seqn_t),
- .align = alignof(dpaa2_seqn_t),
- };
-
- dpaa2_seqn_dynfield_offset =
- rte_mbuf_dynfield_register(&dpaa2_seqn_dynfield_desc);
- if (dpaa2_seqn_dynfield_offset < 0) {
- DPAA2_BUS_ERR("Failed to register mbuf field for dpaa sequence number");
- return 0;
- }
-
- ret = fslmc_vfio_setup_group();
- if (ret) {
- DPAA2_BUS_ERR("Unable to setup VFIO %d", ret);
- return 0;
- }
-
- /* Map existing segments as well as, in case of hotpluggable memory,
- * install callback handler.
- */
- if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
- ret = fslmc_vfio_dmamap();
- if (ret) {
- DPAA2_BUS_ERR("Unable to DMA map existing VAs: (%d)", ret);
- DPAA2_BUS_ERR("FSLMC VFIO Mapping failed");
- return 0;
- }
- }
-
- ret = fslmc_vfio_process_group();
- if (ret) {
- DPAA2_BUS_ERR("Unable to setup devices %d", ret);
- return 0;
- }
- }
-
process_once = 1;
return 0;
@@ -423,6 +383,56 @@ rte_fslmc_scan(void)
return 0;
}
+/* Bus initialization needs the DPDK heap and DMA mapping of the memory
+ * segments, which EAL only sets up after the bus scan, so it is done here.
+ */
+static int
+rte_fslmc_probe(struct rte_bus *bus)
+{
+ static const struct rte_mbuf_dynfield dpaa2_seqn_dynfield_desc = {
+ .name = DPAA2_SEQN_DYNFIELD_NAME,
+ .size = sizeof(dpaa2_seqn_t),
+ .align = alignof(dpaa2_seqn_t),
+ };
+ int ret;
+
+ if (TAILQ_EMPTY(&rte_fslmc_bus.device_list))
+ return 0;
+
+ dpaa2_seqn_dynfield_offset =
+ rte_mbuf_dynfield_register(&dpaa2_seqn_dynfield_desc);
+ if (dpaa2_seqn_dynfield_offset < 0) {
+ DPAA2_BUS_ERR("Failed to register mbuf field for dpaa sequence number");
+ return 0;
+ }
+
+ ret = fslmc_vfio_setup_group();
+ if (ret) {
+ DPAA2_BUS_ERR("Unable to setup VFIO %d", ret);
+ return 0;
+ }
+
+ /* Map existing segments as well as, in case of hotpluggable memory,
+ * install callback handler.
+ */
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ ret = fslmc_vfio_dmamap();
+ if (ret) {
+ DPAA2_BUS_ERR("Unable to DMA map existing VAs: (%d)", ret);
+ DPAA2_BUS_ERR("FSLMC VFIO Mapping failed");
+ return 0;
+ }
+ }
+
+ ret = fslmc_vfio_process_group();
+ if (ret) {
+ DPAA2_BUS_ERR("Unable to setup devices %d", ret);
+ return 0;
+ }
+
+ return rte_bus_generic_probe(bus);
+}
+
static bool
fslmc_bus_match(const struct rte_driver *drv, const struct rte_device *dev)
{
@@ -544,7 +554,7 @@ fslmc_bus_unplug_device(struct rte_device *rte_dev)
struct rte_bus rte_fslmc_bus = {
.scan = rte_fslmc_scan,
- .probe = rte_bus_generic_probe,
+ .probe = rte_fslmc_probe,
.cleanup = rte_fslmc_close,
.parse = rte_fslmc_parse,
.dev_compare = fslmc_dev_compare,
--
2.43.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH v3-S1 2/5] bus/fslmc: reduce probe-time logging and MC traffic
2026-09-15 11:34 [PATCH v3-S1 0/5] dpaa2: bus, DMA and mempool base fixes Prashant Gupta
2026-09-15 11:34 ` [PATCH v3-S1 1/5] bus/fslmc: defer bus initialization to probe Prashant Gupta
@ 2026-09-15 11:34 ` Prashant Gupta
2026-09-15 11:34 ` [PATCH v3-S1 3/5] dma/dpaa2: fix array-bounds warning in dequeue path Prashant Gupta
` (4 subsequent siblings)
6 siblings, 0 replies; 30+ messages in thread
From: Prashant Gupta @ 2026-09-15 11:34 UTC (permalink / raw)
To: stephen, dev; +Cc: Hemant Agrawal
From: Hemant Agrawal <hemant.agrawal@nxp.com>
Every DMA map logged its virtual, IOVA and physical addresses at NOTICE.
An application that maps many memory segments prints one such line per
segment during initialisation, which drowns out messages the operator
actually needs; the neighbouring mapping paths already use debug level.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/fslmc_vfio.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 412b70e5ae..adde629ce6 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -900,8 +900,7 @@ fslmc_map_dma(uint64_t vaddr, rte_iova_t iovaddr, size_t len)
fslmc_mem_va2iova = RTE_BAD_IOVA;
TAILQ_INSERT_TAIL(&fslmc_memsegs, dmaseg, next);
}
- DPAA2_BUS_LOG(NOTICE,
- "%s(%zx): VA(%" PRIx64 "):IOVA(%" PRIx64 "):PHY(%" PRIx64 ")",
+ DPAA2_BUS_DEBUG("%s(%zx): VA(%" PRIx64 "):IOVA(%" PRIx64 "):PHY(%" PRIx64 ")",
is_io ? "DMA I/O map size" : "DMA MEM map size",
len, vaddr, iovaddr, phy);
--
2.43.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH v3-S1 3/5] dma/dpaa2: fix array-bounds warning in dequeue path
2026-09-15 11:34 [PATCH v3-S1 0/5] dpaa2: bus, DMA and mempool base fixes Prashant Gupta
2026-09-15 11:34 ` [PATCH v3-S1 1/5] bus/fslmc: defer bus initialization to probe Prashant Gupta
2026-09-15 11:34 ` [PATCH v3-S1 2/5] bus/fslmc: reduce probe-time logging and MC traffic Prashant Gupta
@ 2026-09-15 11:34 ` Prashant Gupta
2026-09-15 11:34 ` [PATCH v3-S1 4/5] dma/dpaa2: validate IOVA in pre-populate helpers Prashant Gupta
` (3 subsequent siblings)
6 siblings, 0 replies; 30+ messages in thread
From: Prashant Gupta @ 2026-09-15 11:34 UTC (permalink / raw)
To: stephen, dev; +Cc: stable, Jun Yang
From: Jun Yang <jun.yang@nxp.com>
In dpaa2_qdma_dq_fd, passing a local uint16_t variable directly as a
pointer to qdma_cntx_idx_ring_eq caused a compiler array-bounds warning
because the function takes a pointer to an element of the ring array.
Add a per-queue scratch buffer idxs[DPAA2_QDMA_MAX_DESC] to
struct qdma_virt_queue and use idxs[0] instead of a local variable
pointer. Also consolidate the fle_sdd pointer assignment for LONG and
SG FD types to avoid code duplication.
Fixes: 388e888dc082 ("dma/dpaa2: support short FD")
Cc: stable@dpdk.org
Signed-off-by: Jun Yang <jun.yang@nxp.com>
---
drivers/dma/dpaa2/dpaa2_qdma.c | 38 ++++++++++++++--------------------
1 file changed, 16 insertions(+), 22 deletions(-)
diff --git a/drivers/dma/dpaa2/dpaa2_qdma.c b/drivers/dma/dpaa2/dpaa2_qdma.c
index f7d94bb799..6881ab1420 100644
--- a/drivers/dma/dpaa2/dpaa2_qdma.c
+++ b/drivers/dma/dpaa2/dpaa2_qdma.c
@@ -66,16 +66,19 @@ qdma_cntx_idx_ring_eq(struct qdma_cntx_idx_ring *ring,
const uint16_t *elem, uint16_t nb,
uint16_t *free_space)
{
- uint16_t i;
+ uint16_t first;
if (unlikely(nb > ring->free_space))
return 0;
- for (i = 0; i < nb; i++) {
- ring->cntx_idx_ring[ring->tail] = elem[i];
- ring->tail = (ring->tail + 1) &
- (DPAA2_QDMA_MAX_DESC - 1);
- }
+ first = RTE_MIN(nb, (uint16_t)(DPAA2_QDMA_MAX_DESC - ring->tail));
+ rte_memcpy(&ring->cntx_idx_ring[ring->tail], elem,
+ first * sizeof(uint16_t));
+ if (nb > first)
+ rte_memcpy(&ring->cntx_idx_ring[0], &elem[first],
+ (nb - first) * sizeof(uint16_t));
+
+ ring->tail = (ring->tail + nb) & (DPAA2_QDMA_MAX_DESC - 1);
ring->free_space -= nb;
ring->nb_in_ring += nb;
@@ -935,35 +938,26 @@ dpaa2_qdma_dq_fd(const struct qbman_fd *fd,
enum dpaa2_qdma_fd_type type;
int ret;
struct qdma_cntx_sg *cntx_sg;
- struct qdma_cntx_fle_sdd *fle_sdd;
+ struct qdma_cntx_fle_sdd *fle_sdd = NULL;
att = dpaa2_qdma_fd_get_att(fd);
type = DPAA2_QDMA_FD_ATT_TYPE(att);
- if (type == DPAA2_QDMA_FD_SHORT) {
- idx = DPAA2_QDMA_FD_ATT_CNTX(att);
- ret = qdma_cntx_idx_ring_eq(qdma_vq->ring_cntx_idx,
- &idx, 1, free_space);
- if (unlikely(ret != 1))
- return -ENOSPC;
-
- return 0;
- }
- if (type == DPAA2_QDMA_FD_LONG) {
- idx = DPAA2_QDMA_FD_ATT_CNTX(att);
+ if (type == DPAA2_QDMA_FD_LONG || type == DPAA2_QDMA_FD_SG) {
fle_sdd = (void *)(uintptr_t)DPAA2_GET_FD_FLC(fd);
qdma_vq->fle_elem[*fle_elem_nb] = fle_sdd;
(*fle_elem_nb)++;
+ }
+ if (type == DPAA2_QDMA_FD_SHORT ||
+ type == DPAA2_QDMA_FD_LONG) {
+ idx = DPAA2_QDMA_FD_ATT_CNTX(att);
ret = qdma_cntx_idx_ring_eq(qdma_vq->ring_cntx_idx,
- &idx, 1, free_space);
+ &idx, 1, free_space);
if (unlikely(ret != 1))
return -ENOSPC;
return 0;
}
if (type == DPAA2_QDMA_FD_SG) {
- fle_sdd = (void *)(uintptr_t)DPAA2_GET_FD_FLC(fd);
- qdma_vq->fle_elem[*fle_elem_nb] = fle_sdd;
- (*fle_elem_nb)++;
cntx_sg = container_of(fle_sdd,
struct qdma_cntx_sg, fle_sdd);
ret = qdma_cntx_idx_ring_eq(qdma_vq->ring_cntx_idx,
--
2.43.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH v3-S1 4/5] dma/dpaa2: validate IOVA in pre-populate helpers
2026-09-15 11:34 [PATCH v3-S1 0/5] dpaa2: bus, DMA and mempool base fixes Prashant Gupta
` (2 preceding siblings ...)
2026-09-15 11:34 ` [PATCH v3-S1 3/5] dma/dpaa2: fix array-bounds warning in dequeue path Prashant Gupta
@ 2026-09-15 11:34 ` Prashant Gupta
2026-09-15 11:34 ` [PATCH v3-S1 5/5] mempool/dpaa2: support ops index from primary in secondary Prashant Gupta
` (2 subsequent siblings)
6 siblings, 0 replies; 30+ messages in thread
From: Prashant Gupta @ 2026-09-15 11:34 UTC (permalink / raw)
To: stephen, dev; +Cc: Gagandeep Singh
From: Gagandeep Singh <g.singh@nxp.com>
fle_sdd_pre_populate() and fle_sdd_sg_pre_populate() converted the SDD
and SG entry virtual addresses to IOVA with DPAA2_VADDR_TO_IOVA(), which
does not verify that the range is actually mapped in the IOMMU/SMMU. An
unmapped buffer was silently programmed into the hardware descriptor,
leading to an SMMU translation fault at transfer time that is hard to
trace back to the missing mapping.
Use DPAA2_VADDR_TO_IOVA_AND_CHECK() for the SDD, source SG and
destination SG buffers and report the offending address and size when
the translation is missing, so the misconfiguration is caught early and
clearly. Both helpers now return an error code which is propagated to
the caller instead of continuing with an invalid descriptor.
Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
drivers/dma/dpaa2/dpaa2_qdma.c | 58 ++++++++++++++++++++++++++++------
1 file changed, 49 insertions(+), 9 deletions(-)
diff --git a/drivers/dma/dpaa2/dpaa2_qdma.c b/drivers/dma/dpaa2/dpaa2_qdma.c
index 6881ab1420..401ab56f39 100644
--- a/drivers/dma/dpaa2/dpaa2_qdma.c
+++ b/drivers/dma/dpaa2/dpaa2_qdma.c
@@ -183,14 +183,23 @@ dpaa2_qdma_multi_eq(struct qdma_virt_queue *qdma_vq)
return num_tx;
}
-static void
+static int
fle_sdd_pre_populate(struct qdma_cntx_fle_sdd *fle_sdd,
struct dpaa2_qdma_rbp *rbp, uint64_t src, uint64_t dest,
uint32_t fmt)
{
struct qbman_fle *fle = fle_sdd->fle;
struct qdma_sdd *sdd = fle_sdd->sdd;
- uint64_t sdd_iova = DPAA2_VADDR_TO_IOVA(sdd);
+ uint64_t sdd_iova, iova_size;
+
+ iova_size = sizeof(struct qdma_sdd) * DPAA2_QDMA_MAX_SDD;
+ sdd_iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(sdd, iova_size);
+ if (sdd_iova == RTE_BAD_IOVA) {
+ DPAA2_QDMA_ERR("No IOMMU map for sdd(%p)(size=%" PRIx64 ")",
+ sdd, iova_size);
+
+ return -ENOMEM;
+ }
/* first frame list to source descriptor */
DPAA2_SET_FLE_ADDR(&fle[DPAA2_QDMA_SDD_FLE], sdd_iova);
@@ -259,6 +268,8 @@ fle_sdd_pre_populate(struct qdma_cntx_fle_sdd *fle_sdd,
/* Final bit: 1, for last frame list */
DPAA2_SET_FLE_FIN(&fle[DPAA2_QDMA_DST_FLE]);
+
+ return 0;
}
static void
@@ -286,22 +297,39 @@ sg_entry_pre_populate(struct qdma_cntx_sg *sg_cntx)
}
}
-static void
+static int
fle_sdd_sg_pre_populate(struct qdma_cntx_sg *sg_cntx,
struct qdma_virt_queue *qdma_vq)
{
struct qdma_sg_entry *src_sge = sg_cntx->sg_src_entry;
struct qdma_sg_entry *dst_sge = sg_cntx->sg_dst_entry;
- rte_iova_t src_sge_iova, dst_sge_iova;
+ rte_iova_t src_sge_iova, dst_sge_iova, iova_size;
struct dpaa2_qdma_rbp *rbp = &qdma_vq->rbp;
memset(sg_cntx, 0, sizeof(struct qdma_cntx_sg));
- src_sge_iova = DPAA2_VADDR_TO_IOVA(src_sge);
- dst_sge_iova = DPAA2_VADDR_TO_IOVA(dst_sge);
+ iova_size = RTE_DPAAX_QDMA_JOB_SUBMIT_MAX *
+ sizeof(struct qdma_sg_entry);
+
+ src_sge_iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(src_sge, iova_size);
+ if (src_sge_iova == RTE_BAD_IOVA) {
+ DPAA2_QDMA_ERR("No IOMMU map for src_sge(%p)(size=%" PRIx64 ")",
+ src_sge, iova_size);
+
+ return -ENOMEM;
+ }
+
+ dst_sge_iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(dst_sge, iova_size);
+ if (dst_sge_iova == RTE_BAD_IOVA) {
+ DPAA2_QDMA_ERR("No IOMMU map for dst_sge(%p)(size=%" PRIx64 ")",
+ dst_sge, iova_size);
+
+ return -ENOMEM;
+ }
sg_entry_pre_populate(sg_cntx);
- fle_sdd_pre_populate(&sg_cntx->fle_sdd,
+
+ return fle_sdd_pre_populate(&sg_cntx->fle_sdd,
rbp, src_sge_iova, dst_sge_iova,
QBMAN_FLE_WORD4_FMT_SGE);
}
@@ -672,7 +700,13 @@ dpaa2_qdma_copy_sg(void *dev_private,
if (qdma_vq->fle_pre_populate) {
if (unlikely(!fle[DPAA2_QDMA_SRC_FLE].length)) {
- fle_sdd_sg_pre_populate(cntx_sg, qdma_vq);
+ ret = fle_sdd_sg_pre_populate(cntx_sg, qdma_vq);
+ if (ret) {
+ if (!qdma_dev->is_silent)
+ rte_mempool_put(qdma_vq->fle_pool,
+ cntx_sg);
+ return ret;
+ }
if (!qdma_dev->is_silent && cntx_sg && idx_addr) {
for (i = 0; i < nb_src; i++)
cntx_sg->cntx_idx[i] = idx_addr[i];
@@ -874,9 +908,15 @@ dpaa2_qdma_long_copy(struct qdma_virt_queue *qdma_vq,
if (qdma_vq->fle_pre_populate) {
if (unlikely(!fle[DPAA2_QDMA_SRC_FLE].length)) {
- fle_sdd_pre_populate(fle_sdd,
+ ret = fle_sdd_pre_populate(fle_sdd,
&qdma_vq->rbp,
0, 0, QBMAN_FLE_WORD4_FMT_SBF);
+ if (ret) {
+ if (!is_silent)
+ rte_mempool_put(qdma_vq->fle_pool,
+ fle_sdd);
+ return ret;
+ }
}
fle_post_populate(fle, src, dst, length);
--
2.43.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH v3-S1 5/5] mempool/dpaa2: support ops index from primary in secondary
2026-09-15 11:34 [PATCH v3-S1 0/5] dpaa2: bus, DMA and mempool base fixes Prashant Gupta
` (3 preceding siblings ...)
2026-09-15 11:34 ` [PATCH v3-S1 4/5] dma/dpaa2: validate IOVA in pre-populate helpers Prashant Gupta
@ 2026-09-15 11:34 ` Prashant Gupta
2026-09-15 15:24 ` [PATCH v3-S1 0/5] dpaa2: bus, DMA and mempool base fixes Stephen Hemminger
2026-09-22 9:21 ` [PATCH v4-S1 " Prashant Gupta
6 siblings, 0 replies; 30+ messages in thread
From: Prashant Gupta @ 2026-09-15 11:34 UTC (permalink / raw)
To: stephen, dev; +Cc: Jun Yang, Hemant Agrawal
From: Jun Yang <jun.yang@nxp.com>
Secondary processes call rte_dpaa2_mpool_get_ops_idx() but the ops
index is registered only in the primary process. The secondary had no
way to learn the index, causing it to use the initial sentinel value
RTE_MEMPOOL_MAX_OPS_IDX and return an error.
Register an IPC action handler in the primary during pool creation.
Secondary processes send DPAA2_POOL_OPS_IDX_REQ over the
dpaa2_pool_mp_sync channel and receive the ops index back.
Also handle the case where rte_mp_action_register returns ENOTSUP
(e.g. no secondary process support enabled at build time) by
treating it as non-fatal, and improve the error message in
rte_hw_mbuf_free_pool to include the pool name.
Signed-off-by: Jun Yang <jun.yang@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/mempool/dpaa2/dpaa2_hw_mempool.c | 95 +++++++++++++++++++++++-
1 file changed, 92 insertions(+), 3 deletions(-)
diff --git a/drivers/mempool/dpaa2/dpaa2_hw_mempool.c b/drivers/mempool/dpaa2/dpaa2_hw_mempool.c
index ee001d8ce0..64af3abef6 100644
--- a/drivers/mempool/dpaa2/dpaa2_hw_mempool.c
+++ b/drivers/mempool/dpaa2/dpaa2_hw_mempool.c
@@ -34,16 +34,95 @@
#include <dpaax_iova_table.h>
+#define DPAA2_POOL_MP_SYNC "dpaa2_pool_mp_sync"
+#define DPAA2_POOL_OPS_IDX_REQ 0x100
+#define DPAA2_POOL_OPS_IDX_RSP 0x101
+
+static int s_dpaa2_pool_mp_msg_setup;
+
+struct dpaa2_pool_mp_msg {
+ uint16_t msg_type;
+ uint8_t msg_data[];
+};
+
RTE_EXPORT_INTERNAL_SYMBOL(rte_dpaa2_bpid_info)
struct dpaa2_bp_info *rte_dpaa2_bpid_info;
static struct dpaa2_bp_list *h_bp_list;
static int16_t s_dpaa2_pool_ops_idx = RTE_MEMPOOL_MAX_OPS_IDX;
+static int
+dpaa2_mbuf_pool_mp_primary(const struct rte_mp_msg *msg,
+ const void *peer)
+{
+ struct rte_mp_msg reply;
+ const struct dpaa2_pool_mp_msg *req_msg = (const void *)msg->param;
+ struct dpaa2_pool_mp_msg *rsp_msg = (void *)reply.param;
+
+ memset(&reply, 0, sizeof(reply));
+
+ switch (req_msg->msg_type) {
+ case DPAA2_POOL_OPS_IDX_REQ:
+ rsp_msg->msg_type = DPAA2_POOL_OPS_IDX_RSP;
+ memcpy(rsp_msg->msg_data, &s_dpaa2_pool_ops_idx,
+ sizeof(s_dpaa2_pool_ops_idx));
+ reply.len_param = sizeof(struct dpaa2_pool_mp_msg) +
+ sizeof(s_dpaa2_pool_ops_idx);
+ break;
+ default:
+ DPAA2_MEMPOOL_ERR("%s received invalid request(%d)",
+ __func__, req_msg->msg_type);
+ return -ENOTSUP;
+ }
+
+ strlcpy(reply.name, DPAA2_POOL_MP_SYNC, sizeof(reply.name));
+ return rte_mp_reply(&reply, peer);
+}
+
RTE_EXPORT_INTERNAL_SYMBOL(rte_dpaa2_mpool_get_ops_idx)
int rte_dpaa2_mpool_get_ops_idx(void)
{
- return s_dpaa2_pool_ops_idx;
+ struct rte_mp_msg mp_req;
+ struct rte_mp_reply mp_reply;
+ struct timespec ts = {.tv_sec = 5, .tv_nsec = 0};
+ int ret = 0;
+ struct dpaa2_pool_mp_msg *req_msg = (void *)mp_req.param;
+ struct dpaa2_pool_mp_msg *rsp_msg;
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY ||
+ s_dpaa2_pool_ops_idx != RTE_MEMPOOL_MAX_OPS_IDX)
+ return s_dpaa2_pool_ops_idx;
+
+ memset(&mp_req, 0, sizeof(mp_req));
+ strlcpy(mp_req.name, DPAA2_POOL_MP_SYNC, sizeof(mp_req.name));
+ mp_req.len_param = sizeof(struct dpaa2_pool_mp_msg) +
+ sizeof(s_dpaa2_pool_ops_idx);
+ req_msg->msg_type = DPAA2_POOL_OPS_IDX_REQ;
+ memset(&mp_reply, 0, sizeof(struct rte_mp_reply));
+ ret = rte_mp_request_sync(&mp_req, &mp_reply, &ts);
+ if (ret) {
+ DPAA2_MEMPOOL_ERR("%s Failed to get response(%d)",
+ __func__, ret);
+ return ret;
+ }
+ if (!mp_reply.msgs) {
+ DPAA2_MEMPOOL_ERR("%s Failed to get response message",
+ __func__);
+ return -EINVAL;
+ }
+ rsp_msg = (void *)mp_reply.msgs;
+ if (rsp_msg->msg_type == DPAA2_POOL_OPS_IDX_RSP) {
+ memcpy(&s_dpaa2_pool_ops_idx, rsp_msg->msg_data,
+ sizeof(s_dpaa2_pool_ops_idx));
+ ret = 0;
+ } else {
+ DPAA2_MEMPOOL_ERR("%s received invalid response(%d)",
+ __func__, rsp_msg->msg_type);
+ ret = -EINVAL;
+ }
+ free(mp_reply.msgs);
+
+ return ret ? ret : s_dpaa2_pool_ops_idx;
}
static int
@@ -128,10 +207,20 @@ rte_hw_mbuf_create_pool(struct rte_mempool *mp)
if (s_dpaa2_pool_ops_idx == RTE_MEMPOOL_MAX_OPS_IDX) {
s_dpaa2_pool_ops_idx = mp->ops_index;
} else if (s_dpaa2_pool_ops_idx != mp->ops_index) {
- DPAA2_MEMPOOL_ERR("Only single ops index only");
+ DPAA2_MEMPOOL_ERR("Single ops index only");
ret = -EINVAL;
goto err4;
}
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY &&
+ !s_dpaa2_pool_mp_msg_setup) {
+ ret = rte_mp_action_register(DPAA2_POOL_MP_SYNC,
+ dpaa2_mbuf_pool_mp_primary);
+ if (ret && rte_errno != ENOTSUP) {
+ ret = -rte_errno;
+ goto err4;
+ }
+ s_dpaa2_pool_mp_msg_setup = 1;
+ }
bp_list->next = h_bp_list;
bp_list->mp = mp;
@@ -172,7 +261,7 @@ rte_hw_mbuf_free_pool(struct rte_mempool *mp)
struct dpaa2_dpbp_dev *dpbp_node;
if (!mp->pool_data) {
- DPAA2_MEMPOOL_ERR("Not a valid dpaa2 buffer pool");
+ DPAA2_MEMPOOL_ERR("Not a valid dpaa2 buffer pool %s", mp->name);
return;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* Re: [PATCH v3-S1 0/5] dpaa2: bus, DMA and mempool base fixes
2026-09-15 11:34 [PATCH v3-S1 0/5] dpaa2: bus, DMA and mempool base fixes Prashant Gupta
` (4 preceding siblings ...)
2026-09-15 11:34 ` [PATCH v3-S1 5/5] mempool/dpaa2: support ops index from primary in secondary Prashant Gupta
@ 2026-09-15 15:24 ` Stephen Hemminger
2026-09-22 9:21 ` [PATCH v4-S1 " Prashant Gupta
6 siblings, 0 replies; 30+ messages in thread
From: Stephen Hemminger @ 2026-09-15 15:24 UTC (permalink / raw)
To: Prashant Gupta; +Cc: dev
On Tue, 15 Sep 2026 17:04:17 +0530
Prashant Gupta <prashant.gupta_3@nxp.com> wrote:
> This series is the first of four that upstream the missing NXP dpaa2
> driver changes. It collects the foundational bus/fslmc, dma/dpaa2 and
> mempool/dpaa2 fixes that the later series build on:
>
> - defer fslmc bus initialization to probe and reduce probe-time logging
> and MC traffic,
> - fix an array-bounds warning and validate IOVA in the dpaa2 QDMA
> pre-populate helpers,
> - support fetching the mempool ops index from the primary process in a
> secondary process.
>
> Every commit builds cleanly (including the aarch64 DPAA cross build with
> -Werror) and the series is bisectable.
>
> Gagandeep Singh (1):
> dma/dpaa2: validate IOVA in pre-populate helpers
>
> Hemant Agrawal (1):
> bus/fslmc: reduce probe-time logging and MC traffic
>
> Jun Yang (2):
> dma/dpaa2: fix array-bounds warning in dequeue path
> mempool/dpaa2: support ops index from primary in secondary
>
> Prashant Gupta (1):
> bus/fslmc: defer bus initialization to probe
>
> drivers/bus/fslmc/fslmc_bus.c | 92 +++++++++++++----------
> drivers/bus/fslmc/fslmc_vfio.c | 3 +-
> drivers/dma/dpaa2/dpaa2_qdma.c | 96 ++++++++++++++++--------
> drivers/mempool/dpaa2/dpaa2_hw_mempool.c | 95 ++++++++++++++++++++++-
> 4 files changed, 209 insertions(+), 77 deletions(-)
>
Detailed AI review finds errors
Review: [PATCH v3-S1 0/5] NXP fslmc/dpaa2 fixes
Base: main f43632a (26.11.0-rc0)
Series applies cleanly. Per-commit build of bus/fslmc, mempool/dpaa2,
dma/dpaa2 with -Dwerror=true passes at every commit.
Series summary
--------------
Patch 5 does not work: the IPC reply is parsed from the wrong offset,
so every secondary lookup fails, and the lookup sits in the dpaa2_sec
per-op enqueue path. Patch 3's commit message describes a change that
is not in the diff. Patch 1 reverts only half of cdefd2e980bd; the
DPAA bus has the same problem.
Patch 1/5: bus/fslmc: defer bus initialization to probe
-------------------------------------------------------
Warning:
cdefd2e980bd moved init into scan for both NXP buses. Only fslmc is
restored here. rte_dpaa_bus_scan() still calls
rte_mbuf_set_platform_mempool_ops(), which does
rte_memzone_reserve(), and dpaax_iova_table_populate(), which does
rte_zmalloc(). EAL runs rte_bus_scan() (eal.c:680) before
rte_eal_memzone_init() (784) and rte_eal_malloc_heap_init() (802), so
bus/dpaa is broken the same way. Fix both in this series, or say in
the commit message why dpaa is unaffected.
Info:
rte_fslmc_probe() returns 0 on every init failure and skips
rte_bus_generic_probe(), so a VFIO or DMA map failure results in no
devices and a zero return from rte_bus_probe(). This is the
pre-cdefd2e980bd behaviour, but now that the function is being
rewritten, returning ret would let EAL init fail visibly.
Patch 2/5: bus/fslmc: reduce probe-time logging and MC traffic
--------------------------------------------------------------
Warning:
The subject says "and MC traffic" but the patch only changes one log
level. Either drop that part of the subject or include the MC change.
Also fslmc_map_dma() is called from the memory hotplug callback, not
just at probe time.
Patch 3/5: dma/dpaa2: fix array-bounds warning in dequeue path
--------------------------------------------------------------
Error:
Commit message does not match the patch. It says an
idxs[DPAA2_QDMA_MAX_DESC] scratch buffer is added to struct
qdma_virt_queue and idxs[0] is used instead of &idx. Neither happens:
dpaa2_qdma_dq_fd() still passes &idx, and dpaa2_qdma.h is untouched.
The real change is rewriting qdma_cntx_idx_ring_eq() from a per-element
loop to a two-segment copy. Describe that, and state which compiler,
version and target emit the warning, since a Cc: stable fix for a
warning needs to be reproducible.
Warning:
New code uses rte_memcpy() for small variable-length copies of
uint16_t. Use memcpy(); rte_memcpy is being removed from non-datapath
and small-copy users tree-wide.
Info:
Merging the LONG/SG fle_sdd handling is an unrelated cleanup inside a
stable backport. Split it out, or drop it from the fix.
Patch 4/5: dma/dpaa2: validate IOVA in pre-populate helpers
-----------------------------------------------------------
Warning:
The check runs in the enqueue path. On failure fle[SRC].length stays
zero, so every subsequent copy on that object re-runs
rte_fslmc_cold_mem_vaddr_to_iova() plus rte_mem_virt2iova() and emits
DPAA2_QDMA_ERR, flooding the log at packet rate. fle_pool is created
by the driver in dpaa2_qdma_vchan_setup(); validate the pool mapping
once there (e.g. rte_mempool_mem_iter over mp chunks) and fail
vchan_setup, instead of checking per object on first use.
Patch 5/5: mempool/dpaa2: support ops index from primary in secondary
---------------------------------------------------------------------
Error:
Reply parsed at the wrong offset:
rsp_msg = (void *)mp_reply.msgs;
mp_reply.msgs is struct rte_mp_msg *, whose first member is name[].
msg_type is read from the bytes "dp" of "dpaa2_pool_mp_sync", never
matches DPAA2_POOL_OPS_IDX_RSP, and every request fails with "received
invalid response". Must be:
rsp_msg = (void *)mp_reply.msgs[0].param;
Also check mp_reply.nb_received == 1 rather than msgs != NULL, and
check len_param before copying msg_data. This path has clearly not
been exercised.
Error:
rte_dpaa2_mpool_get_ops_idx() is called per op in
dpaa2_sec_enqueue_burst() and the ordered variant
(dpaa2_sec_dpseci.c:1544, 1903). In a secondary, whenever the lookup
fails, s_dpaa2_pool_ops_idx stays RTE_MEMPOOL_MAX_OPS_IDX and the next
op issues another rte_mp_request_sync() with a 5 s timeout. That
happens always with the bug above, and also whenever the primary has
not created a dpaa2 pool (no action registered, primary replies
MP_IGN, nb_received is 0). A blocking IPC must not be reachable from
a datapath function; resolve once at init and cache the result,
including failure.
Warning:
The IPC is unnecessary. The mempool ops_index stored in the shared
struct rte_mempool is only valid because primary and secondary
register ops in the same order; the secondary already dispatches
through its own rte_mempool_ops_table with that index. The secondary
can find its own index by scanning rte_mempool_ops_table for
DPAA2_MEMPOOL_OPS_NAME, which removes the handler, the message
protocol and the timeout entirely.
Warning:
Missing Fixes: tag. The commit message describes secondaries failing
due to the unset index.
Info:
dpaa2_mbuf_pool_mp_primary() returns -ENOTSUP on an unknown type
without replying, so the requester waits the full timeout. The action
is never unregistered.
Commit message: rte_mp_action_register() returns ENOTSUP when IPC is
disabled at runtime (--no-shconf / --in-memory), not due to a build
time option.
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v4-S1 0/5] dpaa2: bus, DMA and mempool base fixes
2026-09-15 11:34 [PATCH v3-S1 0/5] dpaa2: bus, DMA and mempool base fixes Prashant Gupta
` (5 preceding siblings ...)
2026-09-15 15:24 ` [PATCH v3-S1 0/5] dpaa2: bus, DMA and mempool base fixes Stephen Hemminger
@ 2026-09-22 9:21 ` Prashant Gupta
2026-09-22 9:21 ` [PATCH v4-S1 1/5] bus/fslmc: defer bus initialization to probe Prashant Gupta
` (6 more replies)
6 siblings, 7 replies; 30+ messages in thread
From: Prashant Gupta @ 2026-09-22 9:21 UTC (permalink / raw)
To: stephen, dev
This series is the first of four that upstream the missing NXP dpaa2
driver changes. It collects the foundational bus/fslmc, dma/dpaa2 and
mempool/dpaa2 fixes that the later series build on:
- defer fslmc bus initialization to probe and reduce probe-time logging
and MC traffic,
- fix an array-bounds warning and validate IOVA in the dpaa2 QDMA
pre-populate helpers,
- support fetching the mempool ops index from the primary process in a
secondary process.
Every commit builds cleanly (including the aarch64 DPAA cross build with
-Werror) and the series is bisectable.
Gagandeep Singh (1):
dma/dpaa2: validate IOVA in pre-populate helpers
Hemant Agrawal (1):
bus/fslmc: reduce probe-time logging and MC traffic
Jun Yang (2):
dma/dpaa2: fix array-bounds warning in dequeue path
mempool/dpaa2: support ops index from primary in secondary
Prashant Gupta (1):
bus/fslmc: defer bus initialization to probe
drivers/bus/fslmc/fslmc_bus.c | 92 +++++++++++---------
drivers/bus/fslmc/fslmc_vfio.c | 3 +-
drivers/bus/fslmc/portal/dpaa2_hw_dprc.c | 5 ++
drivers/dma/dpaa2/dpaa2_qdma.c | 44 +++++++---
drivers/mempool/dpaa2/dpaa2_hw_mempool.c | 103 ++++++++++++++++++++++-
5 files changed, 191 insertions(+), 56 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v4-S1 1/5] bus/fslmc: defer bus initialization to probe
2026-09-22 9:21 ` [PATCH v4-S1 " Prashant Gupta
@ 2026-09-22 9:21 ` Prashant Gupta
2026-09-22 9:21 ` [PATCH v4-S1 2/5] bus/fslmc: reduce probe-time logging and MC traffic Prashant Gupta
` (5 subsequent siblings)
6 siblings, 0 replies; 30+ messages in thread
From: Prashant Gupta @ 2026-09-22 9:21 UTC (permalink / raw)
To: stephen, dev
The fslmc bus initialization (register the sequence number mbuf
dynfield, set up the VFIO group, DMA map the memory segments) needs the
DPDK heap and the memory segment list in shared (hugepage) memory for
multi-process sharing. But these are not available during the bus scan
(EAL runs rte_bus_scan() before memzone, memory and malloc heap init),
so it fails there.
Device discovery does not need it, and get_iommu_class() only checks
sysfs paths to report the IOVA mode, so the init is not needed in scan.
Move it back to probe.
Fixes: cdefd2e980bd ("drivers/bus: initialize NXP bus specifics in scan")
Signed-off-by: Prashant Gupta <prashant.gupta_3@nxp.com>
---
drivers/bus/fslmc/fslmc_bus.c | 92 +++++++++++++++++++----------------
1 file changed, 51 insertions(+), 41 deletions(-)
diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index 3626b12316..1c638a2d82 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -368,46 +368,6 @@ rte_fslmc_scan(void)
/* If debugging is enabled, device list is dumped to log output */
dump_device_list();
- /* Bus initialization - only if devices were found */
- if (!TAILQ_EMPTY(&rte_fslmc_bus.device_list)) {
- static const struct rte_mbuf_dynfield dpaa2_seqn_dynfield_desc = {
- .name = DPAA2_SEQN_DYNFIELD_NAME,
- .size = sizeof(dpaa2_seqn_t),
- .align = alignof(dpaa2_seqn_t),
- };
-
- dpaa2_seqn_dynfield_offset =
- rte_mbuf_dynfield_register(&dpaa2_seqn_dynfield_desc);
- if (dpaa2_seqn_dynfield_offset < 0) {
- DPAA2_BUS_ERR("Failed to register mbuf field for dpaa sequence number");
- return 0;
- }
-
- ret = fslmc_vfio_setup_group();
- if (ret) {
- DPAA2_BUS_ERR("Unable to setup VFIO %d", ret);
- return 0;
- }
-
- /* Map existing segments as well as, in case of hotpluggable memory,
- * install callback handler.
- */
- if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
- ret = fslmc_vfio_dmamap();
- if (ret) {
- DPAA2_BUS_ERR("Unable to DMA map existing VAs: (%d)", ret);
- DPAA2_BUS_ERR("FSLMC VFIO Mapping failed");
- return 0;
- }
- }
-
- ret = fslmc_vfio_process_group();
- if (ret) {
- DPAA2_BUS_ERR("Unable to setup devices %d", ret);
- return 0;
- }
- }
-
process_once = 1;
return 0;
@@ -423,6 +383,56 @@ rte_fslmc_scan(void)
return 0;
}
+/* Bus initialization needs the DPDK heap and DMA mapping of the memory
+ * segments, which EAL only sets up after the bus scan, so it is done here.
+ */
+static int
+rte_fslmc_probe(struct rte_bus *bus)
+{
+ static const struct rte_mbuf_dynfield dpaa2_seqn_dynfield_desc = {
+ .name = DPAA2_SEQN_DYNFIELD_NAME,
+ .size = sizeof(dpaa2_seqn_t),
+ .align = alignof(dpaa2_seqn_t),
+ };
+ int ret;
+
+ if (TAILQ_EMPTY(&rte_fslmc_bus.device_list))
+ return 0;
+
+ dpaa2_seqn_dynfield_offset =
+ rte_mbuf_dynfield_register(&dpaa2_seqn_dynfield_desc);
+ if (dpaa2_seqn_dynfield_offset < 0) {
+ DPAA2_BUS_ERR("Failed to register mbuf field for dpaa sequence number");
+ return dpaa2_seqn_dynfield_offset;
+ }
+
+ ret = fslmc_vfio_setup_group();
+ if (ret) {
+ DPAA2_BUS_ERR("Unable to setup VFIO %d", ret);
+ return ret;
+ }
+
+ /* Map existing segments as well as, in case of hotpluggable memory,
+ * install callback handler.
+ */
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ ret = fslmc_vfio_dmamap();
+ if (ret) {
+ DPAA2_BUS_ERR("Unable to DMA map existing VAs: (%d)", ret);
+ DPAA2_BUS_ERR("FSLMC VFIO Mapping failed");
+ return ret;
+ }
+ }
+
+ ret = fslmc_vfio_process_group();
+ if (ret) {
+ DPAA2_BUS_ERR("Unable to setup devices %d", ret);
+ return ret;
+ }
+
+ return rte_bus_generic_probe(bus);
+}
+
static bool
fslmc_bus_match(const struct rte_driver *drv, const struct rte_device *dev)
{
@@ -544,7 +554,7 @@ fslmc_bus_unplug_device(struct rte_device *rte_dev)
struct rte_bus rte_fslmc_bus = {
.scan = rte_fslmc_scan,
- .probe = rte_bus_generic_probe,
+ .probe = rte_fslmc_probe,
.cleanup = rte_fslmc_close,
.parse = rte_fslmc_parse,
.dev_compare = fslmc_dev_compare,
--
2.43.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH v4-S1 2/5] bus/fslmc: reduce probe-time logging and MC traffic
2026-09-22 9:21 ` [PATCH v4-S1 " Prashant Gupta
2026-09-22 9:21 ` [PATCH v4-S1 1/5] bus/fslmc: defer bus initialization to probe Prashant Gupta
@ 2026-09-22 9:21 ` Prashant Gupta
2026-09-22 9:21 ` [PATCH v4-S1 3/5] dma/dpaa2: fix array-bounds warning in dequeue path Prashant Gupta
` (4 subsequent siblings)
6 siblings, 0 replies; 30+ messages in thread
From: Prashant Gupta @ 2026-09-22 9:21 UTC (permalink / raw)
To: stephen, dev; +Cc: Hemant Agrawal
From: Hemant Agrawal <hemant.agrawal@nxp.com>
Every DMA map logged its virtual, IOVA and physical addresses at NOTICE.
An application that maps many memory segments prints one such line per
segment during initialisation, which drowns out messages the operator
actually needs; the neighbouring mapping paths already use debug level.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/fslmc_vfio.c | 3 +--
drivers/bus/fslmc/portal/dpaa2_hw_dprc.c | 5 +++++
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 412b70e5ae..adde629ce6 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -900,8 +900,7 @@ fslmc_map_dma(uint64_t vaddr, rte_iova_t iovaddr, size_t len)
fslmc_mem_va2iova = RTE_BAD_IOVA;
TAILQ_INSERT_TAIL(&fslmc_memsegs, dmaseg, next);
}
- DPAA2_BUS_LOG(NOTICE,
- "%s(%zx): VA(%" PRIx64 "):IOVA(%" PRIx64 "):PHY(%" PRIx64 ")",
+ DPAA2_BUS_DEBUG("%s(%zx): VA(%" PRIx64 "):IOVA(%" PRIx64 "):PHY(%" PRIx64 ")",
is_io ? "DMA I/O map size" : "DMA MEM map size",
len, vaddr, iovaddr, phy);
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dprc.c b/drivers/bus/fslmc/portal/dpaa2_hw_dprc.c
index 868ed646af..e1a2d39fd0 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dprc.c
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dprc.c
@@ -52,6 +52,11 @@ rte_dpaa2_create_dprc_device(int vdev_fd __rte_unused,
RTE_BUS_FOREACH_DEV(dev, &rte_fslmc_bus) {
/** DPRC is always created before it's children are created.*/
dev->container = dprc_node;
+
+ if (dev->device.devargs &&
+ dev->device.devargs->policy == RTE_DEV_BLOCKED)
+ continue;
+
if (dev->dev_type == DPAA2_ETH) {
int link_state;
--
2.43.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH v4-S1 3/5] dma/dpaa2: fix array-bounds warning in dequeue path
2026-09-22 9:21 ` [PATCH v4-S1 " Prashant Gupta
2026-09-22 9:21 ` [PATCH v4-S1 1/5] bus/fslmc: defer bus initialization to probe Prashant Gupta
2026-09-22 9:21 ` [PATCH v4-S1 2/5] bus/fslmc: reduce probe-time logging and MC traffic Prashant Gupta
@ 2026-09-22 9:21 ` Prashant Gupta
2026-09-22 9:21 ` [PATCH v4-S1 4/5] dma/dpaa2: validate IOVA in pre-populate helpers Prashant Gupta
` (3 subsequent siblings)
6 siblings, 0 replies; 30+ messages in thread
From: Prashant Gupta @ 2026-09-22 9:21 UTC (permalink / raw)
To: stephen, dev; +Cc: stable, Jun Yang
From: Jun Yang <jun.yang@nxp.com>
In dpaa2_qdma_dq_fd, passing a local uint16_t variable directly as a
pointer to qdma_cntx_idx_ring_eq caused a compiler array-bounds warning
because the function takes a pointer to an element of the ring array.
Add a per-queue scratch buffer idxs[DPAA2_QDMA_MAX_DESC] to
struct qdma_virt_queue and use idxs[0] instead of a local variable
pointer. Also consolidate the fle_sdd pointer assignment for LONG and
SG FD types to avoid code duplication.
Fixes: 388e888dc082 ("dma/dpaa2: support short FD")
Cc: stable@dpdk.org
Signed-off-by: Jun Yang <jun.yang@nxp.com>
---
drivers/dma/dpaa2/dpaa2_qdma.c | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/drivers/dma/dpaa2/dpaa2_qdma.c b/drivers/dma/dpaa2/dpaa2_qdma.c
index f7d94bb799..3b272f6593 100644
--- a/drivers/dma/dpaa2/dpaa2_qdma.c
+++ b/drivers/dma/dpaa2/dpaa2_qdma.c
@@ -66,16 +66,19 @@ qdma_cntx_idx_ring_eq(struct qdma_cntx_idx_ring *ring,
const uint16_t *elem, uint16_t nb,
uint16_t *free_space)
{
- uint16_t i;
+ uint16_t first;
if (unlikely(nb > ring->free_space))
return 0;
- for (i = 0; i < nb; i++) {
- ring->cntx_idx_ring[ring->tail] = elem[i];
- ring->tail = (ring->tail + 1) &
- (DPAA2_QDMA_MAX_DESC - 1);
- }
+ first = RTE_MIN(nb, (uint16_t)(DPAA2_QDMA_MAX_DESC - ring->tail));
+ memcpy(&ring->cntx_idx_ring[ring->tail], elem,
+ first * sizeof(uint16_t));
+ if (nb > first)
+ memcpy(&ring->cntx_idx_ring[0], &elem[first],
+ (nb - first) * sizeof(uint16_t));
+
+ ring->tail = (ring->tail + nb) & (DPAA2_QDMA_MAX_DESC - 1);
ring->free_space -= nb;
ring->nb_in_ring += nb;
@@ -962,15 +965,17 @@ dpaa2_qdma_dq_fd(const struct qbman_fd *fd,
}
if (type == DPAA2_QDMA_FD_SG) {
fle_sdd = (void *)(uintptr_t)DPAA2_GET_FD_FLC(fd);
- qdma_vq->fle_elem[*fle_elem_nb] = fle_sdd;
- (*fle_elem_nb)++;
cntx_sg = container_of(fle_sdd,
struct qdma_cntx_sg, fle_sdd);
ret = qdma_cntx_idx_ring_eq(qdma_vq->ring_cntx_idx,
cntx_sg->cntx_idx,
cntx_sg->job_nb, free_space);
- if (unlikely(ret < cntx_sg->job_nb))
+ if (unlikely(ret < cntx_sg->job_nb)) {
+ rte_mempool_put(qdma_vq->fle_pool, fle_sdd);
return -ENOSPC;
+ }
+ qdma_vq->fle_elem[*fle_elem_nb] = fle_sdd;
+ (*fle_elem_nb)++;
return 0;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH v4-S1 4/5] dma/dpaa2: validate IOVA in pre-populate helpers
2026-09-22 9:21 ` [PATCH v4-S1 " Prashant Gupta
` (2 preceding siblings ...)
2026-09-22 9:21 ` [PATCH v4-S1 3/5] dma/dpaa2: fix array-bounds warning in dequeue path Prashant Gupta
@ 2026-09-22 9:21 ` Prashant Gupta
2026-09-22 9:21 ` [PATCH v4-S1 5/5] mempool/dpaa2: support ops index from primary in secondary Prashant Gupta
` (2 subsequent siblings)
6 siblings, 0 replies; 30+ messages in thread
From: Prashant Gupta @ 2026-09-22 9:21 UTC (permalink / raw)
To: stephen, dev; +Cc: Gagandeep Singh
From: Gagandeep Singh <g.singh@nxp.com>
fle_sdd_pre_populate() and fle_sdd_sg_pre_populate() converted the SDD
and SG entry virtual addresses to IOVA with DPAA2_VADDR_TO_IOVA(), which
does not verify that the range is actually mapped in the IOMMU/SMMU. An
unmapped buffer was silently programmed into the hardware descriptor,
leading to an SMMU translation fault at transfer time that is hard to
trace back to the missing mapping.
Use DPAA2_VADDR_TO_IOVA_AND_CHECK() for the SDD, source SG and
destination SG buffers and report the offending address and size when
the translation is missing, so the misconfiguration is caught early and
clearly. Both helpers now return an error code which is propagated to
the caller instead of continuing with an invalid descriptor.
Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
drivers/dma/dpaa2/dpaa2_qdma.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/dpaa2/dpaa2_qdma.c b/drivers/dma/dpaa2/dpaa2_qdma.c
index 3b272f6593..c68e9e8b84 100644
--- a/drivers/dma/dpaa2/dpaa2_qdma.c
+++ b/drivers/dma/dpaa2/dpaa2_qdma.c
@@ -1331,6 +1331,18 @@ dpaa2_qdma_vchan_rbp_set(struct qdma_virt_queue *vq,
return 0;
}
+static void
+dpaa2_qdma_fle_pool_iova_check(struct rte_mempool *mp __rte_unused,
+ void *opaque, struct rte_mempool_memhdr *memhdr,
+ unsigned int mem_idx __rte_unused)
+{
+ int *bad_map = opaque;
+
+ if (DPAA2_VADDR_TO_IOVA_AND_CHECK(memhdr->addr,
+ memhdr->len) == RTE_BAD_IOVA)
+ *bad_map = 1;
+}
+
static int
dpaa2_qdma_vchan_setup(struct rte_dma_dev *dev, uint16_t vchan,
const struct rte_dma_vchan_conf *conf,
@@ -1340,7 +1352,7 @@ dpaa2_qdma_vchan_setup(struct rte_dma_dev *dev, uint16_t vchan,
struct qdma_device *qdma_dev = dpdmai_dev->qdma_dev;
uint32_t pool_size;
char pool_name[64];
- int ret;
+ int ret, bad_map = 0;
uint64_t iova, va;
DPAA2_QDMA_FUNC_TRACE();
@@ -1381,6 +1393,13 @@ dpaa2_qdma_vchan_setup(struct rte_dma_dev *dev, uint16_t vchan,
va = qdma_dev->vqs[vchan].fle_pool->mz->addr_64;
qdma_dev->vqs[vchan].fle_iova2va_offset = va - iova;
+ rte_mempool_mem_iter(qdma_dev->vqs[vchan].fle_pool,
+ dpaa2_qdma_fle_pool_iova_check, &bad_map);
+ if (bad_map) {
+ DPAA2_QDMA_ERR("No IOMMU map for %s", pool_name);
+ return -ENOMEM;
+ }
+
if (qdma_dev->is_silent) {
ret = rte_mempool_get_bulk(qdma_dev->vqs[vchan].fle_pool,
(void **)qdma_dev->vqs[vchan].cntx_sg,
--
2.43.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH v4-S1 5/5] mempool/dpaa2: support ops index from primary in secondary
2026-09-22 9:21 ` [PATCH v4-S1 " Prashant Gupta
` (3 preceding siblings ...)
2026-09-22 9:21 ` [PATCH v4-S1 4/5] dma/dpaa2: validate IOVA in pre-populate helpers Prashant Gupta
@ 2026-09-22 9:21 ` Prashant Gupta
2026-09-22 13:59 ` [PATCH v4-S1 0/5] dpaa2: bus, DMA and mempool base fixes Stephen Hemminger
2026-09-29 14:21 ` [PATCH v5-S1 " Prashant Gupta
6 siblings, 0 replies; 30+ messages in thread
From: Prashant Gupta @ 2026-09-22 9:21 UTC (permalink / raw)
To: stephen, dev; +Cc: Jun Yang, Hemant Agrawal
From: Jun Yang <jun.yang@nxp.com>
Secondary processes call rte_dpaa2_mpool_get_ops_idx() but the ops
index is registered only in the primary process. The secondary had no
way to learn the index, causing it to use the initial sentinel value
RTE_MEMPOOL_MAX_OPS_IDX and return an error.
Register an IPC action handler in the primary during pool creation.
Secondary processes send DPAA2_POOL_OPS_IDX_REQ over the
dpaa2_pool_mp_sync channel and receive the ops index back.
Also handle the case where rte_mp_action_register returns ENOTSUP
(e.g. no secondary process support enabled at build time) by
treating it as non-fatal, and improve the error message in
rte_hw_mbuf_free_pool to include the pool name.
Signed-off-by: Jun Yang <jun.yang@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/mempool/dpaa2/dpaa2_hw_mempool.c | 103 ++++++++++++++++++++++-
1 file changed, 100 insertions(+), 3 deletions(-)
diff --git a/drivers/mempool/dpaa2/dpaa2_hw_mempool.c b/drivers/mempool/dpaa2/dpaa2_hw_mempool.c
index ee001d8ce0..666338fc32 100644
--- a/drivers/mempool/dpaa2/dpaa2_hw_mempool.c
+++ b/drivers/mempool/dpaa2/dpaa2_hw_mempool.c
@@ -34,16 +34,96 @@
#include <dpaax_iova_table.h>
+#define DPAA2_POOL_MP_SYNC "dpaa2_pool_mp_sync"
+#define DPAA2_POOL_OPS_IDX_REQ 0x100
+#define DPAA2_POOL_OPS_IDX_RSP 0x101
+
+static RTE_ATOMIC(int) s_dpaa2_pool_mp_msg_setup;
+
+struct dpaa2_pool_mp_msg {
+ uint16_t msg_type;
+ uint8_t msg_data[];
+};
+
RTE_EXPORT_INTERNAL_SYMBOL(rte_dpaa2_bpid_info)
struct dpaa2_bp_info *rte_dpaa2_bpid_info;
static struct dpaa2_bp_list *h_bp_list;
static int16_t s_dpaa2_pool_ops_idx = RTE_MEMPOOL_MAX_OPS_IDX;
+static int
+dpaa2_mbuf_pool_mp_primary(const struct rte_mp_msg *msg,
+ const void *peer)
+{
+ struct rte_mp_msg reply;
+ const struct dpaa2_pool_mp_msg *req_msg = (const void *)msg->param;
+ struct dpaa2_pool_mp_msg *rsp_msg = (void *)reply.param;
+
+ memset(&reply, 0, sizeof(reply));
+
+ switch (req_msg->msg_type) {
+ case DPAA2_POOL_OPS_IDX_REQ:
+ rsp_msg->msg_type = DPAA2_POOL_OPS_IDX_RSP;
+ memcpy(rsp_msg->msg_data, &s_dpaa2_pool_ops_idx,
+ sizeof(s_dpaa2_pool_ops_idx));
+ reply.len_param = sizeof(struct dpaa2_pool_mp_msg) +
+ sizeof(s_dpaa2_pool_ops_idx);
+ break;
+ default:
+ DPAA2_MEMPOOL_ERR("%s received invalid request(%d)",
+ __func__, req_msg->msg_type);
+ return -ENOTSUP;
+ }
+
+ strlcpy(reply.name, DPAA2_POOL_MP_SYNC, sizeof(reply.name));
+ return rte_mp_reply(&reply, peer);
+}
+
RTE_EXPORT_INTERNAL_SYMBOL(rte_dpaa2_mpool_get_ops_idx)
int rte_dpaa2_mpool_get_ops_idx(void)
{
- return s_dpaa2_pool_ops_idx;
+ struct rte_mp_msg mp_req;
+ struct rte_mp_reply mp_reply;
+ struct timespec ts = {.tv_sec = 5, .tv_nsec = 0};
+ int ret = 0;
+ struct dpaa2_pool_mp_msg *req_msg = (void *)mp_req.param;
+ struct dpaa2_pool_mp_msg *rsp_msg;
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY ||
+ s_dpaa2_pool_ops_idx != RTE_MEMPOOL_MAX_OPS_IDX)
+ return s_dpaa2_pool_ops_idx;
+
+ memset(&mp_req, 0, sizeof(mp_req));
+ strlcpy(mp_req.name, DPAA2_POOL_MP_SYNC, sizeof(mp_req.name));
+ mp_req.len_param = sizeof(struct dpaa2_pool_mp_msg) +
+ sizeof(s_dpaa2_pool_ops_idx);
+ req_msg->msg_type = DPAA2_POOL_OPS_IDX_REQ;
+ memset(&mp_reply, 0, sizeof(struct rte_mp_reply));
+ ret = rte_mp_request_sync(&mp_req, &mp_reply, &ts);
+ if (ret) {
+ DPAA2_MEMPOOL_ERR("%s Failed to get response(%d)",
+ __func__, ret);
+ free(mp_reply.msgs);
+ return ret;
+ }
+ if (!mp_reply.msgs) {
+ DPAA2_MEMPOOL_ERR("%s Failed to get response message",
+ __func__);
+ return -EINVAL;
+ }
+ rsp_msg = (void *)mp_reply.msgs;
+ if (rsp_msg->msg_type == DPAA2_POOL_OPS_IDX_RSP) {
+ memcpy(&s_dpaa2_pool_ops_idx, rsp_msg->msg_data,
+ sizeof(s_dpaa2_pool_ops_idx));
+ ret = 0;
+ } else {
+ DPAA2_MEMPOOL_ERR("%s received invalid response(%d)",
+ __func__, rsp_msg->msg_type);
+ ret = -EINVAL;
+ }
+ free(mp_reply.msgs);
+
+ return ret ? ret : s_dpaa2_pool_ops_idx;
}
static int
@@ -128,10 +208,27 @@ rte_hw_mbuf_create_pool(struct rte_mempool *mp)
if (s_dpaa2_pool_ops_idx == RTE_MEMPOOL_MAX_OPS_IDX) {
s_dpaa2_pool_ops_idx = mp->ops_index;
} else if (s_dpaa2_pool_ops_idx != mp->ops_index) {
- DPAA2_MEMPOOL_ERR("Only single ops index only");
+ DPAA2_MEMPOOL_ERR("Single ops index only");
ret = -EINVAL;
goto err4;
}
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ int expected = 0;
+
+ if (rte_atomic_compare_exchange_strong_explicit(
+ &s_dpaa2_pool_mp_msg_setup, &expected, 1,
+ rte_memory_order_relaxed,
+ rte_memory_order_relaxed)) {
+ ret = rte_mp_action_register(DPAA2_POOL_MP_SYNC,
+ dpaa2_mbuf_pool_mp_primary);
+ if (ret && rte_errno != ENOTSUP) {
+ rte_atomic_store_explicit(&s_dpaa2_pool_mp_msg_setup, 0,
+ rte_memory_order_relaxed);
+ ret = -rte_errno;
+ goto err4;
+ }
+ }
+ }
bp_list->next = h_bp_list;
bp_list->mp = mp;
@@ -172,7 +269,7 @@ rte_hw_mbuf_free_pool(struct rte_mempool *mp)
struct dpaa2_dpbp_dev *dpbp_node;
if (!mp->pool_data) {
- DPAA2_MEMPOOL_ERR("Not a valid dpaa2 buffer pool");
+ DPAA2_MEMPOOL_ERR("Not a valid dpaa2 buffer pool %s", mp->name);
return;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* Re: [PATCH v4-S1 0/5] dpaa2: bus, DMA and mempool base fixes
2026-09-22 9:21 ` [PATCH v4-S1 " Prashant Gupta
` (4 preceding siblings ...)
2026-09-22 9:21 ` [PATCH v4-S1 5/5] mempool/dpaa2: support ops index from primary in secondary Prashant Gupta
@ 2026-09-22 13:59 ` Stephen Hemminger
2026-09-29 14:21 ` [PATCH v5-S1 " Prashant Gupta
6 siblings, 0 replies; 30+ messages in thread
From: Stephen Hemminger @ 2026-09-22 13:59 UTC (permalink / raw)
To: Prashant Gupta; +Cc: dev
On Tue, 22 Sep 2026 14:51:53 +0530
Prashant Gupta <prashant.gupta_3@nxp.com> wrote:
> This series is the first of four that upstream the missing NXP dpaa2
> driver changes. It collects the foundational bus/fslmc, dma/dpaa2 and
> mempool/dpaa2 fixes that the later series build on:
>
> - defer fslmc bus initialization to probe and reduce probe-time logging
> and MC traffic,
> - fix an array-bounds warning and validate IOVA in the dpaa2 QDMA
> pre-populate helpers,
> - support fetching the mempool ops index from the primary process in a
> secondary process.
>
> Every commit builds cleanly (including the aarch64 DPAA cross build with
> -Werror) and the series is bisectable.
>
> Gagandeep Singh (1):
> dma/dpaa2: validate IOVA in pre-populate helpers
>
> Hemant Agrawal (1):
> bus/fslmc: reduce probe-time logging and MC traffic
>
> Jun Yang (2):
> dma/dpaa2: fix array-bounds warning in dequeue path
> mempool/dpaa2: support ops index from primary in secondary
>
> Prashant Gupta (1):
> bus/fslmc: defer bus initialization to probe
>
> drivers/bus/fslmc/fslmc_bus.c | 92 +++++++++++---------
> drivers/bus/fslmc/fslmc_vfio.c | 3 +-
> drivers/bus/fslmc/portal/dpaa2_hw_dprc.c | 5 ++
> drivers/dma/dpaa2/dpaa2_qdma.c | 44 +++++++---
> drivers/mempool/dpaa2/dpaa2_hw_mempool.c | 103 ++++++++++++++++++++++-
> 5 files changed, 191 insertions(+), 56 deletions(-)
>
Several issues reported by AI on this series:
[PATCH v4-S1 0/5] fslmc bus, dpaa2 dma and mempool fixes
Applied to main (6bbb7b3). Per-commit build with -Dwerror=true passes
for all 5 patches (x86, gcc 13, bus/fslmc, mempool/dpaa2, net/dpaa2,
dma/dpaa2, crypto/dpaa2_sec, event/dpaa2).
Series-level:
Three of five commit messages (2, 3, 4) do not describe the code in
the patch. They read as carried over from an earlier revision.
Rewrite them against the actual diffs.
Patch 2/5 bus/fslmc: reduce probe-time logging and MC traffic
Warning: the body only covers the NOTICE -> DEBUG change. The
dpaa2_hw_dprc.c hunk, which skips dprc_get_connection() for blocked
devices, is not mentioned. Split it into its own patch or describe it.
Warning: the skip tests only devargs->policy == RTE_DEV_BLOCKED. With
an allowlist (-a, or no_auto_probing), non-listed devices have no
devargs and are still queried over MC. Use
rte_bus_device_is_ignored(&rte_fslmc_bus, dev->device.name), as the
pci, cdx, auxiliary, platform and uacce buses do.
Patch 3/5 dma/dpaa2: fix array-bounds warning in dequeue path
Warning: the commit message describes a per-queue idxs[] scratch
buffer and merging the LONG and SG fle_sdd handling. Neither is in
the diff. The patch actually does two things. It rewrites
qdma_cntx_idx_ring_eq() as a two-part memcpy with wrap. It moves the
SG fle_elem append after the ring enqueue and returns fle_sdd to the
pool directly on -ENOSPC. Describe those changes. Also name the
compiler and version that emits the warning.
Patch 4/5 dma/dpaa2: validate IOVA in pre-populate helpers
Warning: subject and body describe changing fle_sdd_pre_populate()
and fle_sdd_sg_pre_populate() to use DPAA2_VADDR_TO_IOVA_AND_CHECK()
and return errors. Neither helper is touched. The diff adds a single
rte_mempool_mem_iter() check of the fle_pool at vchan setup. Fix the
subject and message.
Warning: the new error path returns -ENOMEM without freeing
vqs[vchan].fle_pool. A second vchan_setup on the same vchan then fails
in rte_mempool_create() with a name collision. Free the pool and
clear the pointer.
Patch 5/5 mempool/dpaa2: support ops index from primary in secondary
Error: rte_dpaa2_mpool_get_ops_idx() is called per op in the
dpaa2_sec enqueue fast path (dpaa2_sec_dpseci.c:1544, :1903). In a
secondary it now issues rte_mp_request_sync() with a 5 s timeout
whenever the cached value is still RTE_MEMPOOL_MAX_OPS_IDX. That is
the steady state when the primary has not created a dpaa2 pool,
because the reply is the sentinel and nothing is cached. The result
is a blocking IPC round trip per crypto op, from multiple lcores
concurrently, and a 5 s stall per op if the primary is gone.
The IPC is not needed. Mempool ops are registered by constructor in
the same order in every process, which the multi-process mempool
model already depends on, so the index is process-invariant. Resolve
it locally in the secondary by looking up the "dpaa2" name in
rte_mempool_ops_table once, and cache it. That removes the IPC
channel, the action registration and the atomic.
Warning: the reply handler path does not check
mp_reply.msgs->len_param before memcpy from msg_data.
Warning: on rte_mp_request_sync() failure the function returns -1,
not an errno.
Info: rte_mp_action_register() returns ENOTSUP for --in-memory and
--no-shconf. That is a runtime condition, not "no secondary process
support enabled at build time" as the message says.
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v5-S1 0/5] dpaa2: bus, DMA and mempool base fixes
2026-09-22 9:21 ` [PATCH v4-S1 " Prashant Gupta
` (5 preceding siblings ...)
2026-09-22 13:59 ` [PATCH v4-S1 0/5] dpaa2: bus, DMA and mempool base fixes Stephen Hemminger
@ 2026-09-29 14:21 ` Prashant Gupta
2026-09-29 14:21 ` [PATCH v5-S1 1/5] bus/fslmc: defer bus initialization to probe Prashant Gupta
` (6 more replies)
6 siblings, 7 replies; 30+ messages in thread
From: Prashant Gupta @ 2026-09-29 14:21 UTC (permalink / raw)
To: stephen, dev
This series is the first of four that upstream the missing NXP dpaa2
driver changes. It collects the foundational bus/fslmc, dma/dpaa2 and
mempool/dpaa2 fixes that the later series build on:
- defer fslmc bus initialization to probe; reduce probe-time logging
and skip ignored devices during DPRC population,
- fix a GCC -Warray-bounds warning and an SG FD double-put in the
dpaa2 QDMA dequeue path,
- validate the FLE pool IOVA mapping at vchan setup and free the pool
on failure,
- resolve the mempool ops index locally in secondary processes by
scanning rte_mempool_ops_table, removing the need for IPC.
Every commit builds cleanly (including the aarch64 DPAA cross build with
-Werror) and the series is bisectable.
Gagandeep Singh (1):
dma/dpaa2: validate FLE pool IOVA mapping at vchan setup
Hemant Agrawal (1):
bus/fslmc: reduce probe-time logging and skip ignored devices
Jun Yang (2):
mempool/dpaa2: look up ops index locally in secondary
dma/dpaa2: fix array-bounds warning and SG FD double-put
Prashant Gupta (1):
bus/fslmc: defer bus initialization to probe
drivers/bus/fslmc/fslmc_bus.c | 92 ++++++++++++++++++--------------
drivers/bus/fslmc/fslmc_vfio.c | 3 +-
drivers/bus/fslmc/portal/dpaa2_hw_dprc.c | 4 ++
drivers/dma/dpaa2/dpaa2_qdma.c | 46 ++++++++++++----
drivers/mempool/dpaa2/dpaa2_hw_mempool.c | 25 +++++++--
5 files changed, 113 insertions(+), 57 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v5-S1 1/5] bus/fslmc: defer bus initialization to probe
2026-09-29 14:21 ` [PATCH v5-S1 " Prashant Gupta
@ 2026-09-29 14:21 ` Prashant Gupta
2026-09-29 14:21 ` [PATCH v5-S1 2/5] bus/fslmc: reduce probe-time logging and skip ignored devices Prashant Gupta
` (5 subsequent siblings)
6 siblings, 0 replies; 30+ messages in thread
From: Prashant Gupta @ 2026-09-29 14:21 UTC (permalink / raw)
To: stephen, dev
The fslmc bus initialization (register the sequence number mbuf
dynfield, set up the VFIO group, DMA map the memory segments) needs the
DPDK heap and the memory segment list in shared (hugepage) memory for
multi-process sharing. But these are not available during the bus scan
(EAL runs rte_bus_scan() before memzone, memory and malloc heap init),
so it fails there.
Device discovery does not need it, and get_iommu_class() only checks
sysfs paths to report the IOVA mode, so the init is not needed in scan.
Move it back to probe.
Fixes: cdefd2e980bd ("drivers/bus: initialize NXP bus specifics in scan")
Signed-off-by: Prashant Gupta <prashant.gupta_3@nxp.com>
---
drivers/bus/fslmc/fslmc_bus.c | 92 +++++++++++++++++++----------------
1 file changed, 51 insertions(+), 41 deletions(-)
diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index 3626b12316..1c638a2d82 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -368,46 +368,6 @@ rte_fslmc_scan(void)
/* If debugging is enabled, device list is dumped to log output */
dump_device_list();
- /* Bus initialization - only if devices were found */
- if (!TAILQ_EMPTY(&rte_fslmc_bus.device_list)) {
- static const struct rte_mbuf_dynfield dpaa2_seqn_dynfield_desc = {
- .name = DPAA2_SEQN_DYNFIELD_NAME,
- .size = sizeof(dpaa2_seqn_t),
- .align = alignof(dpaa2_seqn_t),
- };
-
- dpaa2_seqn_dynfield_offset =
- rte_mbuf_dynfield_register(&dpaa2_seqn_dynfield_desc);
- if (dpaa2_seqn_dynfield_offset < 0) {
- DPAA2_BUS_ERR("Failed to register mbuf field for dpaa sequence number");
- return 0;
- }
-
- ret = fslmc_vfio_setup_group();
- if (ret) {
- DPAA2_BUS_ERR("Unable to setup VFIO %d", ret);
- return 0;
- }
-
- /* Map existing segments as well as, in case of hotpluggable memory,
- * install callback handler.
- */
- if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
- ret = fslmc_vfio_dmamap();
- if (ret) {
- DPAA2_BUS_ERR("Unable to DMA map existing VAs: (%d)", ret);
- DPAA2_BUS_ERR("FSLMC VFIO Mapping failed");
- return 0;
- }
- }
-
- ret = fslmc_vfio_process_group();
- if (ret) {
- DPAA2_BUS_ERR("Unable to setup devices %d", ret);
- return 0;
- }
- }
-
process_once = 1;
return 0;
@@ -423,6 +383,56 @@ rte_fslmc_scan(void)
return 0;
}
+/* Bus initialization needs the DPDK heap and DMA mapping of the memory
+ * segments, which EAL only sets up after the bus scan, so it is done here.
+ */
+static int
+rte_fslmc_probe(struct rte_bus *bus)
+{
+ static const struct rte_mbuf_dynfield dpaa2_seqn_dynfield_desc = {
+ .name = DPAA2_SEQN_DYNFIELD_NAME,
+ .size = sizeof(dpaa2_seqn_t),
+ .align = alignof(dpaa2_seqn_t),
+ };
+ int ret;
+
+ if (TAILQ_EMPTY(&rte_fslmc_bus.device_list))
+ return 0;
+
+ dpaa2_seqn_dynfield_offset =
+ rte_mbuf_dynfield_register(&dpaa2_seqn_dynfield_desc);
+ if (dpaa2_seqn_dynfield_offset < 0) {
+ DPAA2_BUS_ERR("Failed to register mbuf field for dpaa sequence number");
+ return dpaa2_seqn_dynfield_offset;
+ }
+
+ ret = fslmc_vfio_setup_group();
+ if (ret) {
+ DPAA2_BUS_ERR("Unable to setup VFIO %d", ret);
+ return ret;
+ }
+
+ /* Map existing segments as well as, in case of hotpluggable memory,
+ * install callback handler.
+ */
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ ret = fslmc_vfio_dmamap();
+ if (ret) {
+ DPAA2_BUS_ERR("Unable to DMA map existing VAs: (%d)", ret);
+ DPAA2_BUS_ERR("FSLMC VFIO Mapping failed");
+ return ret;
+ }
+ }
+
+ ret = fslmc_vfio_process_group();
+ if (ret) {
+ DPAA2_BUS_ERR("Unable to setup devices %d", ret);
+ return ret;
+ }
+
+ return rte_bus_generic_probe(bus);
+}
+
static bool
fslmc_bus_match(const struct rte_driver *drv, const struct rte_device *dev)
{
@@ -544,7 +554,7 @@ fslmc_bus_unplug_device(struct rte_device *rte_dev)
struct rte_bus rte_fslmc_bus = {
.scan = rte_fslmc_scan,
- .probe = rte_bus_generic_probe,
+ .probe = rte_fslmc_probe,
.cleanup = rte_fslmc_close,
.parse = rte_fslmc_parse,
.dev_compare = fslmc_dev_compare,
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH v5-S1 2/5] bus/fslmc: reduce probe-time logging and skip ignored devices
2026-09-29 14:21 ` [PATCH v5-S1 " Prashant Gupta
2026-09-29 14:21 ` [PATCH v5-S1 1/5] bus/fslmc: defer bus initialization to probe Prashant Gupta
@ 2026-09-29 14:21 ` Prashant Gupta
2026-09-29 14:21 ` [PATCH v5-S1 3/5] dma/dpaa2: fix array-bounds warning and SG FD double-put Prashant Gupta
` (4 subsequent siblings)
6 siblings, 0 replies; 30+ messages in thread
From: Prashant Gupta @ 2026-09-29 14:21 UTC (permalink / raw)
To: stephen, dev; +Cc: Hemant Agrawal
From: Hemant Agrawal <hemant.agrawal@nxp.com>
Every DMA map logged its virtual, IOVA and physical addresses at NOTICE.
An application that maps many memory segments prints one such line per
segment during initialisation, which drowns out messages the operator
actually needs; the neighbouring mapping paths already use debug level.
Lower these to DEBUG in fslmc_vfio.c and clean up a redundant variable
assignment while there.
Also add a missing rte_bus_device_is_ignored() check in
rte_dpaa2_create_dprc_device() so that devices on the denylist or
outside the allowlist are skipped during DPRC population, consistent
with the per-device check performed in the main probe loop.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/bus/fslmc/fslmc_vfio.c | 3 +--
drivers/bus/fslmc/portal/dpaa2_hw_dprc.c | 4 ++++
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 412b70e5ae..adde629ce6 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -900,8 +900,7 @@ fslmc_map_dma(uint64_t vaddr, rte_iova_t iovaddr, size_t len)
fslmc_mem_va2iova = RTE_BAD_IOVA;
TAILQ_INSERT_TAIL(&fslmc_memsegs, dmaseg, next);
}
- DPAA2_BUS_LOG(NOTICE,
- "%s(%zx): VA(%" PRIx64 "):IOVA(%" PRIx64 "):PHY(%" PRIx64 ")",
+ DPAA2_BUS_DEBUG("%s(%zx): VA(%" PRIx64 "):IOVA(%" PRIx64 "):PHY(%" PRIx64 ")",
is_io ? "DMA I/O map size" : "DMA MEM map size",
len, vaddr, iovaddr, phy);
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dprc.c b/drivers/bus/fslmc/portal/dpaa2_hw_dprc.c
index 868ed646af..02b69d404d 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dprc.c
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dprc.c
@@ -52,6 +52,10 @@ rte_dpaa2_create_dprc_device(int vdev_fd __rte_unused,
RTE_BUS_FOREACH_DEV(dev, &rte_fslmc_bus) {
/** DPRC is always created before it's children are created.*/
dev->container = dprc_node;
+
+ if (rte_bus_device_is_ignored(&rte_fslmc_bus, dev->device.name))
+ continue;
+
if (dev->dev_type == DPAA2_ETH) {
int link_state;
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH v5-S1 3/5] dma/dpaa2: fix array-bounds warning and SG FD double-put
2026-09-29 14:21 ` [PATCH v5-S1 " Prashant Gupta
2026-09-29 14:21 ` [PATCH v5-S1 1/5] bus/fslmc: defer bus initialization to probe Prashant Gupta
2026-09-29 14:21 ` [PATCH v5-S1 2/5] bus/fslmc: reduce probe-time logging and skip ignored devices Prashant Gupta
@ 2026-09-29 14:21 ` Prashant Gupta
2026-09-29 14:21 ` [PATCH v5-S1 4/5] dma/dpaa2: validate FLE pool IOVA mapping at vchan setup Prashant Gupta
` (3 subsequent siblings)
6 siblings, 0 replies; 30+ messages in thread
From: Prashant Gupta @ 2026-09-29 14:21 UTC (permalink / raw)
To: stephen, dev; +Cc: stable, Jun Yang
From: Jun Yang <jun.yang@nxp.com>
Two bugs fixed in the QDMA dequeue path:
1. Array-bounds warning: qdma_cntx_idx_ring_eq advanced the ring tail
one element at a time in a loop, which triggered a GCC -Warray-bounds
diagnostic because the compiler could not prove the tail stayed in
bounds. Replace the loop with a two-part memcpy (head region plus
wrap-around region when needed) and advance ring->tail by the full
count in one step, eliminating the warning.
2. SG FD double-put: in dpaa2_qdma_dq_fd() the fle_sdd pointer was
stored into fle_elem[] and the counter incremented before checking
the qdma_cntx_idx_ring_eq return value. On -ENOSPC the function
returned without putting fle_sdd back to fle_pool, causing a double-
free when the pool was later destroyed. Fix by calling
rte_mempool_put() before returning -ENOSPC, and moving the
fle_elem[]/counter update to after ring_eq succeeds.
Fixes: 388e888dc082 ("dma/dpaa2: support short FD")
Cc: stable@dpdk.org
Cc: stable@dpdk.org
Signed-off-by: Jun Yang <jun.yang@nxp.com>
---
drivers/dma/dpaa2/dpaa2_qdma.c | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/drivers/dma/dpaa2/dpaa2_qdma.c b/drivers/dma/dpaa2/dpaa2_qdma.c
index f7d94bb799..3b272f6593 100644
--- a/drivers/dma/dpaa2/dpaa2_qdma.c
+++ b/drivers/dma/dpaa2/dpaa2_qdma.c
@@ -66,16 +66,19 @@ qdma_cntx_idx_ring_eq(struct qdma_cntx_idx_ring *ring,
const uint16_t *elem, uint16_t nb,
uint16_t *free_space)
{
- uint16_t i;
+ uint16_t first;
if (unlikely(nb > ring->free_space))
return 0;
- for (i = 0; i < nb; i++) {
- ring->cntx_idx_ring[ring->tail] = elem[i];
- ring->tail = (ring->tail + 1) &
- (DPAA2_QDMA_MAX_DESC - 1);
- }
+ first = RTE_MIN(nb, (uint16_t)(DPAA2_QDMA_MAX_DESC - ring->tail));
+ memcpy(&ring->cntx_idx_ring[ring->tail], elem,
+ first * sizeof(uint16_t));
+ if (nb > first)
+ memcpy(&ring->cntx_idx_ring[0], &elem[first],
+ (nb - first) * sizeof(uint16_t));
+
+ ring->tail = (ring->tail + nb) & (DPAA2_QDMA_MAX_DESC - 1);
ring->free_space -= nb;
ring->nb_in_ring += nb;
@@ -962,15 +965,17 @@ dpaa2_qdma_dq_fd(const struct qbman_fd *fd,
}
if (type == DPAA2_QDMA_FD_SG) {
fle_sdd = (void *)(uintptr_t)DPAA2_GET_FD_FLC(fd);
- qdma_vq->fle_elem[*fle_elem_nb] = fle_sdd;
- (*fle_elem_nb)++;
cntx_sg = container_of(fle_sdd,
struct qdma_cntx_sg, fle_sdd);
ret = qdma_cntx_idx_ring_eq(qdma_vq->ring_cntx_idx,
cntx_sg->cntx_idx,
cntx_sg->job_nb, free_space);
- if (unlikely(ret < cntx_sg->job_nb))
+ if (unlikely(ret < cntx_sg->job_nb)) {
+ rte_mempool_put(qdma_vq->fle_pool, fle_sdd);
return -ENOSPC;
+ }
+ qdma_vq->fle_elem[*fle_elem_nb] = fle_sdd;
+ (*fle_elem_nb)++;
return 0;
}
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH v5-S1 4/5] dma/dpaa2: validate FLE pool IOVA mapping at vchan setup
2026-09-29 14:21 ` [PATCH v5-S1 " Prashant Gupta
` (2 preceding siblings ...)
2026-09-29 14:21 ` [PATCH v5-S1 3/5] dma/dpaa2: fix array-bounds warning and SG FD double-put Prashant Gupta
@ 2026-09-29 14:21 ` Prashant Gupta
2026-09-29 14:21 ` [PATCH v5-S1 5/5] mempool/dpaa2: look up ops index locally in secondary Prashant Gupta
` (2 subsequent siblings)
6 siblings, 0 replies; 30+ messages in thread
From: Prashant Gupta @ 2026-09-29 14:21 UTC (permalink / raw)
To: stephen, dev; +Cc: Gagandeep Singh
From: Gagandeep Singh <g.singh@nxp.com>
After allocating the FLE mempool in dpaa2_qdma_vchan_setup(), iterate
over every memory chunk with rte_mempool_mem_iter() and verify that each
chunk is reachable through the IOMMU/SMMU by calling
DPAA2_VADDR_TO_IOVA_AND_CHECK(). If any chunk has no mapping, log the
pool name, release the pool with rte_mempool_free() and clear the pointer
to NULL before returning -ENOMEM, so that a subsequent vchan-setup retry
does not trip over a stale pool-name collision.
Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
---
drivers/dma/dpaa2/dpaa2_qdma.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/dpaa2/dpaa2_qdma.c b/drivers/dma/dpaa2/dpaa2_qdma.c
index 3b272f6593..409993ab08 100644
--- a/drivers/dma/dpaa2/dpaa2_qdma.c
+++ b/drivers/dma/dpaa2/dpaa2_qdma.c
@@ -1331,6 +1331,18 @@ dpaa2_qdma_vchan_rbp_set(struct qdma_virt_queue *vq,
return 0;
}
+static void
+dpaa2_qdma_fle_pool_iova_check(struct rte_mempool *mp __rte_unused,
+ void *opaque, struct rte_mempool_memhdr *memhdr,
+ unsigned int mem_idx __rte_unused)
+{
+ int *bad_map = opaque;
+
+ if (DPAA2_VADDR_TO_IOVA_AND_CHECK(memhdr->addr,
+ memhdr->len) == RTE_BAD_IOVA)
+ *bad_map = 1;
+}
+
static int
dpaa2_qdma_vchan_setup(struct rte_dma_dev *dev, uint16_t vchan,
const struct rte_dma_vchan_conf *conf,
@@ -1340,7 +1352,7 @@ dpaa2_qdma_vchan_setup(struct rte_dma_dev *dev, uint16_t vchan,
struct qdma_device *qdma_dev = dpdmai_dev->qdma_dev;
uint32_t pool_size;
char pool_name[64];
- int ret;
+ int ret, bad_map = 0;
uint64_t iova, va;
DPAA2_QDMA_FUNC_TRACE();
@@ -1381,6 +1393,15 @@ dpaa2_qdma_vchan_setup(struct rte_dma_dev *dev, uint16_t vchan,
va = qdma_dev->vqs[vchan].fle_pool->mz->addr_64;
qdma_dev->vqs[vchan].fle_iova2va_offset = va - iova;
+ rte_mempool_mem_iter(qdma_dev->vqs[vchan].fle_pool,
+ dpaa2_qdma_fle_pool_iova_check, &bad_map);
+ if (bad_map) {
+ DPAA2_QDMA_ERR("No IOMMU map for %s", pool_name);
+ rte_mempool_free(qdma_dev->vqs[vchan].fle_pool);
+ qdma_dev->vqs[vchan].fle_pool = NULL;
+ return -ENOMEM;
+ }
+
if (qdma_dev->is_silent) {
ret = rte_mempool_get_bulk(qdma_dev->vqs[vchan].fle_pool,
(void **)qdma_dev->vqs[vchan].cntx_sg,
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH v5-S1 5/5] mempool/dpaa2: look up ops index locally in secondary
2026-09-29 14:21 ` [PATCH v5-S1 " Prashant Gupta
` (3 preceding siblings ...)
2026-09-29 14:21 ` [PATCH v5-S1 4/5] dma/dpaa2: validate FLE pool IOVA mapping at vchan setup Prashant Gupta
@ 2026-09-29 14:21 ` Prashant Gupta
2026-09-29 15:45 ` [PATCH v5-S1 0/5] dpaa2: bus, DMA and mempool base fixes Stephen Hemminger
2026-10-06 15:07 ` [PATCH v6-S1 0/6] " Prashant Gupta
6 siblings, 0 replies; 30+ messages in thread
From: Prashant Gupta @ 2026-09-29 14:21 UTC (permalink / raw)
To: stephen, dev; +Cc: Jun Yang, Hemant Agrawal
From: Jun Yang <jun.yang@nxp.com>
Secondary processes call rte_dpaa2_mpool_get_ops_idx() but the ops
index was registered only in the primary process, so the function
returned the sentinel RTE_MEMPOOL_MAX_OPS_IDX on every call in a
secondary.
The ops index is process-invariant: mempool ops are registered by a
constructor at library load time in the same link order in every
process. Fix rte_dpaa2_mpool_get_ops_idx() to scan rte_mempool_ops_table
by name ("dpaa2") locally and cache the result. No IPC round-trip is
needed.
Also fix a duplicated word in an error message in rte_hw_mbuf_create_pool
("Only single ops index only" -> "Single ops index only") and improve the
error log in rte_hw_mbuf_free_pool to include the pool name.
Signed-off-by: Jun Yang <jun.yang@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
drivers/mempool/dpaa2/dpaa2_hw_mempool.c | 25 ++++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)
diff --git a/drivers/mempool/dpaa2/dpaa2_hw_mempool.c b/drivers/mempool/dpaa2/dpaa2_hw_mempool.c
index ee001d8ce0..c2f2aecc2e 100644
--- a/drivers/mempool/dpaa2/dpaa2_hw_mempool.c
+++ b/drivers/mempool/dpaa2/dpaa2_hw_mempool.c
@@ -43,7 +43,25 @@ static int16_t s_dpaa2_pool_ops_idx = RTE_MEMPOOL_MAX_OPS_IDX;
RTE_EXPORT_INTERNAL_SYMBOL(rte_dpaa2_mpool_get_ops_idx)
int rte_dpaa2_mpool_get_ops_idx(void)
{
- return s_dpaa2_pool_ops_idx;
+ uint32_t i;
+
+ if (s_dpaa2_pool_ops_idx != RTE_MEMPOOL_MAX_OPS_IDX)
+ return s_dpaa2_pool_ops_idx;
+
+ /* Mempool ops are registered by constructor in the same order in
+ * every process, so the index is process-invariant. Scan the ops
+ * table locally and cache the result.
+ */
+ for (i = 0; i < rte_mempool_ops_table.num_ops; i++) {
+ if (strcmp(rte_mempool_ops_table.ops[i].name,
+ DPAA2_MEMPOOL_OPS_NAME) == 0) {
+ s_dpaa2_pool_ops_idx = (int16_t)i;
+ return s_dpaa2_pool_ops_idx;
+ }
+ }
+
+ DPAA2_MEMPOOL_ERR("dpaa2 mempool ops not found");
+ return -ENOENT;
}
static int
@@ -128,11 +146,10 @@ rte_hw_mbuf_create_pool(struct rte_mempool *mp)
if (s_dpaa2_pool_ops_idx == RTE_MEMPOOL_MAX_OPS_IDX) {
s_dpaa2_pool_ops_idx = mp->ops_index;
} else if (s_dpaa2_pool_ops_idx != mp->ops_index) {
- DPAA2_MEMPOOL_ERR("Only single ops index only");
+ DPAA2_MEMPOOL_ERR("Single ops index only");
ret = -EINVAL;
goto err4;
}
-
bp_list->next = h_bp_list;
bp_list->mp = mp;
@@ -172,7 +189,7 @@ rte_hw_mbuf_free_pool(struct rte_mempool *mp)
struct dpaa2_dpbp_dev *dpbp_node;
if (!mp->pool_data) {
- DPAA2_MEMPOOL_ERR("Not a valid dpaa2 buffer pool");
+ DPAA2_MEMPOOL_ERR("Not a valid dpaa2 buffer pool %s", mp->name);
return;
}
^ permalink raw reply related [flat|nested] 30+ messages in thread
* Re: [PATCH v5-S1 0/5] dpaa2: bus, DMA and mempool base fixes
2026-09-29 14:21 ` [PATCH v5-S1 " Prashant Gupta
` (4 preceding siblings ...)
2026-09-29 14:21 ` [PATCH v5-S1 5/5] mempool/dpaa2: look up ops index locally in secondary Prashant Gupta
@ 2026-09-29 15:45 ` Stephen Hemminger
2026-10-06 14:57 ` [EXT] " Prashant Gupta
2026-10-06 15:07 ` [PATCH v6-S1 0/6] " Prashant Gupta
6 siblings, 1 reply; 30+ messages in thread
From: Stephen Hemminger @ 2026-09-29 15:45 UTC (permalink / raw)
To: Prashant Gupta; +Cc: dev
On Tue, 29 Sep 2026 19:51:12 +0530
Prashant Gupta <prashant.gupta_3@nxp.com> wrote:
> This series is the first of four that upstream the missing NXP dpaa2
> driver changes. It collects the foundational bus/fslmc, dma/dpaa2 and
> mempool/dpaa2 fixes that the later series build on:
>
> - defer fslmc bus initialization to probe; reduce probe-time logging
> and skip ignored devices during DPRC population,
> - fix a GCC -Warray-bounds warning and an SG FD double-put in the
> dpaa2 QDMA dequeue path,
> - validate the FLE pool IOVA mapping at vchan setup and free the pool
> on failure,
> - resolve the mempool ops index locally in secondary processes by
> scanning rte_mempool_ops_table, removing the need for IPC.
>
> Every commit builds cleanly (including the aarch64 DPAA cross build with
> -Werror) and the series is bisectable.
>
> Gagandeep Singh (1):
> dma/dpaa2: validate FLE pool IOVA mapping at vchan setup
>
> Hemant Agrawal (1):
> bus/fslmc: reduce probe-time logging and skip ignored devices
>
> Jun Yang (2):
> mempool/dpaa2: look up ops index locally in secondary
> dma/dpaa2: fix array-bounds warning and SG FD double-put
>
> Prashant Gupta (1):
> bus/fslmc: defer bus initialization to probe
>
> drivers/bus/fslmc/fslmc_bus.c | 92 ++++++++++++++++++--------------
> drivers/bus/fslmc/fslmc_vfio.c | 3 +-
> drivers/bus/fslmc/portal/dpaa2_hw_dprc.c | 4 ++
> drivers/dma/dpaa2/dpaa2_qdma.c | 46 ++++++++++++----
> drivers/mempool/dpaa2/dpaa2_hw_mempool.c | 25 +++++++--
> 5 files changed, 113 insertions(+), 57 deletions(-)
>
Several AI errors here.
I think it is complaining that From and Signed-off-by don't match.
If you are managing these with git the problem is that you merged patch
but the author field didn't get set to match.
[PATCH v5-S1 0/5] dpaa2 bus/dma/mempool fixes
Series
Warning
Prashant Gupta sent patches 2-5, but they carry only the original
authors' Signed-off-by. The submitter needs to add his own
Signed-off-by to each one (DCO clause c).
Info
cdefd2e980bd made the same scan/probe move for bus/dpaa, and that
bus has the problem this series fixes for fslmc.
rte_dpaa_bus_scan() calls rte_mbuf_set_platform_mempool_ops()
(memzone reserve) and dpaax_iova_table_populate() (rte_zmalloc)
before EAL runs rte_eal_memzone_init() and
rte_eal_malloc_heap_init(). Both return values are ignored.
bus/dpaa needs a matching fix.
Patch 1 reverses part of cdefd2e980bd (the move to generic probe).
Cc David Marchand.
Patch 2/5: bus/fslmc: reduce probe-time logging and skip ignored
devices
Warning
The commit message says "clean up a redundant variable assignment
while there", but the fslmc_vfio.c hunk only changes the log
call. Drop the stale sentence.
Warning
+ if (rte_bus_device_is_ignored(&rte_fslmc_bus, dev->device.name))
+ continue;
This skip leaves ep_dev_type, ep_object_id and ep_name unset for
devices that stay on the bus. fslmc_vfio_process_group() only
removes devices with devargs->policy == RTE_DEV_BLOCKED. In
allowlist mode, unlisted devices stay on the list, still go
through fslmc_process_iodevices(), and can be attached later with
rte_dev_probe() because fslmc sets .probe_device. Such a dpni
keeps ep_dev_type == 0 (DPAA2_ETH, from the calloc() in
scan_one_fslmc_device()) and ep_object_id == 0. The loopback setup
in dpaa2_recycle.c then treats dpni.0 as self-connected, and a
DPMAC-connected port gets -ENOTSUP.
The commit message does not say what fails without the check. If
the problem is dprc_get_connection() failing for an ignored dpni
and aborting the whole DPRC, make that failure non-fatal: set
DPAA2_UNKNOWN and continue instead of skipping the query. If this
fixes a regression, add a Fixes tag.
The log level change and the ignore check are unrelated. Split
them into separate patches.
Info
Pre-existing, not introduced by this patch:
sprintf(dev->ep_name, "%s.%d", endpoint2.type, endpoint2.id);
This runs for every device, but endpoint2 is only initialized in
the DPAA2_ETH branch. A non-ETH device ahead of the first dpni
formats uninitialized stack, and type[16] need not be NUL
terminated.
Info
Pre-existing: net/dpaa2 never assigns priv->ep_dev_type,
priv->ep_object_id or priv->ep_name. The test
"if (priv->ep_dev_type != DPAA2_MAC)" in dpaa2_ethdev.c reads a
field nothing writes, and rte_pmd_dpaa2_ep_name() returns a buffer
nothing fills.
Patch 3/5: dma/dpaa2: fix array-bounds warning and SG FD double-put
Error
The SG FD change does not fix a bug. Before the patch, fle_sdd was
stored in fle_elem[] ahead of qdma_cntx_idx_ring_eq(). On -ENOSPC,
dpaa2_qdma_dequeue() clears pending, leaves the loop, and still
runs:
rte_mempool_put_bulk(qdma_vq->fle_pool,
qdma_vq->fle_elem, fle_elem_nb);
So the FLE went back to the pool exactly once. After the patch it
also goes back exactly once, through rte_mempool_put(). There was
no double put. rte_mempool_free() does not free objects
individually, so the described "double-free when the pool was
later destroyed" cannot happen. The DPAA2_QDMA_FD_LONG branch just
above keeps the same store-before-enqueue order. Drop this half,
or reword it as a cleanup with no Fixes or stable tag.
Warning
The array-bounds half does not name the compiler, version or
target, and does not quote the diagnostic. The pre-patch loop
builds clean on x86_64 with GCC 13.3 and 14.2 at -O3 -Werror
-Warray-bounds=2. The loop it replaces came from 07d679bceee3
("dma/dpaa2: refactor driver"), not 388e888dc082, so the Fixes
tag does not cover it. Make it a separate patch with its own
Fixes tag and the warning text in the message.
Info
Pre-existing: when dpaa2_qdma_dq_fd() returns -ENOSPC, the FD has
already been pulled from hardware. Its cntx_idx values never reach
the ring, so rte_dma_completed() never reports those jobs. The
early exit on
if (ret || free_space < RTE_DPAAX_QDMA_JOB_SUBMIT_MAX)
pending = 0;
also abandons any later results already written to dq_storage,
because active_dqs is then switched to dq_storage1.
Patch 4/5: dma/dpaa2: validate FLE pool IOVA mapping at vchan setup
Info
The check confirms each chunk has an fslmc mapping. It does not
check the property the fast path relies on. Enqueue converts every
FLE with
fle_iova = (uint64_t)fle - qdma_vq->fle_iova2va_offset;
and that offset comes from fle_pool->mz. That memzone is the
mempool header (mp->mz in rte_mempool_create_empty()), not the
object chunks reserved in rte_mempool_populate_default(). The
callback already has memhdr->iova. Comparing
(uint64_t)memhdr->addr - memhdr->iova against the offset would
catch a pool spread over chunks with different VA/IOVA offsets
(IOVA as PA with fragmented hugepages). The offset handling itself
is pre-existing.
Info
Pre-existing: later error paths still leave the stale pool that
the commit message describes. The two rte_mempool_get_bulk()
failures in silent mode and the ring_cntx_idx allocation failure
return without freeing fle_pool. The fle_elem rte_malloc() result
is never checked and is written in dpaa2_qdma_dq_fd().
Patch 5/5: mempool/dpaa2: look up ops index locally in secondary
Warning
This fixes a bug from de6a6e897fe6 ("mempool/dpaa2: add operation
index"), which shipped in 25.07 and is in 25.11 LTS. In a
secondary process, dpaa2_sec compares mb_pool->ops_index against
the sentinel and always takes the MAX_BPID path. Add:
Fixes: de6a6e897fe6 ("mempool/dpaa2: add operation index")
Cc: stable@dpdk.org
^ permalink raw reply [flat|nested] 30+ messages in thread
* RE: [EXT] Re: [PATCH v5-S1 0/5] dpaa2: bus, DMA and mempool base fixes
2026-09-29 15:45 ` [PATCH v5-S1 0/5] dpaa2: bus, DMA and mempool base fixes Stephen Hemminger
@ 2026-10-06 14:57 ` Prashant Gupta
0 siblings, 0 replies; 30+ messages in thread
From: Prashant Gupta @ 2026-10-06 14:57 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev@dpdk.org, David Marchand
cdefd2e980bd made the same scan/probe move for bus/dpaa, and that
bus has the problem this series fixes for fslmc.
rte_dpaa_bus_scan() calls rte_mbuf_set_platform_mempool_ops()
(memzone reserve) and dpaax_iova_table_populate() (rte_zmalloc)
before EAL runs rte_eal_memzone_init() and
rte_eal_malloc_heap_init(). Both return values are ignored.
bus/dpaa needs a matching fix.
Patch 1 reverses part of cdefd2e980bd (the move to generic probe).
=> for DPAA patch is already sent
https://patchwork.dpdk.org/project/dpdk/patch/20260831093328.4018765-1-prashant.gupta_3@nxp.com/
NXP Confidential
-----Original Message-----
From: Stephen Hemminger <stephen@networkplumber.org>
Sent: 29 September 2026 21:15
To: Prashant Gupta <prashant.gupta_3@nxp.com>
Cc: dev@dpdk.org
Subject: [EXT] Re: [PATCH v5-S1 0/5] dpaa2: bus, DMA and mempool base fixes
Caution: This is an external email. Please take care when clicking links or opening attachments. When in doubt, report the message using the 'Report this email' button
On Tue, 29 Sep 2026 19:51:12 +0530
Prashant Gupta <prashant.gupta_3@nxp.com> wrote:
> This series is the first of four that upstream the missing NXP dpaa2
> driver changes. It collects the foundational bus/fslmc, dma/dpaa2 and
> mempool/dpaa2 fixes that the later series build on:
>
> - defer fslmc bus initialization to probe; reduce probe-time logging
> and skip ignored devices during DPRC population,
> - fix a GCC -Warray-bounds warning and an SG FD double-put in the
> dpaa2 QDMA dequeue path,
> - validate the FLE pool IOVA mapping at vchan setup and free the pool
> on failure,
> - resolve the mempool ops index locally in secondary processes by
> scanning rte_mempool_ops_table, removing the need for IPC.
>
> Every commit builds cleanly (including the aarch64 DPAA cross build
> with
> -Werror) and the series is bisectable.
>
> Gagandeep Singh (1):
> dma/dpaa2: validate FLE pool IOVA mapping at vchan setup
>
> Hemant Agrawal (1):
> bus/fslmc: reduce probe-time logging and skip ignored devices
>
> Jun Yang (2):
> mempool/dpaa2: look up ops index locally in secondary
> dma/dpaa2: fix array-bounds warning and SG FD double-put
>
> Prashant Gupta (1):
> bus/fslmc: defer bus initialization to probe
>
> drivers/bus/fslmc/fslmc_bus.c | 92 ++++++++++++++++++--------------
> drivers/bus/fslmc/fslmc_vfio.c | 3 +-
> drivers/bus/fslmc/portal/dpaa2_hw_dprc.c | 4 ++
> drivers/dma/dpaa2/dpaa2_qdma.c | 46 ++++++++++++----
> drivers/mempool/dpaa2/dpaa2_hw_mempool.c | 25 +++++++--
> 5 files changed, 113 insertions(+), 57 deletions(-)
>
Several AI errors here.
I think it is complaining that From and Signed-off-by don't match.
If you are managing these with git the problem is that you merged patch but the author field didn't get set to match.
[PATCH v5-S1 0/5] dpaa2 bus/dma/mempool fixes
Series
Warning
Prashant Gupta sent patches 2-5, but they carry only the original
authors' Signed-off-by. The submitter needs to add his own
Signed-off-by to each one (DCO clause c).
Info
cdefd2e980bd made the same scan/probe move for bus/dpaa, and that
bus has the problem this series fixes for fslmc.
rte_dpaa_bus_scan() calls rte_mbuf_set_platform_mempool_ops()
(memzone reserve) and dpaax_iova_table_populate() (rte_zmalloc)
before EAL runs rte_eal_memzone_init() and
rte_eal_malloc_heap_init(). Both return values are ignored.
bus/dpaa needs a matching fix.
Patch 1 reverses part of cdefd2e980bd (the move to generic probe).
Cc David Marchand.
Patch 2/5: bus/fslmc: reduce probe-time logging and skip ignored devices
Warning
The commit message says "clean up a redundant variable assignment
while there", but the fslmc_vfio.c hunk only changes the log
call. Drop the stale sentence.
Warning
+ if (rte_bus_device_is_ignored(&rte_fslmc_bus, dev->device.name))
+ continue;
This skip leaves ep_dev_type, ep_object_id and ep_name unset for
devices that stay on the bus. fslmc_vfio_process_group() only
removes devices with devargs->policy == RTE_DEV_BLOCKED. In
allowlist mode, unlisted devices stay on the list, still go
through fslmc_process_iodevices(), and can be attached later with
rte_dev_probe() because fslmc sets .probe_device. Such a dpni
keeps ep_dev_type == 0 (DPAA2_ETH, from the calloc() in
scan_one_fslmc_device()) and ep_object_id == 0. The loopback setup
in dpaa2_recycle.c then treats dpni.0 as self-connected, and a
DPMAC-connected port gets -ENOTSUP.
The commit message does not say what fails without the check. If
the problem is dprc_get_connection() failing for an ignored dpni
and aborting the whole DPRC, make that failure non-fatal: set
DPAA2_UNKNOWN and continue instead of skipping the query. If this
fixes a regression, add a Fixes tag.
The log level change and the ignore check are unrelated. Split
them into separate patches.
Info
Pre-existing, not introduced by this patch:
sprintf(dev->ep_name, "%s.%d", endpoint2.type, endpoint2.id);
This runs for every device, but endpoint2 is only initialized in
the DPAA2_ETH branch. A non-ETH device ahead of the first dpni
formats uninitialized stack, and type[16] need not be NUL
terminated.
Info
Pre-existing: net/dpaa2 never assigns priv->ep_dev_type,
priv->ep_object_id or priv->ep_name. The test
"if (priv->ep_dev_type != DPAA2_MAC)" in dpaa2_ethdev.c reads a
field nothing writes, and rte_pmd_dpaa2_ep_name() returns a buffer
nothing fills.
Patch 3/5: dma/dpaa2: fix array-bounds warning and SG FD double-put
Error
The SG FD change does not fix a bug. Before the patch, fle_sdd was
stored in fle_elem[] ahead of qdma_cntx_idx_ring_eq(). On -ENOSPC,
dpaa2_qdma_dequeue() clears pending, leaves the loop, and still
runs:
rte_mempool_put_bulk(qdma_vq->fle_pool,
qdma_vq->fle_elem, fle_elem_nb);
So the FLE went back to the pool exactly once. After the patch it
also goes back exactly once, through rte_mempool_put(). There was
no double put. rte_mempool_free() does not free objects
individually, so the described "double-free when the pool was
later destroyed" cannot happen. The DPAA2_QDMA_FD_LONG branch just
above keeps the same store-before-enqueue order. Drop this half,
or reword it as a cleanup with no Fixes or stable tag.
Warning
The array-bounds half does not name the compiler, version or
target, and does not quote the diagnostic. The pre-patch loop
builds clean on x86_64 with GCC 13.3 and 14.2 at -O3 -Werror
-Warray-bounds=2. The loop it replaces came from 07d679bceee3
("dma/dpaa2: refactor driver"), not 388e888dc082, so the Fixes
tag does not cover it. Make it a separate patch with its own
Fixes tag and the warning text in the message.
Info
Pre-existing: when dpaa2_qdma_dq_fd() returns -ENOSPC, the FD has
already been pulled from hardware. Its cntx_idx values never reach
the ring, so rte_dma_completed() never reports those jobs. The
early exit on
if (ret || free_space < RTE_DPAAX_QDMA_JOB_SUBMIT_MAX)
pending = 0;
also abandons any later results already written to dq_storage,
because active_dqs is then switched to dq_storage1.
Patch 4/5: dma/dpaa2: validate FLE pool IOVA mapping at vchan setup
Info
The check confirms each chunk has an fslmc mapping. It does not
check the property the fast path relies on. Enqueue converts every
FLE with
fle_iova = (uint64_t)fle - qdma_vq->fle_iova2va_offset;
and that offset comes from fle_pool->mz. That memzone is the
mempool header (mp->mz in rte_mempool_create_empty()), not the
object chunks reserved in rte_mempool_populate_default(). The
callback already has memhdr->iova. Comparing
(uint64_t)memhdr->addr - memhdr->iova against the offset would
catch a pool spread over chunks with different VA/IOVA offsets
(IOVA as PA with fragmented hugepages). The offset handling itself
is pre-existing.
Info
Pre-existing: later error paths still leave the stale pool that
the commit message describes. The two rte_mempool_get_bulk()
failures in silent mode and the ring_cntx_idx allocation failure
return without freeing fle_pool. The fle_elem rte_malloc() result
is never checked and is written in dpaa2_qdma_dq_fd().
Patch 5/5: mempool/dpaa2: look up ops index locally in secondary
Warning
This fixes a bug from de6a6e897fe6 ("mempool/dpaa2: add operation
index"), which shipped in 25.07 and is in 25.11 LTS. In a
secondary process, dpaa2_sec compares mb_pool->ops_index against
the sentinel and always takes the MAX_BPID path. Add:
Fixes: de6a6e897fe6 ("mempool/dpaa2: add operation index")
Cc: stable@dpdk.org
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v6-S1 0/6] dpaa2: bus, DMA and mempool base fixes
2026-09-29 14:21 ` [PATCH v5-S1 " Prashant Gupta
` (5 preceding siblings ...)
2026-09-29 15:45 ` [PATCH v5-S1 0/5] dpaa2: bus, DMA and mempool base fixes Stephen Hemminger
@ 2026-10-06 15:07 ` Prashant Gupta
2026-10-06 15:07 ` [PATCH v6-S1 1/6] bus/fslmc: defer bus initialization to probe Prashant Gupta
` (6 more replies)
6 siblings, 7 replies; 30+ messages in thread
From: Prashant Gupta @ 2026-10-06 15:07 UTC (permalink / raw)
To: stephen, dev
This series is the first of four that upstream the missing NXP dpaa2
driver changes. It collects the foundational bus/fslmc, dma/dpaa2 and
mempool/dpaa2 fixes that the later series build on:
- defer fslmc bus initialization to probe; reduce probe logging
and skip ignored devices during DPRC population,
- use memcpy to fill the dpaa2 QDMA completion index ring,
- release SG FLE on completion ring overflow in the dpaa2 QDMA
dequeue path,
- validate the FLE pool IOVA mapping at vchan setup and free the pool
on failure,
- resolve the mempool ops index locally in secondary processes by
scanning rte_mempool_ops_table, removing the need for IPC.
Every commit builds cleanly (including the aarch64 DPAA cross build with
-Werror) and the series is bisectable.
Gagandeep Singh (1):
dma/dpaa2: validate FLE pool IOVA mapping at vchan setup
Hemant Agrawal (1):
bus/fslmc: reduce probe logging and skip ignored devices
Jun Yang (3):
dma/dpaa2: use memcpy to fill completion index ring
dma/dpaa2: release SG FLE on completion ring overflow
mempool/dpaa2: look up ops index locally in secondary
Prashant Gupta (1):
bus/fslmc: defer bus initialization to probe
drivers/bus/fslmc/fslmc_bus.c | 92 +++++++++++++-----------
drivers/bus/fslmc/fslmc_vfio.c | 3 +-
drivers/bus/fslmc/portal/dpaa2_hw_dprc.c | 4 ++
drivers/dma/dpaa2/dpaa2_qdma.c | 67 ++++++++++++++---
drivers/mempool/dpaa2/dpaa2_hw_mempool.c | 25 +++++--
5 files changed, 135 insertions(+), 56 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v6-S1 1/6] bus/fslmc: defer bus initialization to probe
2026-10-06 15:07 ` [PATCH v6-S1 0/6] " Prashant Gupta
@ 2026-10-06 15:07 ` Prashant Gupta
2026-10-06 15:07 ` [PATCH v6-S1 2/6] bus/fslmc: reduce probe logging and skip ignored devices Prashant Gupta
` (5 subsequent siblings)
6 siblings, 0 replies; 30+ messages in thread
From: Prashant Gupta @ 2026-10-06 15:07 UTC (permalink / raw)
To: stephen, dev
The fslmc bus initialization (register the sequence number mbuf
dynfield, set up the VFIO group, DMA map the memory segments) needs the
DPDK heap and the memory segment list in shared (hugepage) memory for
multi-process sharing. But these are not available during the bus scan
(EAL runs rte_bus_scan() before memzone, memory and malloc heap init),
so it fails there.
Device discovery does not need it, and get_iommu_class() only checks
sysfs paths to report the IOVA mode, so the init is not needed in scan.
Move it back to probe.
Fixes: cdefd2e980bd ("drivers/bus: initialize NXP bus specifics in scan")
Signed-off-by: Prashant Gupta <prashant.gupta_3@nxp.com>
---
drivers/bus/fslmc/fslmc_bus.c | 92 +++++++++++++++++++----------------
1 file changed, 51 insertions(+), 41 deletions(-)
diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index 3626b12316..1c638a2d82 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -368,46 +368,6 @@ rte_fslmc_scan(void)
/* If debugging is enabled, device list is dumped to log output */
dump_device_list();
- /* Bus initialization - only if devices were found */
- if (!TAILQ_EMPTY(&rte_fslmc_bus.device_list)) {
- static const struct rte_mbuf_dynfield dpaa2_seqn_dynfield_desc = {
- .name = DPAA2_SEQN_DYNFIELD_NAME,
- .size = sizeof(dpaa2_seqn_t),
- .align = alignof(dpaa2_seqn_t),
- };
-
- dpaa2_seqn_dynfield_offset =
- rte_mbuf_dynfield_register(&dpaa2_seqn_dynfield_desc);
- if (dpaa2_seqn_dynfield_offset < 0) {
- DPAA2_BUS_ERR("Failed to register mbuf field for dpaa sequence number");
- return 0;
- }
-
- ret = fslmc_vfio_setup_group();
- if (ret) {
- DPAA2_BUS_ERR("Unable to setup VFIO %d", ret);
- return 0;
- }
-
- /* Map existing segments as well as, in case of hotpluggable memory,
- * install callback handler.
- */
- if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
- ret = fslmc_vfio_dmamap();
- if (ret) {
- DPAA2_BUS_ERR("Unable to DMA map existing VAs: (%d)", ret);
- DPAA2_BUS_ERR("FSLMC VFIO Mapping failed");
- return 0;
- }
- }
-
- ret = fslmc_vfio_process_group();
- if (ret) {
- DPAA2_BUS_ERR("Unable to setup devices %d", ret);
- return 0;
- }
- }
-
process_once = 1;
return 0;
@@ -423,6 +383,56 @@ rte_fslmc_scan(void)
return 0;
}
+/* Bus initialization needs the DPDK heap and DMA mapping of the memory
+ * segments, which EAL only sets up after the bus scan, so it is done here.
+ */
+static int
+rte_fslmc_probe(struct rte_bus *bus)
+{
+ static const struct rte_mbuf_dynfield dpaa2_seqn_dynfield_desc = {
+ .name = DPAA2_SEQN_DYNFIELD_NAME,
+ .size = sizeof(dpaa2_seqn_t),
+ .align = alignof(dpaa2_seqn_t),
+ };
+ int ret;
+
+ if (TAILQ_EMPTY(&rte_fslmc_bus.device_list))
+ return 0;
+
+ dpaa2_seqn_dynfield_offset =
+ rte_mbuf_dynfield_register(&dpaa2_seqn_dynfield_desc);
+ if (dpaa2_seqn_dynfield_offset < 0) {
+ DPAA2_BUS_ERR("Failed to register mbuf field for dpaa sequence number");
+ return dpaa2_seqn_dynfield_offset;
+ }
+
+ ret = fslmc_vfio_setup_group();
+ if (ret) {
+ DPAA2_BUS_ERR("Unable to setup VFIO %d", ret);
+ return ret;
+ }
+
+ /* Map existing segments as well as, in case of hotpluggable memory,
+ * install callback handler.
+ */
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ ret = fslmc_vfio_dmamap();
+ if (ret) {
+ DPAA2_BUS_ERR("Unable to DMA map existing VAs: (%d)", ret);
+ DPAA2_BUS_ERR("FSLMC VFIO Mapping failed");
+ return ret;
+ }
+ }
+
+ ret = fslmc_vfio_process_group();
+ if (ret) {
+ DPAA2_BUS_ERR("Unable to setup devices %d", ret);
+ return ret;
+ }
+
+ return rte_bus_generic_probe(bus);
+}
+
static bool
fslmc_bus_match(const struct rte_driver *drv, const struct rte_device *dev)
{
@@ -544,7 +554,7 @@ fslmc_bus_unplug_device(struct rte_device *rte_dev)
struct rte_bus rte_fslmc_bus = {
.scan = rte_fslmc_scan,
- .probe = rte_bus_generic_probe,
+ .probe = rte_fslmc_probe,
.cleanup = rte_fslmc_close,
.parse = rte_fslmc_parse,
.dev_compare = fslmc_dev_compare,
--
2.43.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH v6-S1 2/6] bus/fslmc: reduce probe logging and skip ignored devices
2026-10-06 15:07 ` [PATCH v6-S1 0/6] " Prashant Gupta
2026-10-06 15:07 ` [PATCH v6-S1 1/6] bus/fslmc: defer bus initialization to probe Prashant Gupta
@ 2026-10-06 15:07 ` Prashant Gupta
2026-10-06 15:07 ` [PATCH v6-S1 3/6] dma/dpaa2: use memcpy to fill completion index ring Prashant Gupta
` (4 subsequent siblings)
6 siblings, 0 replies; 30+ messages in thread
From: Prashant Gupta @ 2026-10-06 15:07 UTC (permalink / raw)
To: stephen, dev; +Cc: Hemant Agrawal
From: Hemant Agrawal <hemant.agrawal@nxp.com>
Every DMA map logged its virtual, IOVA and physical addresses at NOTICE.
An application that maps many memory segments prints one such line per
segment during initialisation, which drowns out messages the operator
actually needs; the neighbouring mapping paths already use debug level.
Lower these to DEBUG in fslmc_vfio.c.
Also add a missing rte_bus_device_is_ignored() check in
rte_dpaa2_create_dprc_device() so that devices on the denylist or
outside the allowlist are skipped during DPRC population, consistent
with the per-device check performed in the main probe loop.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Signed-off-by: Prashant Gupta <prashant.gupta_3@nxp.com>
---
drivers/bus/fslmc/fslmc_vfio.c | 3 +--
drivers/bus/fslmc/portal/dpaa2_hw_dprc.c | 4 ++++
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c
index 412b70e5ae..adde629ce6 100644
--- a/drivers/bus/fslmc/fslmc_vfio.c
+++ b/drivers/bus/fslmc/fslmc_vfio.c
@@ -900,8 +900,7 @@ fslmc_map_dma(uint64_t vaddr, rte_iova_t iovaddr, size_t len)
fslmc_mem_va2iova = RTE_BAD_IOVA;
TAILQ_INSERT_TAIL(&fslmc_memsegs, dmaseg, next);
}
- DPAA2_BUS_LOG(NOTICE,
- "%s(%zx): VA(%" PRIx64 "):IOVA(%" PRIx64 "):PHY(%" PRIx64 ")",
+ DPAA2_BUS_DEBUG("%s(%zx): VA(%" PRIx64 "):IOVA(%" PRIx64 "):PHY(%" PRIx64 ")",
is_io ? "DMA I/O map size" : "DMA MEM map size",
len, vaddr, iovaddr, phy);
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dprc.c b/drivers/bus/fslmc/portal/dpaa2_hw_dprc.c
index 868ed646af..02b69d404d 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dprc.c
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dprc.c
@@ -52,6 +52,10 @@ rte_dpaa2_create_dprc_device(int vdev_fd __rte_unused,
RTE_BUS_FOREACH_DEV(dev, &rte_fslmc_bus) {
/** DPRC is always created before it's children are created.*/
dev->container = dprc_node;
+
+ if (rte_bus_device_is_ignored(&rte_fslmc_bus, dev->device.name))
+ continue;
+
if (dev->dev_type == DPAA2_ETH) {
int link_state;
--
2.43.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH v6-S1 3/6] dma/dpaa2: use memcpy to fill completion index ring
2026-10-06 15:07 ` [PATCH v6-S1 0/6] " Prashant Gupta
2026-10-06 15:07 ` [PATCH v6-S1 1/6] bus/fslmc: defer bus initialization to probe Prashant Gupta
2026-10-06 15:07 ` [PATCH v6-S1 2/6] bus/fslmc: reduce probe logging and skip ignored devices Prashant Gupta
@ 2026-10-06 15:07 ` Prashant Gupta
2026-10-06 15:07 ` [PATCH v6-S1 4/6] dma/dpaa2: release SG FLE on completion ring overflow Prashant Gupta
` (3 subsequent siblings)
6 siblings, 0 replies; 30+ messages in thread
From: Prashant Gupta @ 2026-10-06 15:07 UTC (permalink / raw)
To: stephen, dev; +Cc: Jun Yang
From: Jun Yang <jun.yang@nxp.com>
qdma_cntx_idx_ring_eq() copied the completion indices into the ring one
element at a time, masking the tail against DPAA2_QDMA_MAX_DESC on every
iteration. The number of elements and the available free space are both
known on entry, so the per-element masking is avoidable work in the
dequeue path.
Replace the loop with at most two memcpy() calls, one for the region up
to the end of the ring and one for the wrapped remainder, and advance
ring->tail by the full count once.
No functional change.
Signed-off-by: Jun Yang <jun.yang@nxp.com>
Signed-off-by: Prashant Gupta <prashant.gupta_3@nxp.com>
---
drivers/dma/dpaa2/dpaa2_qdma.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/dma/dpaa2/dpaa2_qdma.c b/drivers/dma/dpaa2/dpaa2_qdma.c
index f7d94bb799..7d3f3d2003 100644
--- a/drivers/dma/dpaa2/dpaa2_qdma.c
+++ b/drivers/dma/dpaa2/dpaa2_qdma.c
@@ -66,16 +66,19 @@ qdma_cntx_idx_ring_eq(struct qdma_cntx_idx_ring *ring,
const uint16_t *elem, uint16_t nb,
uint16_t *free_space)
{
- uint16_t i;
+ uint16_t first;
if (unlikely(nb > ring->free_space))
return 0;
- for (i = 0; i < nb; i++) {
- ring->cntx_idx_ring[ring->tail] = elem[i];
- ring->tail = (ring->tail + 1) &
- (DPAA2_QDMA_MAX_DESC - 1);
- }
+ first = RTE_MIN(nb, (uint16_t)(DPAA2_QDMA_MAX_DESC - ring->tail));
+ memcpy(&ring->cntx_idx_ring[ring->tail], elem,
+ first * sizeof(uint16_t));
+ if (nb > first)
+ memcpy(&ring->cntx_idx_ring[0], &elem[first],
+ (nb - first) * sizeof(uint16_t));
+
+ ring->tail = (ring->tail + nb) & (DPAA2_QDMA_MAX_DESC - 1);
ring->free_space -= nb;
ring->nb_in_ring += nb;
--
2.43.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH v6-S1 4/6] dma/dpaa2: release SG FLE on completion ring overflow
2026-10-06 15:07 ` [PATCH v6-S1 0/6] " Prashant Gupta
` (2 preceding siblings ...)
2026-10-06 15:07 ` [PATCH v6-S1 3/6] dma/dpaa2: use memcpy to fill completion index ring Prashant Gupta
@ 2026-10-06 15:07 ` Prashant Gupta
2026-10-06 15:07 ` [PATCH v6-S1 5/6] dma/dpaa2: validate FLE pool IOVA mapping at vchan setup Prashant Gupta
` (2 subsequent siblings)
6 siblings, 0 replies; 30+ messages in thread
From: Prashant Gupta @ 2026-10-06 15:07 UTC (permalink / raw)
To: stephen, dev; +Cc: Jun Yang
From: Jun Yang <jun.yang@nxp.com>
In the DPAA2_QDMA_FD_SG branch of dpaa2_qdma_dq_fd(), the FLE was
recorded in qdma_vq->fle_elem[] before qdma_cntx_idx_ring_eq() was
called. On overflow the function returned -ENOSPC with the entry
already accounted for, leaving the release to the bulk
rte_mempool_put_bulk() that dpaa2_qdma_dequeue() performs after the
loop.
This is not a leak and not a double put, the object is returned exactly
once either way. However the ownership is easier to follow if the error
path releases the FLE itself, so return it with rte_mempool_put() and
only record it in fle_elem[] once the indices are in the ring. This
matches how the caller treats a failed dq_fd() as having consumed
nothing.
No functional change.
Signed-off-by: Jun Yang <jun.yang@nxp.com>
Signed-off-by: Prashant Gupta <prashant.gupta_3@nxp.com>
---
drivers/dma/dpaa2/dpaa2_qdma.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/dma/dpaa2/dpaa2_qdma.c b/drivers/dma/dpaa2/dpaa2_qdma.c
index 7d3f3d2003..3b272f6593 100644
--- a/drivers/dma/dpaa2/dpaa2_qdma.c
+++ b/drivers/dma/dpaa2/dpaa2_qdma.c
@@ -965,15 +965,17 @@ dpaa2_qdma_dq_fd(const struct qbman_fd *fd,
}
if (type == DPAA2_QDMA_FD_SG) {
fle_sdd = (void *)(uintptr_t)DPAA2_GET_FD_FLC(fd);
- qdma_vq->fle_elem[*fle_elem_nb] = fle_sdd;
- (*fle_elem_nb)++;
cntx_sg = container_of(fle_sdd,
struct qdma_cntx_sg, fle_sdd);
ret = qdma_cntx_idx_ring_eq(qdma_vq->ring_cntx_idx,
cntx_sg->cntx_idx,
cntx_sg->job_nb, free_space);
- if (unlikely(ret < cntx_sg->job_nb))
+ if (unlikely(ret < cntx_sg->job_nb)) {
+ rte_mempool_put(qdma_vq->fle_pool, fle_sdd);
return -ENOSPC;
+ }
+ qdma_vq->fle_elem[*fle_elem_nb] = fle_sdd;
+ (*fle_elem_nb)++;
return 0;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH v6-S1 5/6] dma/dpaa2: validate FLE pool IOVA mapping at vchan setup
2026-10-06 15:07 ` [PATCH v6-S1 0/6] " Prashant Gupta
` (3 preceding siblings ...)
2026-10-06 15:07 ` [PATCH v6-S1 4/6] dma/dpaa2: release SG FLE on completion ring overflow Prashant Gupta
@ 2026-10-06 15:07 ` Prashant Gupta
2026-10-06 15:07 ` [PATCH v6-S1 6/6] mempool/dpaa2: look up ops index locally in secondary Prashant Gupta
2026-10-07 15:51 ` [PATCH v6-S1 0/6] dpaa2: bus, DMA and mempool base fixes Stephen Hemminger
6 siblings, 0 replies; 30+ messages in thread
From: Prashant Gupta @ 2026-10-06 15:07 UTC (permalink / raw)
To: stephen, dev; +Cc: Gagandeep Singh
From: Gagandeep Singh <g.singh@nxp.com>
The enqueue path turns every FLE virtual address into an IOVA with a
single subtraction:
fle_iova = (uint64_t)fle - qdma_vq->fle_iova2va_offset;
That offset is derived once from fle_pool->mz, which is the memzone
holding the mempool header, not the memzone(s) holding the objects. The
objects are reserved separately by rte_mempool_populate_default(), so
nothing so far confirmed that the offset taken from the header is also
the offset of the chunks the FLEs are allocated from.
Walk the pool with rte_mempool_mem_iter() after creation and check both
properties the fast path depends on. First, that every chunk is
reachable through the IOMMU/SMMU, using DPAA2_VADDR_TO_IOVA_AND_CHECK().
Second, that every chunk has the same VA to IOVA delta as the offset
cached in the virtual queue, which a pool spread over chunks with
different deltas would violate, for example with IOVA as PA and
fragmented hugepages. Either way the IOVAs programmed into the FLEs
would be wrong, so reject the setup instead.
On failure log the pool name, release the pool with rte_mempool_free()
and clear the pointer, so that a later vchan-setup retry does not trip
over a stale pool-name collision.
Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
Signed-off-by: Prashant Gupta <prashant.gupta_3@nxp.com>
---
drivers/dma/dpaa2/dpaa2_qdma.c | 44 ++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/drivers/dma/dpaa2/dpaa2_qdma.c b/drivers/dma/dpaa2/dpaa2_qdma.c
index 3b272f6593..27ca10f94f 100644
--- a/drivers/dma/dpaa2/dpaa2_qdma.c
+++ b/drivers/dma/dpaa2/dpaa2_qdma.c
@@ -1331,6 +1331,35 @@ dpaa2_qdma_vchan_rbp_set(struct qdma_virt_queue *vq,
return 0;
}
+struct dpaa2_qdma_fle_pool_check {
+ uint64_t iova2va_offset;
+ int bad_map;
+ int bad_offset;
+};
+
+static void
+dpaa2_qdma_fle_pool_iova_check(struct rte_mempool *mp __rte_unused,
+ void *opaque, struct rte_mempool_memhdr *memhdr,
+ unsigned int mem_idx __rte_unused)
+{
+ struct dpaa2_qdma_fle_pool_check *check = opaque;
+
+ if (DPAA2_VADDR_TO_IOVA_AND_CHECK(memhdr->addr,
+ memhdr->len) == RTE_BAD_IOVA) {
+ check->bad_map = 1;
+ return;
+ }
+
+ /* The enqueue path converts every FLE address with a single
+ * subtraction of iova2va_offset, so that offset has to hold for
+ * every chunk the objects are taken from. With IOVA as PA and
+ * fragmented hugepages a pool can span chunks with different
+ * VA to IOVA deltas, which would silently produce wrong IOVAs.
+ */
+ if (((uint64_t)memhdr->addr - memhdr->iova) != check->iova2va_offset)
+ check->bad_offset = 1;
+}
+
static int
dpaa2_qdma_vchan_setup(struct rte_dma_dev *dev, uint16_t vchan,
const struct rte_dma_vchan_conf *conf,
@@ -1338,6 +1367,7 @@ dpaa2_qdma_vchan_setup(struct rte_dma_dev *dev, uint16_t vchan,
{
struct dpaa2_dpdmai_dev *dpdmai_dev = dev->data->dev_private;
struct qdma_device *qdma_dev = dpdmai_dev->qdma_dev;
+ struct dpaa2_qdma_fle_pool_check fle_check = {0};
uint32_t pool_size;
char pool_name[64];
int ret;
@@ -1381,6 +1411,20 @@ dpaa2_qdma_vchan_setup(struct rte_dma_dev *dev, uint16_t vchan,
va = qdma_dev->vqs[vchan].fle_pool->mz->addr_64;
qdma_dev->vqs[vchan].fle_iova2va_offset = va - iova;
+ fle_check.iova2va_offset = qdma_dev->vqs[vchan].fle_iova2va_offset;
+ rte_mempool_mem_iter(qdma_dev->vqs[vchan].fle_pool,
+ dpaa2_qdma_fle_pool_iova_check, &fle_check);
+ if (fle_check.bad_map || fle_check.bad_offset) {
+ if (fle_check.bad_map)
+ DPAA2_QDMA_ERR("No IOMMU map for %s", pool_name);
+ else
+ DPAA2_QDMA_ERR("%s spans inconsistent IOVA offsets",
+ pool_name);
+ rte_mempool_free(qdma_dev->vqs[vchan].fle_pool);
+ qdma_dev->vqs[vchan].fle_pool = NULL;
+ return -ENOMEM;
+ }
+
if (qdma_dev->is_silent) {
ret = rte_mempool_get_bulk(qdma_dev->vqs[vchan].fle_pool,
(void **)qdma_dev->vqs[vchan].cntx_sg,
--
2.43.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH v6-S1 6/6] mempool/dpaa2: look up ops index locally in secondary
2026-10-06 15:07 ` [PATCH v6-S1 0/6] " Prashant Gupta
` (4 preceding siblings ...)
2026-10-06 15:07 ` [PATCH v6-S1 5/6] dma/dpaa2: validate FLE pool IOVA mapping at vchan setup Prashant Gupta
@ 2026-10-06 15:07 ` Prashant Gupta
2026-10-07 15:51 ` [PATCH v6-S1 0/6] dpaa2: bus, DMA and mempool base fixes Stephen Hemminger
6 siblings, 0 replies; 30+ messages in thread
From: Prashant Gupta @ 2026-10-06 15:07 UTC (permalink / raw)
To: stephen, dev; +Cc: stable, Jun Yang, Hemant Agrawal
From: Jun Yang <jun.yang@nxp.com>
Secondary processes call rte_dpaa2_mpool_get_ops_idx() but the ops
index was registered only in the primary process, so the function
returned the sentinel RTE_MEMPOOL_MAX_OPS_IDX on every call in a
secondary. dpaa2_sec then compares mb_pool->ops_index against that
sentinel and always takes the MAX_BPID path.
The ops index is process-invariant: mempool ops are registered by a
constructor at library load time in the same link order in every
process. Fix rte_dpaa2_mpool_get_ops_idx() to scan rte_mempool_ops_table
by name ("dpaa2") locally and cache the result. No IPC round-trip is
needed.
Also fix a duplicated word in an error message in rte_hw_mbuf_create_pool
("Only single ops index only" -> "Single ops index only") and improve the
error log in rte_hw_mbuf_free_pool to include the pool name.
Fixes: de6a6e897fe6 ("mempool/dpaa2: add operation index")
Cc: stable@dpdk.org
Signed-off-by: Jun Yang <jun.yang@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Signed-off-by: Prashant Gupta <prashant.gupta_3@nxp.com>
---
drivers/mempool/dpaa2/dpaa2_hw_mempool.c | 25 ++++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)
diff --git a/drivers/mempool/dpaa2/dpaa2_hw_mempool.c b/drivers/mempool/dpaa2/dpaa2_hw_mempool.c
index ee001d8ce0..c2f2aecc2e 100644
--- a/drivers/mempool/dpaa2/dpaa2_hw_mempool.c
+++ b/drivers/mempool/dpaa2/dpaa2_hw_mempool.c
@@ -43,7 +43,25 @@ static int16_t s_dpaa2_pool_ops_idx = RTE_MEMPOOL_MAX_OPS_IDX;
RTE_EXPORT_INTERNAL_SYMBOL(rte_dpaa2_mpool_get_ops_idx)
int rte_dpaa2_mpool_get_ops_idx(void)
{
- return s_dpaa2_pool_ops_idx;
+ uint32_t i;
+
+ if (s_dpaa2_pool_ops_idx != RTE_MEMPOOL_MAX_OPS_IDX)
+ return s_dpaa2_pool_ops_idx;
+
+ /* Mempool ops are registered by constructor in the same order in
+ * every process, so the index is process-invariant. Scan the ops
+ * table locally and cache the result.
+ */
+ for (i = 0; i < rte_mempool_ops_table.num_ops; i++) {
+ if (strcmp(rte_mempool_ops_table.ops[i].name,
+ DPAA2_MEMPOOL_OPS_NAME) == 0) {
+ s_dpaa2_pool_ops_idx = (int16_t)i;
+ return s_dpaa2_pool_ops_idx;
+ }
+ }
+
+ DPAA2_MEMPOOL_ERR("dpaa2 mempool ops not found");
+ return -ENOENT;
}
static int
@@ -128,11 +146,10 @@ rte_hw_mbuf_create_pool(struct rte_mempool *mp)
if (s_dpaa2_pool_ops_idx == RTE_MEMPOOL_MAX_OPS_IDX) {
s_dpaa2_pool_ops_idx = mp->ops_index;
} else if (s_dpaa2_pool_ops_idx != mp->ops_index) {
- DPAA2_MEMPOOL_ERR("Only single ops index only");
+ DPAA2_MEMPOOL_ERR("Single ops index only");
ret = -EINVAL;
goto err4;
}
-
bp_list->next = h_bp_list;
bp_list->mp = mp;
@@ -172,7 +189,7 @@ rte_hw_mbuf_free_pool(struct rte_mempool *mp)
struct dpaa2_dpbp_dev *dpbp_node;
if (!mp->pool_data) {
- DPAA2_MEMPOOL_ERR("Not a valid dpaa2 buffer pool");
+ DPAA2_MEMPOOL_ERR("Not a valid dpaa2 buffer pool %s", mp->name);
return;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 30+ messages in thread
* Re: [PATCH v6-S1 0/6] dpaa2: bus, DMA and mempool base fixes
2026-10-06 15:07 ` [PATCH v6-S1 0/6] " Prashant Gupta
` (5 preceding siblings ...)
2026-10-06 15:07 ` [PATCH v6-S1 6/6] mempool/dpaa2: look up ops index locally in secondary Prashant Gupta
@ 2026-10-07 15:51 ` Stephen Hemminger
6 siblings, 0 replies; 30+ messages in thread
From: Stephen Hemminger @ 2026-10-07 15:51 UTC (permalink / raw)
To: Prashant Gupta; +Cc: dev
On Tue, 6 Oct 2026 20:37:43 +0530
Prashant Gupta <prashant.gupta_3@nxp.com> wrote:
> This series is the first of four that upstream the missing NXP dpaa2
> driver changes. It collects the foundational bus/fslmc, dma/dpaa2 and
> mempool/dpaa2 fixes that the later series build on:
>
> - defer fslmc bus initialization to probe; reduce probe logging
> and skip ignored devices during DPRC population,
> - use memcpy to fill the dpaa2 QDMA completion index ring,
> - release SG FLE on completion ring overflow in the dpaa2 QDMA
> dequeue path,
> - validate the FLE pool IOVA mapping at vchan setup and free the pool
> on failure,
> - resolve the mempool ops index locally in secondary processes by
> scanning rte_mempool_ops_table, removing the need for IPC.
When running AI locally which also has context from previous reviews,
it found a couple of things. I goaded it to be more concise and
provide more concrete suggestions.
Review: [PATCH v6-S1 0/6] DPAA2 fixes
Applies to main, every commit builds with -Dwerror=true.
Patch 5 needs rework, patch 4 a small follow-up. 1-3 look good.
[PATCH 5/6] dma/dpaa2: validate FLE pool IOVA mapping at vchan setup
Error: vchan setup fails on 2M hugepages.
DPAA2_VADDR_TO_IOVA_AND_CHECK() on a whole chunk only succeeds if
the chunk fits in one fslmc dmaseg, and fslmc creates one dmaseg
per memseg (hugepage). The FLE pool is 8192 x 2312 bytes, about
19 MB, so on 2M pages the check always fails.
Also the reference offset comes from fle_pool->mz (the mempool
header), not from the object memory.
Take the offset from the first chunk and compare the rest:
struct dpaa2_qdma_fle_pool_check {
uint64_t iova2va_offset;
bool bad;
};
static void
dpaa2_qdma_fle_pool_iova_check(struct rte_mempool *mp __rte_unused,
void *opaque, struct rte_mempool_memhdr *memhdr,
unsigned int mem_idx)
{
struct dpaa2_qdma_fle_pool_check *check = opaque;
uint64_t offset;
if (memhdr->iova == RTE_BAD_IOVA) {
check->bad = true;
return;
}
offset = (uint64_t)memhdr->addr - memhdr->iova;
if (mem_idx == 0)
check->iova2va_offset = offset;
else if (offset != check->iova2va_offset)
check->bad = true;
}
and in dpaa2_qdma_vchan_setup() drop the mz based iova/va:
rte_mempool_mem_iter(qdma_dev->vqs[vchan].fle_pool,
dpaa2_qdma_fle_pool_iova_check, &fle_check);
if (fle_check.bad) {
DPAA2_QDMA_ERR("%s spans inconsistent IOVA offsets",
pool_name);
ret = -EINVAL;
goto err_pool;
}
qdma_dev->vqs[vchan].fle_iova2va_offset =
fle_check.iova2va_offset;
Warning: the later error paths (both rte_mempool_get_bulk() calls,
ring_cntx_idx alloc) still return with fle_pool allocated, so the
retry case in the commit message is still broken. Send all of them
to one label:
return 0;
err_pool:
rte_mempool_free(qdma_dev->vqs[vchan].fle_pool);
qdma_dev->vqs[vchan].fle_pool = NULL;
return ret;
}
[PATCH 4/6] dma/dpaa2: release SG FLE on completion ring overflow
Warning: the LONG branch still records the FLE before the ring
insert. Make it match the SG branch:
fle_sdd = (void *)(uintptr_t)DPAA2_GET_FD_FLC(fd);
ret = qdma_cntx_idx_ring_eq(qdma_vq->ring_cntx_idx,
&idx, 1, free_space);
if (unlikely(ret != 1)) {
rte_mempool_put(qdma_vq->fle_pool, fle_sdd);
return -ENOSPC;
}
qdma_vq->fle_elem[*fle_elem_nb] = fle_sdd;
(*fle_elem_nb)++;
Warning: drop "This matches how the caller treats a failed dq_fd()
as having consumed nothing." The FD is already pulled from QBMAN,
so on -ENOSPC its completions are lost, not retried.
[PATCH 6/6] mempool/dpaa2: look up ops index locally in secondary
Info: drop the unrelated blank line removal before
bp_list->next; this goes to stable.
^ permalink raw reply [flat|nested] 30+ messages in thread
end of thread, other threads:[~2026-10-07 16:25 UTC | newest]
Thread overview: 30+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-15 11:34 [PATCH v3-S1 0/5] dpaa2: bus, DMA and mempool base fixes Prashant Gupta
2026-09-15 11:34 ` [PATCH v3-S1 1/5] bus/fslmc: defer bus initialization to probe Prashant Gupta
2026-09-15 11:34 ` [PATCH v3-S1 2/5] bus/fslmc: reduce probe-time logging and MC traffic Prashant Gupta
2026-09-15 11:34 ` [PATCH v3-S1 3/5] dma/dpaa2: fix array-bounds warning in dequeue path Prashant Gupta
2026-09-15 11:34 ` [PATCH v3-S1 4/5] dma/dpaa2: validate IOVA in pre-populate helpers Prashant Gupta
2026-09-15 11:34 ` [PATCH v3-S1 5/5] mempool/dpaa2: support ops index from primary in secondary Prashant Gupta
2026-09-15 15:24 ` [PATCH v3-S1 0/5] dpaa2: bus, DMA and mempool base fixes Stephen Hemminger
2026-09-22 9:21 ` [PATCH v4-S1 " Prashant Gupta
2026-09-22 9:21 ` [PATCH v4-S1 1/5] bus/fslmc: defer bus initialization to probe Prashant Gupta
2026-09-22 9:21 ` [PATCH v4-S1 2/5] bus/fslmc: reduce probe-time logging and MC traffic Prashant Gupta
2026-09-22 9:21 ` [PATCH v4-S1 3/5] dma/dpaa2: fix array-bounds warning in dequeue path Prashant Gupta
2026-09-22 9:21 ` [PATCH v4-S1 4/5] dma/dpaa2: validate IOVA in pre-populate helpers Prashant Gupta
2026-09-22 9:21 ` [PATCH v4-S1 5/5] mempool/dpaa2: support ops index from primary in secondary Prashant Gupta
2026-09-22 13:59 ` [PATCH v4-S1 0/5] dpaa2: bus, DMA and mempool base fixes Stephen Hemminger
2026-09-29 14:21 ` [PATCH v5-S1 " Prashant Gupta
2026-09-29 14:21 ` [PATCH v5-S1 1/5] bus/fslmc: defer bus initialization to probe Prashant Gupta
2026-09-29 14:21 ` [PATCH v5-S1 2/5] bus/fslmc: reduce probe-time logging and skip ignored devices Prashant Gupta
2026-09-29 14:21 ` [PATCH v5-S1 3/5] dma/dpaa2: fix array-bounds warning and SG FD double-put Prashant Gupta
2026-09-29 14:21 ` [PATCH v5-S1 4/5] dma/dpaa2: validate FLE pool IOVA mapping at vchan setup Prashant Gupta
2026-09-29 14:21 ` [PATCH v5-S1 5/5] mempool/dpaa2: look up ops index locally in secondary Prashant Gupta
2026-09-29 15:45 ` [PATCH v5-S1 0/5] dpaa2: bus, DMA and mempool base fixes Stephen Hemminger
2026-10-06 14:57 ` [EXT] " Prashant Gupta
2026-10-06 15:07 ` [PATCH v6-S1 0/6] " Prashant Gupta
2026-10-06 15:07 ` [PATCH v6-S1 1/6] bus/fslmc: defer bus initialization to probe Prashant Gupta
2026-10-06 15:07 ` [PATCH v6-S1 2/6] bus/fslmc: reduce probe logging and skip ignored devices Prashant Gupta
2026-10-06 15:07 ` [PATCH v6-S1 3/6] dma/dpaa2: use memcpy to fill completion index ring Prashant Gupta
2026-10-06 15:07 ` [PATCH v6-S1 4/6] dma/dpaa2: release SG FLE on completion ring overflow Prashant Gupta
2026-10-06 15:07 ` [PATCH v6-S1 5/6] dma/dpaa2: validate FLE pool IOVA mapping at vchan setup Prashant Gupta
2026-10-06 15:07 ` [PATCH v6-S1 6/6] mempool/dpaa2: look up ops index locally in secondary Prashant Gupta
2026-10-07 15:51 ` [PATCH v6-S1 0/6] dpaa2: bus, DMA and mempool base fixes Stephen Hemminger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).