summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/core/umem.c57
-rw-r--r--drivers/infiniband/core/uverbs_std_types_cq.c2
-rw-r--r--include/rdma/ib_umem.h20
-rw-r--r--include/uapi/rdma/ib_user_ioctl_cmds.h1
4 files changed, 79 insertions, 1 deletions
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index d364a5ab0558..b3261b924a71 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -497,7 +497,7 @@ 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,
+static int uverbs_create_cq_get_buffer_desc(const struct uverbs_attr_bundle *attrs,
struct ib_uverbs_buffer_desc *desc)
{
struct ib_device *ib_dev = attrs->context->device;
@@ -548,6 +548,61 @@ static int uverbs_create_cq_get_buffer_desc(struct uverbs_attr_bundle *attrs,
}
/**
+ * ib_umem_get_cq_buf - Pin a CQ buffer umem from per-command attributes.
+ * @device: IB device.
+ * @attrs: uverbs attribute bundle (may be NULL).
+ * @size: minimum required CQ buffer length.
+ * @access: IB access flags.
+ *
+ * Resolves the CQ buffer from the new UMEM attribute or the legacy
+ * CQ buffer attributes. There is no UHW VA fallback, so the caller
+ * must arrange its own backing (typically an in-kernel allocation)
+ * when no source is available.
+ *
+ * Return: caller-owned umem on success; NULL when no source supplied
+ * a buffer; ERR_PTR(...) on error.
+ */
+struct ib_umem *ib_umem_get_cq_buf(struct ib_device *device,
+ const struct uverbs_attr_bundle *attrs,
+ size_t size, int access)
+{
+ return ib_umem_get_from_attrs(device, attrs,
+ UVERBS_ATTR_CREATE_CQ_BUF_UMEM,
+ uverbs_create_cq_get_buffer_desc,
+ size, access);
+}
+EXPORT_SYMBOL(ib_umem_get_cq_buf);
+
+/**
+ * ib_umem_get_cq_buf_or_va - Pin a CQ buffer umem with UHW VA fallback.
+ * @device: IB device.
+ * @attrs: uverbs attribute bundle (may be NULL).
+ * @addr: UHW user VA used when no per-command attribute matched.
+ * @size: on the attr / legacy paths, the minimum required umem length
+ * validated post-pin; on the VA fallback path, the length to pin.
+ * @access: IB access flags.
+ *
+ * Like ib_umem_get_cq_buf(), but pins @addr/@size when neither the
+ * UMEM attribute nor the legacy CQ buffer attributes are supplied.
+ *
+ * See ib_umem_get_attr_or_va() for the note on @size's dual role and
+ * the migration path for drivers that would distinguish a user-supplied
+ * length from a driver-computed minimum.
+ *
+ * Return: caller-owned umem on success, ERR_PTR(...) on error.
+ */
+struct ib_umem *ib_umem_get_cq_buf_or_va(struct ib_device *device,
+ const struct uverbs_attr_bundle *attrs,
+ u64 addr, size_t size, int access)
+{
+ return ib_umem_get_from_attrs_or_va(device, attrs,
+ UVERBS_ATTR_CREATE_CQ_BUF_UMEM,
+ uverbs_create_cq_get_buffer_desc,
+ addr, size, access);
+}
+EXPORT_SYMBOL(ib_umem_get_cq_buf_or_va);
+
+/**
* ib_umem_get_cq_tmp - Temporary CQ buffer umem getter.
* @device: IB device.
* @attrs: uverbs attribute bundle.
diff --git a/drivers/infiniband/core/uverbs_std_types_cq.c b/drivers/infiniband/core/uverbs_std_types_cq.c
index 711bad0aa8a3..05d1294762c0 100644
--- a/drivers/infiniband/core/uverbs_std_types_cq.c
+++ b/drivers/infiniband/core/uverbs_std_types_cq.c
@@ -215,6 +215,8 @@ DECLARE_UVERBS_NAMED_METHOD(
UVERBS_ATTR_PTR_IN(UVERBS_ATTR_CREATE_CQ_BUFFER_OFFSET,
UVERBS_ATTR_TYPE(u64),
UA_OPTIONAL),
+ UVERBS_ATTR_UMEM(UVERBS_ATTR_CREATE_CQ_BUF_UMEM,
+ UA_OPTIONAL),
UVERBS_ATTR_UHW());
static int UVERBS_HANDLER(UVERBS_METHOD_CQ_DESTROY)(
diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h
index 0d6e90a35f3a..492c8d365730 100644
--- a/include/rdma/ib_umem.h
+++ b/include/rdma/ib_umem.h
@@ -90,6 +90,12 @@ 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_buf(struct ib_device *device,
+ const struct uverbs_attr_bundle *attrs,
+ size_t size, int access);
+struct ib_umem *ib_umem_get_cq_buf_or_va(struct ib_device *device,
+ const struct uverbs_attr_bundle *attrs,
+ u64 addr, size_t size, int access);
struct ib_umem *ib_umem_get_cq_tmp(struct ib_device *device,
struct uverbs_attr_bundle *attrs);
@@ -210,6 +216,20 @@ ib_umem_get_attr_or_va(struct ib_device *device,
return ERR_PTR(-EOPNOTSUPP);
}
static inline struct ib_umem *
+ib_umem_get_cq_buf(struct ib_device *device,
+ const struct uverbs_attr_bundle *attrs, size_t size,
+ int access)
+{
+ return ERR_PTR(-EOPNOTSUPP);
+}
+static inline struct ib_umem *
+ib_umem_get_cq_buf_or_va(struct ib_device *device,
+ const struct uverbs_attr_bundle *attrs, u64 addr,
+ size_t size, int access)
+{
+ 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);
diff --git a/include/uapi/rdma/ib_user_ioctl_cmds.h b/include/uapi/rdma/ib_user_ioctl_cmds.h
index 72041c1b0ea5..02835b7fd76d 100644
--- a/include/uapi/rdma/ib_user_ioctl_cmds.h
+++ b/include/uapi/rdma/ib_user_ioctl_cmds.h
@@ -117,6 +117,7 @@ enum uverbs_attrs_create_cq_cmd_attr_ids {
UVERBS_ATTR_CREATE_CQ_BUFFER_LENGTH,
UVERBS_ATTR_CREATE_CQ_BUFFER_FD,
UVERBS_ATTR_CREATE_CQ_BUFFER_OFFSET,
+ UVERBS_ATTR_CREATE_CQ_BUF_UMEM,
};
enum uverbs_attrs_destroy_cq_cmd_attr_ids {