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.

No functional change.

Signed-off-by: Jun Yang <[email protected]>
Signed-off-by: Prashant Gupta <[email protected]>
---
 drivers/dma/dpaa2/dpaa2_qdma.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/dma/dpaa2/dpaa2_qdma.c b/drivers/dma/dpaa2/dpaa2_qdma.c
index 7d3f3d2003..e8ec9cddfc 100644
--- a/drivers/dma/dpaa2/dpaa2_qdma.c
+++ b/drivers/dma/dpaa2/dpaa2_qdma.c
@@ -954,26 +954,30 @@ dpaa2_qdma_dq_fd(const struct qbman_fd *fd,
        if (type == DPAA2_QDMA_FD_LONG) {
                idx = DPAA2_QDMA_FD_ATT_CNTX(att);
                fle_sdd = (void *)(uintptr_t)DPAA2_GET_FD_FLC(fd);
-               qdma_vq->fle_elem[*fle_elem_nb] = fle_sdd;
-               (*fle_elem_nb)++;
                ret = qdma_cntx_idx_ring_eq(qdma_vq->ring_cntx_idx,
                                &idx, 1, free_space);
-               if (unlikely(ret != 1))
+               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)++;
 
                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,
                                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

Reply via email to