[PATCH for-next 05/23] RDMA/core: Add writev to uverbs file descriptor

Dennis Dalessandro
2025-06-30T17:58:12Z

From: Dean Luick <dean.luick@cornelisnetworks.com>

Add a writev pass-through between the uverbs file descriptor and
infiniband devices. Interested devices may subscribe to this
functionality.

Signed-off-by: Dean Luick <dean.luick@cornelisnetworks.com>
Signed-off-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
---
drivers/infiniband/core/device.c | 1 +
drivers/infiniband/core/uverbs_main.c | 22 ++++++++++++++++++++++
include/rdma/ib_verbs.h | 2 ++
3 files changed, 25 insertions(+)

diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index d4263385850a..6c270f9421af 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -2789,6 +2789,7 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops)
SET_DEVICE_OP(dev_ops, set_vf_link_state);
SET_DEVICE_OP(dev_ops, ufile_hw_cleanup);
SET_DEVICE_OP(dev_ops, report_port_event);
+ SET_DEVICE_OP(dev_ops, write_iter);

SET_OBJ_SIZE(dev_ops, ib_ah);
SET_OBJ_SIZE(dev_ops, ib_counters);
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index 973fe2c7ef53..9cb7c60f85b0 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -713,6 +713,26 @@ static int ib_uverbs_mmap(struct file *filp, struct vm_area_struct *vma)
return ret;
}

+static ssize_t ib_uverbs_write_iter(struct kiocb *kiocb, struct iov_iter *from)
+{
+ struct ib_uverbs_file *file = kiocb->ki_filp->private_data;
+ struct ib_ucontext *ucontext;
+ ssize_t ret = -EOPNOTSUPP;
+ int srcu_key;
+
+ srcu_key = srcu_read_lock(&file->device->disassociate_srcu);
+ ucontext = ib_uverbs_get_ucontext_file(file);
+ if (IS_ERR(ucontext)) {
+ ret = PTR_ERR(ucontext);
+ goto out;
+ }
+ if (ucontext->device->ops.write_iter)
+ ret = ucontext->device->ops.write_iter(ucontext, from);
+out:
+ srcu_read_unlock(&file->device->disassociate_srcu, srcu_key);
+ return ret;
+}
+
/*
* The VMA has been dup'd, initialize the vm_private_data with a new tracking
* struct
@@ -1031,6 +1051,7 @@ static const struct file_operations uverbs_fops = {
.release = ib_uverbs_close,
.unlocked_ioctl = ib_uverbs_ioctl,
.compat_ioctl = compat_ptr_ioctl,
+ .write_iter = ib_uverbs_write_iter,
};

static const struct file_operations uverbs_mmap_fops = {
@@ -1041,6 +1062,7 @@ static const struct file_operations uverbs_mmap_fops = {
.release = ib_uverbs_close,
.unlocked_ioctl = ib_uverbs_ioctl,
.compat_ioctl = compat_ptr_ioctl,
+ .write_iter = ib_uverbs_write_iter,
};

static int ib_uverbs_get_nl_info(struct ib_device *ibdev, void *client_data,
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 901353796fbb..db4597b67d3b 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -2686,6 +2686,8 @@ struct ib_device_ops {
* Everyone else relies on Linux memory management model.
*/
int (*get_numa_node)(struct ib_device *dev);
+ /* subscribe to file ops write_iter callback */
+ ssize_t (*write_iter)(struct ib_ucontext *context, struct iov_iter *from);

/**
* add_sub_dev - Add a sub IB device