Skip to content

Commit dc202c5

Browse files
YonatanNachumrleon
authored andcommitted
RDMA/efa: Fix wrong resources deallocation order
When trying to destroy QP or CQ, we first decrease the refcount and potentially free memory regions allocated for the object and then request the device to destroy the object. If the device fails, the object isn't fully destroyed so the user/IB core can try to destroy the object again which will lead to underflow when trying to decrease an already zeroed refcount. Deallocate resources in reverse order of allocating them to safely free them. Fixes: ff6629f ("RDMA/efa: Do not delay freeing of DMA pages") Reviewed-by: Michael Margolin <[email protected]> Reviewed-by: Yossi Leybovich <[email protected]> Signed-off-by: Yonatan Nachum <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Leon Romanovsky <[email protected]>
1 parent 9dfccb6 commit dc202c5

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

drivers/infiniband/hw/efa/efa_verbs.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -453,12 +453,12 @@ int efa_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
453453

454454
ibdev_dbg(&dev->ibdev, "Destroy qp[%u]\n", ibqp->qp_num);
455455

456-
efa_qp_user_mmap_entries_remove(qp);
457-
458456
err = efa_destroy_qp_handle(dev, qp->qp_handle);
459457
if (err)
460458
return err;
461459

460+
efa_qp_user_mmap_entries_remove(qp);
461+
462462
if (qp->rq_cpu_addr) {
463463
ibdev_dbg(&dev->ibdev,
464464
"qp->cpu_addr[0x%p] freed: size[%lu], dma[%pad]\n",
@@ -1017,8 +1017,8 @@ int efa_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
10171017
"Destroy cq[%d] virt[0x%p] freed: size[%lu], dma[%pad]\n",
10181018
cq->cq_idx, cq->cpu_addr, cq->size, &cq->dma_addr);
10191019

1020-
efa_cq_user_mmap_entries_remove(cq);
10211020
efa_destroy_cq_idx(dev, cq->cq_idx);
1021+
efa_cq_user_mmap_entries_remove(cq);
10221022
if (cq->eq) {
10231023
xa_erase(&dev->cqs_xa, cq->cq_idx);
10241024
synchronize_irq(cq->eq->irq.irqn);

0 commit comments

Comments
 (0)