diff options
author | Shani Michaeli <shanim@mellanox.com> | 2013-02-06 11:19:09 -0500 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2013-02-21 14:38:43 -0500 |
commit | 61083720702a329ed5952e32bda384e3bbc9093c (patch) | |
tree | e31fb437442c23fdab04f94b69d0c612b870478d | |
parent | b20e519a81d648aebfbb90811743cc86cd469a48 (diff) |
mlx4_core: Propagate MR deregistration failures to caller
MR deregistration fails when memory windows are bound to the MR.
Handle such failures by propagating them to the caller ULP.
Signed-off-by: Haggai Eran <haggaie@mellanox.com>
Signed-off-by: Shani Michaeli <shanim@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
-rw-r--r-- | drivers/infiniband/hw/mlx4/mr.c | 13 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_main.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mr.c | 29 | ||||
-rw-r--r-- | include/linux/mlx4/device.h | 2 |
4 files changed, 33 insertions, 15 deletions
diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c index bbaf6176f207..254e1cf26439 100644 --- a/drivers/infiniband/hw/mlx4/mr.c +++ b/drivers/infiniband/hw/mlx4/mr.c | |||
@@ -68,7 +68,7 @@ struct ib_mr *mlx4_ib_get_dma_mr(struct ib_pd *pd, int acc) | |||
68 | return &mr->ibmr; | 68 | return &mr->ibmr; |
69 | 69 | ||
70 | err_mr: | 70 | err_mr: |
71 | mlx4_mr_free(to_mdev(pd->device)->dev, &mr->mmr); | 71 | (void) mlx4_mr_free(to_mdev(pd->device)->dev, &mr->mmr); |
72 | 72 | ||
73 | err_free: | 73 | err_free: |
74 | kfree(mr); | 74 | kfree(mr); |
@@ -163,7 +163,7 @@ struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, | |||
163 | return &mr->ibmr; | 163 | return &mr->ibmr; |
164 | 164 | ||
165 | err_mr: | 165 | err_mr: |
166 | mlx4_mr_free(to_mdev(pd->device)->dev, &mr->mmr); | 166 | (void) mlx4_mr_free(to_mdev(pd->device)->dev, &mr->mmr); |
167 | 167 | ||
168 | err_umem: | 168 | err_umem: |
169 | ib_umem_release(mr->umem); | 169 | ib_umem_release(mr->umem); |
@@ -177,8 +177,11 @@ err_free: | |||
177 | int mlx4_ib_dereg_mr(struct ib_mr *ibmr) | 177 | int mlx4_ib_dereg_mr(struct ib_mr *ibmr) |
178 | { | 178 | { |
179 | struct mlx4_ib_mr *mr = to_mmr(ibmr); | 179 | struct mlx4_ib_mr *mr = to_mmr(ibmr); |
180 | int ret; | ||
180 | 181 | ||
181 | mlx4_mr_free(to_mdev(ibmr->device)->dev, &mr->mmr); | 182 | ret = mlx4_mr_free(to_mdev(ibmr->device)->dev, &mr->mmr); |
183 | if (ret) | ||
184 | return ret; | ||
182 | if (mr->umem) | 185 | if (mr->umem) |
183 | ib_umem_release(mr->umem); | 186 | ib_umem_release(mr->umem); |
184 | kfree(mr); | 187 | kfree(mr); |
@@ -212,7 +215,7 @@ struct ib_mr *mlx4_ib_alloc_fast_reg_mr(struct ib_pd *pd, | |||
212 | return &mr->ibmr; | 215 | return &mr->ibmr; |
213 | 216 | ||
214 | err_mr: | 217 | err_mr: |
215 | mlx4_mr_free(dev->dev, &mr->mmr); | 218 | (void) mlx4_mr_free(dev->dev, &mr->mmr); |
216 | 219 | ||
217 | err_free: | 220 | err_free: |
218 | kfree(mr); | 221 | kfree(mr); |
@@ -291,7 +294,7 @@ struct ib_fmr *mlx4_ib_fmr_alloc(struct ib_pd *pd, int acc, | |||
291 | return &fmr->ibfmr; | 294 | return &fmr->ibfmr; |
292 | 295 | ||
293 | err_mr: | 296 | err_mr: |
294 | mlx4_mr_free(to_mdev(pd->device)->dev, &fmr->mfmr.mr); | 297 | (void) mlx4_mr_free(to_mdev(pd->device)->dev, &fmr->mfmr.mr); |
295 | 298 | ||
296 | err_free: | 299 | err_free: |
297 | kfree(fmr); | 300 | kfree(fmr); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_main.c b/drivers/net/ethernet/mellanox/mlx4/en_main.c index 3a2b8c65642d..a2987142734d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_main.c | |||
@@ -176,7 +176,7 @@ static void mlx4_en_remove(struct mlx4_dev *dev, void *endev_ptr) | |||
176 | 176 | ||
177 | flush_workqueue(mdev->workqueue); | 177 | flush_workqueue(mdev->workqueue); |
178 | destroy_workqueue(mdev->workqueue); | 178 | destroy_workqueue(mdev->workqueue); |
179 | mlx4_mr_free(dev, &mdev->mr); | 179 | (void) mlx4_mr_free(dev, &mdev->mr); |
180 | iounmap(mdev->uar_map); | 180 | iounmap(mdev->uar_map); |
181 | mlx4_uar_free(dev, &mdev->priv_uar); | 181 | mlx4_uar_free(dev, &mdev->priv_uar); |
182 | mlx4_pd_free(dev, mdev->priv_pdn); | 182 | mlx4_pd_free(dev, mdev->priv_pdn); |
@@ -283,7 +283,7 @@ static void *mlx4_en_add(struct mlx4_dev *dev) | |||
283 | return mdev; | 283 | return mdev; |
284 | 284 | ||
285 | err_mr: | 285 | err_mr: |
286 | mlx4_mr_free(dev, &mdev->mr); | 286 | (void) mlx4_mr_free(dev, &mdev->mr); |
287 | err_map: | 287 | err_map: |
288 | if (!mdev->uar_map) | 288 | if (!mdev->uar_map) |
289 | iounmap(mdev->uar_map); | 289 | iounmap(mdev->uar_map); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c index 49705cf860c6..06b16e4ace80 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mr.c +++ b/drivers/net/ethernet/mellanox/mlx4/mr.c | |||
@@ -442,7 +442,7 @@ int mlx4_mr_alloc(struct mlx4_dev *dev, u32 pd, u64 iova, u64 size, u32 access, | |||
442 | } | 442 | } |
443 | EXPORT_SYMBOL_GPL(mlx4_mr_alloc); | 443 | EXPORT_SYMBOL_GPL(mlx4_mr_alloc); |
444 | 444 | ||
445 | static void mlx4_mr_free_reserved(struct mlx4_dev *dev, struct mlx4_mr *mr) | 445 | static int mlx4_mr_free_reserved(struct mlx4_dev *dev, struct mlx4_mr *mr) |
446 | { | 446 | { |
447 | int err; | 447 | int err; |
448 | 448 | ||
@@ -450,20 +450,31 @@ static void mlx4_mr_free_reserved(struct mlx4_dev *dev, struct mlx4_mr *mr) | |||
450 | err = mlx4_HW2SW_MPT(dev, NULL, | 450 | err = mlx4_HW2SW_MPT(dev, NULL, |
451 | key_to_hw_index(mr->key) & | 451 | key_to_hw_index(mr->key) & |
452 | (dev->caps.num_mpts - 1)); | 452 | (dev->caps.num_mpts - 1)); |
453 | if (err) | 453 | if (err) { |
454 | mlx4_warn(dev, "xxx HW2SW_MPT failed (%d)\n", err); | 454 | mlx4_warn(dev, "HW2SW_MPT failed (%d),", err); |
455 | mlx4_warn(dev, "MR has MWs bound to it.\n"); | ||
456 | return err; | ||
457 | } | ||
455 | 458 | ||
456 | mr->enabled = MLX4_MPT_EN_SW; | 459 | mr->enabled = MLX4_MPT_EN_SW; |
457 | } | 460 | } |
458 | mlx4_mtt_cleanup(dev, &mr->mtt); | 461 | mlx4_mtt_cleanup(dev, &mr->mtt); |
462 | |||
463 | return 0; | ||
459 | } | 464 | } |
460 | 465 | ||
461 | void mlx4_mr_free(struct mlx4_dev *dev, struct mlx4_mr *mr) | 466 | int mlx4_mr_free(struct mlx4_dev *dev, struct mlx4_mr *mr) |
462 | { | 467 | { |
463 | mlx4_mr_free_reserved(dev, mr); | 468 | int ret; |
469 | |||
470 | ret = mlx4_mr_free_reserved(dev, mr); | ||
471 | if (ret) | ||
472 | return ret; | ||
464 | if (mr->enabled) | 473 | if (mr->enabled) |
465 | mlx4_mpt_free_icm(dev, key_to_hw_index(mr->key)); | 474 | mlx4_mpt_free_icm(dev, key_to_hw_index(mr->key)); |
466 | mlx4_mpt_release(dev, key_to_hw_index(mr->key)); | 475 | mlx4_mpt_release(dev, key_to_hw_index(mr->key)); |
476 | |||
477 | return 0; | ||
467 | } | 478 | } |
468 | EXPORT_SYMBOL_GPL(mlx4_mr_free); | 479 | EXPORT_SYMBOL_GPL(mlx4_mr_free); |
469 | 480 | ||
@@ -831,7 +842,7 @@ int mlx4_fmr_alloc(struct mlx4_dev *dev, u32 pd, u32 access, int max_pages, | |||
831 | return 0; | 842 | return 0; |
832 | 843 | ||
833 | err_free: | 844 | err_free: |
834 | mlx4_mr_free(dev, &fmr->mr); | 845 | (void) mlx4_mr_free(dev, &fmr->mr); |
835 | return err; | 846 | return err; |
836 | } | 847 | } |
837 | EXPORT_SYMBOL_GPL(mlx4_fmr_alloc); | 848 | EXPORT_SYMBOL_GPL(mlx4_fmr_alloc); |
@@ -888,10 +899,14 @@ EXPORT_SYMBOL_GPL(mlx4_fmr_unmap); | |||
888 | 899 | ||
889 | int mlx4_fmr_free(struct mlx4_dev *dev, struct mlx4_fmr *fmr) | 900 | int mlx4_fmr_free(struct mlx4_dev *dev, struct mlx4_fmr *fmr) |
890 | { | 901 | { |
902 | int ret; | ||
903 | |||
891 | if (fmr->maps) | 904 | if (fmr->maps) |
892 | return -EBUSY; | 905 | return -EBUSY; |
893 | 906 | ||
894 | mlx4_mr_free(dev, &fmr->mr); | 907 | ret = mlx4_mr_free(dev, &fmr->mr); |
908 | if (ret) | ||
909 | return ret; | ||
895 | fmr->mr.enabled = MLX4_MPT_DISABLED; | 910 | fmr->mr.enabled = MLX4_MPT_DISABLED; |
896 | 911 | ||
897 | return 0; | 912 | return 0; |
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 20ea939c22a6..e9fe8caaf8bb 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h | |||
@@ -801,7 +801,7 @@ u64 mlx4_mtt_addr(struct mlx4_dev *dev, struct mlx4_mtt *mtt); | |||
801 | 801 | ||
802 | int mlx4_mr_alloc(struct mlx4_dev *dev, u32 pd, u64 iova, u64 size, u32 access, | 802 | int mlx4_mr_alloc(struct mlx4_dev *dev, u32 pd, u64 iova, u64 size, u32 access, |
803 | int npages, int page_shift, struct mlx4_mr *mr); | 803 | int npages, int page_shift, struct mlx4_mr *mr); |
804 | void mlx4_mr_free(struct mlx4_dev *dev, struct mlx4_mr *mr); | 804 | int mlx4_mr_free(struct mlx4_dev *dev, struct mlx4_mr *mr); |
805 | int mlx4_mr_enable(struct mlx4_dev *dev, struct mlx4_mr *mr); | 805 | int mlx4_mr_enable(struct mlx4_dev *dev, struct mlx4_mr *mr); |
806 | int mlx4_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt, | 806 | int mlx4_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt, |
807 | int start_index, int npages, u64 *page_list); | 807 | int start_index, int npages, u64 *page_list); |