]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
RDMA/uverbs: Push out CQ buffer umem processing into a helper
authorJiri Pirko <jiri@nvidia.com>
Fri, 29 May 2026 13:43:01 +0000 (15:43 +0200)
committerJason Gunthorpe <jgg@nvidia.com>
Fri, 29 May 2026 23:19:58 +0000 (20:19 -0300)
Extract the UVERBS_ATTR_CREATE_CQ_BUFFER_* parser from the CQ
create handler into uverbs_create_cq_get_buffer_desc(), and wrap
it in ib_umem_get_cq_tmp(), the umem-producing helper the cq_create
handler now calls.

ib_umem_get_cq_tmp() is temporary; subsequent patches replace it
with driver-owned ib_umem_get_cq_buf*() wrappers built on the
same parser, and remove it once all CQ drivers have switched.

Link: https://patch.msgid.link/r/20260529134312.2836341-6-jiri@resnulli.us
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/infiniband/core/umem.c
drivers/infiniband/core/uverbs_std_types_cq.c
include/rdma/ib_umem.h

index 680bdbbc59848a929bef1ae1c07fb10cb9fdd8b2..d364a5ab055805e11d2c31b8ad45cf5023f62a61 100644 (file)
@@ -497,6 +497,85 @@ struct ib_umem *ib_umem_get_attr_or_va(struct ib_device *device,
 }
 EXPORT_SYMBOL(ib_umem_get_attr_or_va);
 
