]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blobdiff - drivers/infiniband/hw/mlx5/mr.c
Merge tag 'for-linus-hmm' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
[mirror_ubuntu-hirsute-kernel.git] / drivers / infiniband / hw / mlx5 / mr.c
index 3401f5f6792e6bb79e472f6411eade5c2d1e2dab..1eff031ef04842f06ab4d088b04a610b9388aa1b 100644 (file)
@@ -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. */