From: Jiri Pirko Date: Fri, 29 May 2026 13:43:02 +0000 (+0200) Subject: RDMA/uverbs: Add CQ buffer UMEM attribute and driver helpers X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f6d2e53ca53ad2e847e5eb64c56c426ee2fd8bdd;p=thirdparty%2Flinux.git RDMA/uverbs: Add CQ buffer UMEM attribute and driver helpers Add UVERBS_ATTR_CREATE_CQ_BUF_UMEM and two driver-facing wrappers, ib_umem_get_cq_buf() and ib_umem_get_cq_buf_or_va(), that pin a CQ buffer umem from it. The wrappers reuse the existing legacy CQ buffer-attr filler. Link: https://patch.msgid.link/r/20260529134312.2836341-7-jiri@resnulli.us Signed-off-by: Jiri Pirko Signed-off-by: Jason Gunthorpe --- diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c index d364a5ab05580..b3261b924a718 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; @@ -547,6 +547,61 @@ static int uverbs_create_cq_get_buffer_desc(struct uverbs_attr_bundle *attrs, return -ENODATA; } +/** + * 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. diff --git a/drivers/infiniband/core/uverbs_std_types_cq.c b/drivers/infiniband/core/uverbs_std_types_cq.c index 711bad0aa8a3f..05d1294762c0b 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 0d6e90a35f3ab..492c8d3657303 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 72041c1b0ea51..02835b7fd76d2 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 {