From: Yishai Hadas yishaih@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-leon@kernel.org Cc: stable@vger.kernel.org # 3.19 Fixes: 968e78dd9644 ("IB/mlx5: Enhance UMR support to allow partial page table update") Signed-off-by: Yishai Hadas yishaih@mellanox.com Reviewed-by: Artemy Kovalyov artemyko@mellanox.com Signed-off-by: Leon Romanovsky leonro@mellanox.com Reviewed-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Greg Kroah-Hartman gregkh@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 @@ -427,6 +427,7 @@ struct mlx5_umr_wr { u64 length; int access_flags; u32 mkey; + u8 ignore_free_state:1; };
static inline struct mlx5_umr_wr *umr_wr(struct ib_send_wr *wr) --- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c @@ -1302,10 +1302,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 @@ -3265,10 +3265,14 @@ static void set_reg_umr_segment(struct m
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) {