From: Jun Yang <[email protected]> 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 <[email protected]> Signed-off-by: Prashant Gupta <[email protected]> --- 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

