From: Yishai Hadas <yish...@mellanox.com>

commit 6a053953739d23694474a5f9c81d1a30093da81a upstream.

Fix unreg_umr to ignore the mkey state and do not fail if was freed.  This
prevents a case that a user space application already changed the mkey
state to free and then the UMR operation will fail leaving the mkey in an
inappropriate state.

Link: https://lore.kernel.org/r/20190723065733.4899-3-l...@kernel.org
Cc: <sta...@vger.kernel.org> # 3.19
Fixes: 968e78dd9644 ("IB/mlx5: Enhance UMR support to allow partial page table 
update")
Signed-off-by: Yishai Hadas <yish...@mellanox.com>
Reviewed-by: Artemy Kovalyov <artem...@mellanox.com>
Signed-off-by: Leon Romanovsky <leo...@mellanox.com>
Reviewed-by: Jason Gunthorpe <j...@mellanox.com>
Signed-off-by: Jason Gunthorpe <j...@mellanox.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
 drivers/infiniband/hw/mlx5/mlx5_ib.h |    1 +
 drivers/infiniband/hw/mlx5/mr.c      |    4 ++--
 drivers/infiniband/hw/mlx5/qp.c      |   12 ++++++++----
 3 files changed, 11 insertions(+), 6 deletions(-)

--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -467,6 +467,7 @@ struct mlx5_umr_wr {
        u64                             length;
        int                             access_flags;
        u32                             mkey;
+       u8                              ignore_free_state:1;
 };
 
 static inline const struct mlx5_umr_wr *umr_wr(const struct ib_send_wr *wr)
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@ -1407,10 +1407,10 @@ static int unreg_umr(struct mlx5_ib_dev
        if (mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)
                return 0;
 
-       umrwr.wr.send_flags = MLX5_IB_SEND_UMR_DISABLE_MR |
-                             MLX5_IB_SEND_UMR_FAIL_IF_FREE;
+       umrwr.wr.send_flags = MLX5_IB_SEND_UMR_DISABLE_MR;
        umrwr.wr.opcode = MLX5_IB_WR_UMR;
        umrwr.mkey = mr->mmkey.key;
+       umrwr.ignore_free_state = 1;
 
        return mlx5_ib_post_send_wait(dev, &umrwr);
 }
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -3717,10 +3717,14 @@ static int set_reg_umr_segment(struct ml
 
        memset(umr, 0, sizeof(*umr));
 
-       if (wr->send_flags & MLX5_IB_SEND_UMR_FAIL_IF_FREE)
-               umr->flags = MLX5_UMR_CHECK_FREE; /* fail if free */
-       else
-               umr->flags = MLX5_UMR_CHECK_NOT_FREE; /* fail if not free */
+       if (!umrwr->ignore_free_state) {
+               if (wr->send_flags & MLX5_IB_SEND_UMR_FAIL_IF_FREE)
+                        /* fail if free */
+                       umr->flags = MLX5_UMR_CHECK_FREE;
+               else
+                       /* fail if not free */
+                       umr->flags = MLX5_UMR_CHECK_NOT_FREE;
+       }
 
        umr->xlt_octowords = cpu_to_be16(get_xlt_octo(umrwr->xlt_size));
        if (wr->send_flags & MLX5_IB_SEND_UMR_UPDATE_XLT) {


Reply via email to