RDMA/mlx5: Split ODP mkey search logic
authorMichael Guralnik <michaelgur@nvidia.com>
Mon, 9 Sep 2024 10:05:01 +0000 (13:05 +0300)
committerLeon Romanovsky <leon@kernel.org>
Wed, 11 Sep 2024 11:56:25 +0000 (14:56 +0300)
Split the search for the ODP mkey when handling an rdma type page fault to
a helper function, later to be used in other page fault types.

Signed-off-by: Michael Guralnik <michaelgur@nvidia.com>
Link: https://patch.msgid.link/20240909100504.29797-6-michaelgur@nvidia.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
drivers/infiniband/hw/mlx5/odp.c

index 20ad2616bed0ecd61477f9e0bfaf7314784040cb..05b92f4cac0ebbc32ec8dbe3c36569d7fd3a01f6 100644 (file)
@@ -819,6 +819,27 @@ static bool mkey_is_eq(struct mlx5_ib_mkey *mmkey, u32 key)
        return mmkey->key == key;
 }
 
+static struct mlx5_ib_mkey *find_odp_mkey(struct mlx5_ib_dev *dev, u32 key)
+{
+       struct mlx5_ib_mkey *mmkey;
+
+       xa_lock(&dev->odp_mkeys);
+       mmkey = xa_load(&dev->odp_mkeys, mlx5_base_mkey(key));
+       if (!mmkey) {
+               mmkey = ERR_PTR(-ENOENT);
+               goto out;
+       }
+       if (!mkey_is_eq(mmkey, key)) {
+               mmkey = ERR_PTR(-EFAULT);
+               goto out;
+       }
+       refcount_inc(&mmkey->usecount);
+out:
+       xa_unlock(&dev->odp_mkeys);
+
+       return mmkey;
+}
+
 /*
  * Handle a single data segment in a page-fault WQE or RDMA region.
  *
@@ -846,32 +867,24 @@ static int pagefault_single_data_segment(struct mlx5_ib_dev *dev,
 
        io_virt += *bytes_committed;
        bcnt -= *bytes_committed;
-
 next_mr:
-       xa_lock(&dev->odp_mkeys);
-       mmkey = xa_load(&dev->odp_mkeys, mlx5_base_mkey(key));
-       if (!mmkey) {
-               xa_unlock(&dev->odp_mkeys);
-               mlx5_ib_dbg(
-                       dev,
-                       "skipping non ODP MR (lkey=0x%06x) in page fault handler.\n",
-                       key);
-               if (bytes_mapped)
-                       *bytes_mapped += bcnt;
-               /*
-                * The user could specify a SGL with multiple lkeys and only
-                * some of them are ODP. Treat the non-ODP ones as fully
-                * faulted.
-                */
-               ret = 0;
-               goto end;
-       }
-       refcount_inc(&mmkey->usecount);
-       xa_unlock(&dev->odp_mkeys);
-
-       if (!mkey_is_eq(mmkey, key)) {
-               mlx5_ib_dbg(dev, "failed to find mkey %x\n", key);
-               ret = -EFAULT;
+       mmkey = find_odp_mkey(dev, key);
+       if (IS_ERR(mmkey)) {
+               ret = PTR_ERR(mmkey);
+               if (ret == -ENOENT) {
+                       mlx5_ib_dbg(
+                               dev,
+                               "skipping non ODP MR (lkey=0x%06x) in page fault handler.\n",
+                               key);
+                       if (bytes_mapped)
+                               *bytes_mapped += bcnt;
+                       /*
+                        * The user could specify a SGL with multiple lkeys and
+                        * only some of them are ODP. Treat the non-ODP ones as
+                        * fully faulted.
+                        */
+                       ret = 0;
+               }
                goto end;
        }
 
@@ -966,7 +979,7 @@ next_mr:
        }
 
 end:
-       if (mmkey)
+       if (!IS_ERR(mmkey))
                mlx5r_deref_odp_mkey(mmkey);
        while (head) {
                frame = head;