From: Jens Axboe <axboe@kernel.dk>
To: io-uring@vger.kernel.org
Cc: Jens Axboe <axboe@kernel.dk>
Subject: [PATCH 2/2] io_uring/msg_ring: add support for sending a sync message
Date: Mon, 23 Sep 2024 22:59:54 -0600 [thread overview]
Message-ID: <20240924050531.39427-3-axboe@kernel.dk> (raw)
In-Reply-To: <20240924050531.39427-1-axboe@kernel.dk>
Normally MSG_RING requires both a source and a destination ring. But
some users don't always have a ring avilable to send a message from, yet
they still need to notify a target ring.
Add support for using io_uring_register(2) without having a source ring,
using a file descriptor of -1 for that. Internally those are called
blind registration opcodes. Implement IORING_REGISTER_SEND_MSG_RING as a
blind opcode, which simply takes an sqe that the application can put on
the stack and use the normal liburing helpers to get it setup. Then it
can call:
io_uring_register(-1, IORING_REGISTER_SEND_MSG_RING, &sqe, 1);
and get the same behavior in terms of the target where a CQE is posted
with the details given in the sqe.
For now this takes a single sqe pointer argument, and hence arg must
be set to that, and nr_args must be 1. Could easily be extended to take
an array of sqes, but for now let's keep it simple.
Signed-off-by: Jens Axboe <axboe@kernel.dk>
---
include/uapi/linux/io_uring.h | 3 +++
io_uring/msg_ring.c | 27 +++++++++++++++++++++++++++
io_uring/msg_ring.h | 1 +
io_uring/register.c | 27 +++++++++++++++++++++++++++
4 files changed, 58 insertions(+)
diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h
index 1fe79e750470..86cb385fe0b5 100644
--- a/include/uapi/linux/io_uring.h
+++ b/include/uapi/linux/io_uring.h
@@ -612,6 +612,9 @@ enum io_uring_register_op {
/* clone registered buffers from source ring to current ring */
IORING_REGISTER_CLONE_BUFFERS = 30,
+ /* send MSG_RING without having a ring */
+ IORING_REGISTER_SEND_MSG_RING = 31,
+
/* this goes last */
IORING_REGISTER_LAST,
diff --git a/io_uring/msg_ring.c b/io_uring/msg_ring.c
index ea4c7a7691e0..e64be6260cc6 100644
--- a/io_uring/msg_ring.c
+++ b/io_uring/msg_ring.c
@@ -333,6 +333,33 @@ int io_msg_ring(struct io_kiocb *req, unsigned int issue_flags)
return IOU_OK;
}
+int io_uring_sync_msg_ring(struct io_uring_sqe *sqe)
+{
+ struct io_msg io_msg = { };
+ struct fd f;
+ int ret;
+
+ ret =__io_msg_ring_prep(&io_msg, sqe);
+ if (unlikely(ret))
+ return ret;
+
+ if (io_msg.cmd != IORING_MSG_DATA)
+ return -EINVAL;
+
+ f = fdget(sqe->fd);
+ if (!fd_file(f))
+ return -EBADF;
+
+ ret = -EBADFD;
+ if (!io_is_uring_fops(fd_file(f)))
+ goto err;
+
+ ret = __io_msg_ring_data(fd_file(f)->private_data, &io_msg, 0);
+err:
+ fdput(f);
+ return ret;
+}
+
void io_msg_cache_free(const void *entry)
{
struct io_kiocb *req = (struct io_kiocb *) entry;
diff --git a/io_uring/msg_ring.h b/io_uring/msg_ring.h
index 3030f3942f0f..38e7f8f0c944 100644
--- a/io_uring/msg_ring.h
+++ b/io_uring/msg_ring.h
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
+int io_uring_sync_msg_ring(struct io_uring_sqe *sqe);
int io_msg_ring_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
int io_msg_ring(struct io_kiocb *req, unsigned int issue_flags);
void io_msg_ring_cleanup(struct io_kiocb *req);
diff --git a/io_uring/register.c b/io_uring/register.c
index eca26d4884d9..2daa6f48a178 100644
--- a/io_uring/register.c
+++ b/io_uring/register.c
@@ -28,6 +28,7 @@
#include "kbuf.h"
#include "napi.h"
#include "eventfd.h"
+#include "msg_ring.h"
#define IORING_MAX_RESTRICTIONS (IORING_RESTRICTION_LAST + \
IORING_REGISTER_LAST + IORING_OP_LAST)
@@ -588,6 +589,29 @@ struct file *io_uring_register_get_file(unsigned int fd, bool registered)
return ERR_PTR(-EOPNOTSUPP);
}
+/*
+ * "blind" registration opcodes are ones where there's no ring given, and
+ * hence the source fd must be -1.
+ */
+static int io_uring_register_blind(unsigned int opcode, void __user *arg,
+ unsigned int nr_args)
+{
+ switch (opcode) {
+ case IORING_REGISTER_SEND_MSG_RING: {
+ struct io_uring_sqe sqe;
+
+ if (!arg || nr_args != 1)
+ return -EINVAL;
+ if (copy_from_user(&sqe, arg, sizeof(sqe)))
+ return -EFAULT;
+ if (sqe.opcode == IORING_OP_MSG_RING)
+ return io_uring_sync_msg_ring(&sqe);
+ }
+ }
+
+ return -EINVAL;
+}
+
SYSCALL_DEFINE4(io_uring_register, unsigned int, fd, unsigned int, opcode,
void __user *, arg, unsigned int, nr_args)
{
@@ -602,6 +626,9 @@ SYSCALL_DEFINE4(io_uring_register, unsigned int, fd, unsigned int, opcode,
if (opcode >= IORING_REGISTER_LAST)
return -EINVAL;
+ if (fd == -1)
+ return io_uring_register_blind(opcode, arg, nr_args);
+
file = io_uring_register_get_file(fd, use_registered_ring);
if (IS_ERR(file))
return PTR_ERR(file);
--
2.45.2
next prev parent reply other threads:[~2024-09-24 5:05 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-24 4:59 [PATCHSET 0/2] Add support for sending sync MSG_RING Jens Axboe
2024-09-24 4:59 ` [PATCH 1/2] io_uring/msg_ring: refactor a few helper functions Jens Axboe
2024-09-24 4:59 ` Jens Axboe [this message]
-- strict thread matches above, loose matches on Subject: below --
2024-09-24 11:57 [PATCHSET v2 0/2] Add support for sending sync MSG_RING Jens Axboe
2024-09-24 11:57 ` [PATCH 2/2] io_uring/msg_ring: add support for sending a sync message Jens Axboe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240924050531.39427-3-axboe@kernel.dk \
--to=axboe@kernel.dk \
--cc=io-uring@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.