diff options
Diffstat (limited to 'drivers/infiniband/hw/mlx5/mr.c')
| -rw-r--r-- | drivers/infiniband/hw/mlx5/mr.c | 38 | 
1 files changed, 28 insertions, 10 deletions
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c index 3401f5f6792e..1eff031ef048 100644 --- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c @@ -784,19 +784,37 @@ static int mr_umem_get(struct mlx5_ib_dev *dev, struct ib_udata *udata,  		       int *ncont, int *order)  {  	struct ib_umem *u; -	int err;  	*umem = NULL; -	u = ib_umem_get(udata, start, length, access_flags, 0); -	err = PTR_ERR_OR_ZERO(u); -	if (err) { -		mlx5_ib_dbg(dev, "umem get failed (%d)\n", err); -		return err; +	if (access_flags & IB_ACCESS_ON_DEMAND) { +		struct ib_umem_odp *odp; + +		odp = ib_umem_odp_get(udata, start, length, access_flags); +		if (IS_ERR(odp)) { +			mlx5_ib_dbg(dev, "umem get failed (%ld)\n", +				    PTR_ERR(odp)); +			return PTR_ERR(odp); +		} + +		u = &odp->umem; + +		*page_shift = odp->page_shift; +		*ncont = ib_umem_odp_num_pages(odp); +		*npages = *ncont << (*page_shift - PAGE_SHIFT); +		if (order) +			*order = ilog2(roundup_pow_of_two(*ncont)); +	} else { +		u = ib_umem_get(udata, start, length, access_flags, 0); +		if (IS_ERR(u)) { +			mlx5_ib_dbg(dev, "umem get failed (%ld)\n", PTR_ERR(u)); +			return PTR_ERR(u); +		} + +		mlx5_ib_cont_pages(u, start, MLX5_MKEY_PAGE_SHIFT_MASK, npages, +				   page_shift, ncont, order);  	} -	mlx5_ib_cont_pages(u, start, MLX5_MKEY_PAGE_SHIFT_MASK, npages, -			   page_shift, ncont, order);  	if (!*npages) {  		mlx5_ib_warn(dev, "avoid zero region\n");  		ib_umem_release(u); @@ -1599,7 +1617,7 @@ static void dereg_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr)  		/* Wait for all running page-fault handlers to finish. */  		synchronize_srcu(&dev->mr_srcu);  		/* Destroy all page mappings */ -		if (umem_odp->page_list) +		if (!umem_odp->is_implicit_odp)  			mlx5_ib_invalidate_range(umem_odp,  						 ib_umem_start(umem_odp),  						 ib_umem_end(umem_odp)); @@ -1610,7 +1628,7 @@ static void dereg_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr)  		 * so that there will not be any invalidations in  		 * flight, looking at the *mr struct.  		 */ -		ib_umem_release(umem); +		ib_umem_odp_release(umem_odp);  		atomic_sub(npages, &dev->mdev->priv.reg_pages);  		/* Avoid double-freeing the umem. */  |