On Tue, 6 Oct 2026 20:37:48 +0530 Prashant Gupta <[email protected]> wrote:
> From: Gagandeep Singh <[email protected]> > > 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 <[email protected]> > Signed-off-by: Prashant Gupta <[email protected]> > --- This AI review item seems serious enough that a new version is needed. [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; }