+static int uverbs_create_cq_get_buffer_desc(struct uverbs_attr_bundle *attrs,
+                                           struct ib_uverbs_buffer_desc *desc)
+{
+       struct ib_device *ib_dev = attrs->context->device;
+       int ret;
+
+       if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_VA)) {
+               ret = uverbs_copy_from(&desc->addr, attrs,
+                                      UVERBS_ATTR_CREATE_CQ_BUFFER_VA);
+               if (ret)
+                       return ret;
+               ret = uverbs_copy_from(&desc->length, attrs,
+                                      UVERBS_ATTR_CREATE_CQ_BUFFER_LENGTH);
+               if (ret)
+                       return ret;
+               if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_FD) ||
+                   uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_OFFSET) ||
+                   !ib_dev->ops.create_user_cq)
+                       return -EINVAL;
+               desc->type = IB_UVERBS_BUFFER_TYPE_VA;
+               return 0;
+       }
+
+       if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_FD)) {
+               ret = uverbs_get_raw_fd(&desc->fd, attrs,
+                                       UVERBS_ATTR_CREATE_CQ_BUFFER_FD);
+               if (ret)
+                       return ret;
+
+               ret = uverbs_copy_from(&desc->addr, attrs,
+                                      UVERBS_ATTR_CREATE_CQ_BUFFER_OFFSET);
+               if (ret)
+                       return ret;
+               ret = uverbs_copy_from(&desc->length, attrs,
+                                      UVERBS_ATTR_CREATE_CQ_BUFFER_LENGTH);
+               if (ret)
+                       return ret;
+               if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_VA) ||
+                   !ib_dev->ops.create_user_cq)
+                       return -EINVAL;
+               desc->type = IB_UVERBS_BUFFER_TYPE_DMABUF;
+               return 0;
+       }
+
+       if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_OFFSET) ||
+           uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_LENGTH))
+               return -EINVAL;
+       return -ENODATA;
+}
+
+/**
+ * ib_umem_get_cq_tmp - Temporary CQ buffer umem getter.
+ * @device: IB device.
+ * @attrs:  uverbs attribute bundle.
+ *
+ * Pins a CQ buffer described by the legacy CQ buffer attributes.
+ * Returns NULL when none are supplied.
+ *
+ * Will be removed once all CQ drivers have switched to get
+ * their buffer directly.
+ *
+ * Return: caller-owned umem on success; NULL when no legacy attribute
+ * is supplied; ERR_PTR(...) on error.
+ */
+struct ib_umem *ib_umem_get_cq_tmp(struct ib_device *device,
+                                  struct uverbs_attr_bundle *attrs)
+{
+       struct ib_uverbs_buffer_desc desc = {};
+       int ret;
+
+       ret = uverbs_create_cq_get_buffer_desc(attrs, &desc);
+       if (ret == -ENODATA)
+               return NULL;
+       if (ret)
+               return ERR_PTR(ret);
+       return ib_umem_get_desc(device, &desc, IB_ACCESS_LOCAL_WRITE);
+}
+EXPORT_SYMBOL(ib_umem_get_cq_tmp);
+
 /**
  * ib_umem_release - release pinned memory
  * @umem: umem struct to release
index 1a6bc8baa52be5f0ff22afab603c458dc3493a79..711bad0aa8a3fcc0783e02a92e889f4f1904764c 100644 (file)
@@ -66,16 +66,11 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(
                typeof(*obj), uevent.uobject);
        struct ib_uverbs_completion_event_file *ev_file = NULL;
        struct ib_device *ib_dev = attrs->context->device;
-       struct ib_umem_dmabuf *umem_dmabuf;
        struct ib_cq_init_attr attr = {};
        struct ib_uobject *ev_file_uobj;
        struct ib_umem *umem = NULL;
-       u64 buffer_length;
-       u64 buffer_offset;
        struct ib_cq *cq;
        u64 user_handle;
-       u64 buffer_va;
-       int buffer_fd;
        int ret;
 
        if ((!ib_dev->ops.create_cq && !ib_dev->ops.create_user_cq) ||
@@ -122,58 +117,9 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(
        INIT_LIST_HEAD(&obj->comp_list);
        INIT_LIST_HEAD(&obj->uevent.event_list);
 
-       if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_VA)) {
-
-               ret = uverbs_copy_from(&buffer_va, attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_VA);
-               if (ret)
-                       goto err_event_file;
-
-               ret = uverbs_copy_from(&buffer_length, attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_LENGTH);
-               if (ret)
-                       goto err_event_file;
-
-               if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_FD) ||
-                   uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_OFFSET) ||
-                   !ib_dev->ops.create_user_cq) {
-                       ret = -EINVAL;
-                       goto err_event_file;
-               }
-
-               umem = ib_umem_get_va(ib_dev, buffer_va, buffer_length, IB_ACCESS_LOCAL_WRITE);
-               if (IS_ERR(umem)) {
-                       ret = PTR_ERR(umem);
-                       goto err_event_file;
-               }
-       } else if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_FD)) {
-
-               ret = uverbs_get_raw_fd(&buffer_fd, attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_FD);
-               if (ret)
-                       goto err_event_file;
-
-               ret = uverbs_copy_from(&buffer_offset, attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_OFFSET);
-               if (ret)
-                       goto err_event_file;
-
-               ret = uverbs_copy_from(&buffer_length, attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_LENGTH);
-               if (ret)
-                       goto err_event_file;
-
-               if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_VA) ||
-                   !ib_dev->ops.create_user_cq) {
-                       ret = -EINVAL;
-                       goto err_event_file;
-               }
-
-               umem_dmabuf = ib_umem_dmabuf_get_pinned(ib_dev, buffer_offset, buffer_length,
-                                                       buffer_fd, IB_ACCESS_LOCAL_WRITE);
-               if (IS_ERR(umem_dmabuf)) {
-                       ret = PTR_ERR(umem_dmabuf);
-                       goto err_event_file;
-               }
-               umem = &umem_dmabuf->umem;
-       } else if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_OFFSET) ||
-                  uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_LENGTH)) {
-               ret = -EINVAL;
+       umem = ib_umem_get_cq_tmp(ib_dev, attrs);
+       if (IS_ERR(umem)) {
+               ret = PTR_ERR(umem);
                goto err_event_file;
        }
 
index 908eafa52840e0d2f0117452605e38205416356c..0d6e90a35f3abd4ea079911ad9706caa241ea620 100644 (file)
@@ -90,6 +90,8 @@ struct ib_umem *ib_umem_get_attr_or_va(struct ib_device *device,
                                       const struct uverbs_attr_bundle *attrs,
                                       u16 attr_id, u64 addr, size_t size,
                                       int access);
+struct ib_umem *ib_umem_get_cq_tmp(struct ib_device *device,
+                                  struct uverbs_attr_bundle *attrs);
 
 static inline struct ib_umem *ib_umem_get_va(struct ib_device *device,
                                             unsigned long addr, size_t size,
@@ -207,6 +209,11 @@ ib_umem_get_attr_or_va(struct ib_device *device,
 {
        return ERR_PTR(-EOPNOTSUPP);
 }
+static inline struct ib_umem *
+ib_umem_get_cq_tmp(struct ib_device *device, struct uverbs_attr_bundle *attrs)
+{
+       return ERR_PTR(-EOPNOTSUPP);
+}
 static inline void ib_umem_release(struct ib_umem *umem) { }
 static inline int ib_umem_copy_from(void *dst, struct ib_umem *umem, size_t offset,
                                    size_t length) {