Re: [PATCH 14/15] RDMA/mlx5: Do not race with mlx5_ib_invalidate_range during create and destroy

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Oct 09, 2019 at 01:09:34PM -0300, Jason Gunthorpe wrote:
> diff --git a/drivers/infiniband/hw/mlx5/odp.c b/drivers/infiniband/hw/mlx5/odp.c
> index 66523313c3e46c..fd2306aff78ad7 100644
> +++ b/drivers/infiniband/hw/mlx5/odp.c
> @@ -144,6 +144,32 @@ void mlx5_odp_populate_klm(struct mlx5_klm *pklm, size_t idx, size_t nentries,
>  	}
>  }
>  
> +static void dma_fence_odp_mr(struct mlx5_ib_mr *mr)
> +{
> +	struct ib_umem_odp *odp = to_ib_umem_odp(mr->umem);
> +
> +	/* Ensure mlx5_ib_invalidate_range() will not touch the MR any more */
> +	mutex_lock(&odp->umem_mutex);
> +	if (odp->npages) {
> +		/*
> +		 * If not cached then the caller had to do clean_mrs first to
> +		 * fence the mkey.
> +		 */
> +		if (mr->allocated_from_cache) {
> +			mlx5_mr_cache_invalidate(mr);
> +		} else {
> +			/* clean_mr() */
> +			mlx5_core_destroy_mkey(mr->dev->mdev, &mr->mmkey);
> +			WARN_ON(mr->descs);
> +		}
> +		ib_umem_odp_unmap_dma_pages(odp, ib_umem_start(odp),
> +					    ib_umem_end(odp));
> +		WARN_ON(odp->npages);
> +	}
> +	odp->private = NULL;
> +	mutex_unlock(&odp->umem_mutex);

The new mmu notifier debugging catches that mlx5_core_destroy_mkey()
allocates as GFP_KERNEL and cannot be called under umem_mutex, so this
needs to be reworked.

I think to rely on mlx5_mr_cache_invalidate() to fence the DMA, then
destroy out of the lock:

diff --git a/drivers/infiniband/hw/mlx5/odp.c b/drivers/infiniband/hw/mlx5/odp.c
index 74c45356d54007..f713eb82eeead4 100644
--- a/drivers/infiniband/hw/mlx5/odp.c
+++ b/drivers/infiniband/hw/mlx5/odp.c
@@ -151,23 +151,18 @@ static void dma_fence_odp_mr(struct mlx5_ib_mr *mr)
 	/* Ensure mlx5_ib_invalidate_range() will not touch the MR any more */
 	mutex_lock(&odp->umem_mutex);
 	if (odp->npages) {
-		/*
-		 * If not cached then the caller had to do clean_mrs first to
-		 * fence the mkey.
-		 */
-		if (mr->allocated_from_cache) {
-			mlx5_mr_cache_invalidate(mr);
-		} else {
-			/* clean_mr() */
-			mlx5_core_destroy_mkey(mr->dev->mdev, &mr->mmkey);
-			WARN_ON(mr->descs);
-		}
+		mlx5_mr_cache_invalidate(mr);
 		ib_umem_odp_unmap_dma_pages(odp, ib_umem_start(odp),
 					    ib_umem_end(odp));
 		WARN_ON(odp->npages);
 	}
 	odp->private = NULL;
 	mutex_unlock(&odp->umem_mutex);
+
+	if (!mr->allocated_from_cache) {
+		mlx5_core_destroy_mkey(mr->dev->mdev, &mr->mmkey);
+		WARN_ON(mr->descs);
+	}
 }
 
 /*



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux