Skip to content

Commit 096f7e7

Browse files
haggaierolandd
authored andcommitted
IB/mlx5: Fix error handling in reg_umr
If ib_post_send fails when posting the UMR work request in reg_umr, the code doesn't release the temporary pas buffer allocated, and doesn't dma_unmap it. Signed-off-by: Haggai Eran <[email protected]> Signed-off-by: Roland Dreier <[email protected]>
1 parent c7f44fb commit 096f7e7

File tree

1 file changed

+16
-15
lines changed
  • drivers/infiniband/hw/mlx5

1 file changed

+16
-15
lines changed

drivers/infiniband/hw/mlx5/mr.c

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ static struct mlx5_ib_mr *reg_umr(struct ib_pd *pd, struct ib_umem *umem,
730730
struct mlx5_ib_mr *mr;
731731
struct ib_sge sg;
732732
int size = sizeof(u64) * npages;
733-
int err;
733+
int err = 0;
734734
int i;
735735

736736
for (i = 0; i < 1; i++) {
@@ -751,7 +751,7 @@ static struct mlx5_ib_mr *reg_umr(struct ib_pd *pd, struct ib_umem *umem,
751751
mr->pas = kmalloc(size + MLX5_UMR_ALIGN - 1, GFP_KERNEL);
752752
if (!mr->pas) {
753753
err = -ENOMEM;
754-
goto error;
754+
goto free_mr;
755755
}
756756

757757
mlx5_ib_populate_pas(dev, umem, page_shift,
@@ -760,9 +760,8 @@ static struct mlx5_ib_mr *reg_umr(struct ib_pd *pd, struct ib_umem *umem,
760760
mr->dma = dma_map_single(ddev, mr_align(mr->pas, MLX5_UMR_ALIGN), size,
761761
DMA_TO_DEVICE);
762762
if (dma_mapping_error(ddev, mr->dma)) {
763-
kfree(mr->pas);
764763
err = -ENOMEM;
765-
goto error;
764+
goto free_pas;
766765
}
767766

768767
memset(&wr, 0, sizeof(wr));
@@ -778,26 +777,28 @@ static struct mlx5_ib_mr *reg_umr(struct ib_pd *pd, struct ib_umem *umem,
778777
err = ib_post_send(umrc->qp, &wr, &bad);
779778
if (err) {
780779
mlx5_ib_warn(dev, "post send failed, err %d\n", err);
781-
up(&umrc->sem);
782-
goto error;
780+
goto unmap_dma;
783781
}
784782
wait_for_completion(&mr->done);
785-
up(&umrc->sem);
783+
if (mr->status != IB_WC_SUCCESS) {
784+
mlx5_ib_warn(dev, "reg umr failed\n");
785+
err = -EFAULT;
786+
}
786787

788+
unmap_dma:
789+
up(&umrc->sem);
787790
dma_unmap_single(ddev, mr->dma, size, DMA_TO_DEVICE);
791+
792+
free_pas:
788793
kfree(mr->pas);
789794

790-
if (mr->status != IB_WC_SUCCESS) {
791-
mlx5_ib_warn(dev, "reg umr failed\n");
792-
err = -EFAULT;
793-
goto error;
795+
free_mr:
796+
if (err) {
797+
free_cached_mr(dev, mr);
798+
return ERR_PTR(err);
794799
}
795800

796801
return mr;
797-
798-
error:
799-
free_cached_mr(dev, mr);
800-
return ERR_PTR(err);
801802
}
802803

803804
static struct mlx5_ib_mr *reg_create(struct ib_pd *pd, u64 virt_addr,

0 commit comments

Comments
 (0)