RDMA/mlx5: Fix a race for DMABUF MR which can lead to CQE with error
This patch addresses a potential race condition for a DMABUF MR that can
result in a CQE with an error on the UMR QP.
During the __mlx5_ib_dereg_mr() flow, the following sequence of calls
occurs:
mlx5_revoke_mr()
mlx5r_umr_revoke_mr()
mlx5r_umr_post_send_wait()
At this point, the lkey is freed from the hardware's perspective.
However, concurrently, mlx5_ib_dmabuf_invalidate_cb() might be triggered
by another task attempting to invalidate the MR having that freed lkey.
Since the lkey has already been freed, this can lead to a CQE error,
causing the UMR QP to enter an error state.
To resolve this race condition, the dma_resv_lock() which was hold as
part of the mlx5_ib_dmabuf_invalidate_cb() is now also acquired as part
of the mlx5_revoke_mr() scope.
Upon a successful revoke, we set umem_dmabuf->private which points to
that MR to NULL, preventing any further invalidation attempts on its
lkey.
Fixes: e6fb246cca
("RDMA/mlx5: Consolidate MR destruction to mlx5_ib_dereg_mr()")
Signed-off-by: Yishai Hadas <yishaih@nvidia.com>
Reviewed-by: Artemy Kovalyov <artemyko@mnvidia.com>
Link: https://patch.msgid.link/70617067abbfaa0c816a2544c922e7f4346def58.1738587016.git.leon@kernel.org
Signed-off-by: Leon Romanovsky <leon@kernel.org>
This commit is contained in:
parent
12d044770e
commit
cc668a11e6
1 changed files with 12 additions and 1 deletions
|
@ -1550,7 +1550,7 @@ static void mlx5_ib_dmabuf_invalidate_cb(struct dma_buf_attachment *attach)
|
|||
|
||||
dma_resv_assert_held(umem_dmabuf->attach->dmabuf->resv);
|
||||
|
||||
if (!umem_dmabuf->sgt)
|
||||
if (!umem_dmabuf->sgt || !mr)
|
||||
return;
|
||||
|
||||
mlx5r_umr_update_mr_pas(mr, MLX5_IB_UPD_XLT_ZAP);
|
||||
|
@ -2022,11 +2022,16 @@ static int mlx5_revoke_mr(struct mlx5_ib_mr *mr)
|
|||
struct mlx5_ib_dev *dev = to_mdev(mr->ibmr.device);
|
||||
struct mlx5_cache_ent *ent = mr->mmkey.cache_ent;
|
||||
bool is_odp = is_odp_mr(mr);
|
||||
bool is_odp_dma_buf = is_dmabuf_mr(mr) &&
|
||||
!to_ib_umem_dmabuf(mr->umem)->pinned;
|
||||
int ret = 0;
|
||||
|
||||
if (is_odp)
|
||||
mutex_lock(&to_ib_umem_odp(mr->umem)->umem_mutex);
|
||||
|
||||
if (is_odp_dma_buf)
|
||||
dma_resv_lock(to_ib_umem_dmabuf(mr->umem)->attach->dmabuf->resv, NULL);
|
||||
|
||||
if (mr->mmkey.cacheable && !mlx5r_umr_revoke_mr(mr) && !cache_ent_find_and_store(dev, mr)) {
|
||||
ent = mr->mmkey.cache_ent;
|
||||
/* upon storing to a clean temp entry - schedule its cleanup */
|
||||
|
@ -2054,6 +2059,12 @@ out:
|
|||
mutex_unlock(&to_ib_umem_odp(mr->umem)->umem_mutex);
|
||||
}
|
||||
|
||||
if (is_odp_dma_buf) {
|
||||
if (!ret)
|
||||
to_ib_umem_dmabuf(mr->umem)->private = NULL;
|
||||
dma_resv_unlock(to_ib_umem_dmabuf(mr->umem)->attach->dmabuf->resv);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue