All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 5.11 0/2] clean up async msg setup
@ 2020-11-15 10:17 Pavel Begunkov
  2020-11-15 10:17 ` [PATCH 1/2] io_uring: update msg header on copy Pavel Begunkov
  2020-11-15 10:17 ` [PATCH 2/2] io_uring: setup iter for recv BUFFER_SELECT once Pavel Begunkov
  0 siblings, 2 replies; 3+ messages in thread
From: Pavel Begunkov @ 2020-11-15 10:17 UTC (permalink / raw)
  To: Jens Axboe, io-uring

This refactors sendmsg() and recvmsg() msg copy, async_data setup
and its later use. Also deduplicates a couple of things helping to keep
it saner.

Pavel Begunkov (2):
  io_uring: update msg header on copy
  io_uring: setup iter for recv BUFFER_SELECT once

 fs/io_uring.c | 83 +++++++++++++++++++++++++--------------------------
 1 file changed, 41 insertions(+), 42 deletions(-)

-- 
2.24.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/2] io_uring: update msg header on copy
  2020-11-15 10:17 [PATCH 5.11 0/2] clean up async msg setup Pavel Begunkov
@ 2020-11-15 10:17 ` Pavel Begunkov
  2020-11-15 10:17 ` [PATCH 2/2] io_uring: setup iter for recv BUFFER_SELECT once Pavel Begunkov
  1 sibling, 0 replies; 3+ messages in thread
From: Pavel Begunkov @ 2020-11-15 10:17 UTC (permalink / raw)
  To: Jens Axboe, io-uring

After copying a send/recv msg header, fix up all the fields right away
instead of delaying it. Keeping it in one place makes it easier to
follow.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
---
 fs/io_uring.c | 32 +++++++++++++-------------------
 1 file changed, 13 insertions(+), 19 deletions(-)

diff --git a/fs/io_uring.c b/fs/io_uring.c
index 365a583033c5..02811c90f711 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -4487,6 +4487,10 @@ static int io_setup_async_msg(struct io_kiocb *req,
 	async_msg = req->async_data;
 	req->flags |= REQ_F_NEED_CLEANUP;
 	memcpy(async_msg, kmsg, sizeof(*kmsg));
+	async_msg->msg.msg_name = &async_msg->addr;
+	/* if iov is not set, it uses fast_iov */
+	if (!async_msg->iov)
+		async_msg->msg.msg_iter.iov = async_msg->fast_iov;
 	return -EAGAIN;
 }
 
@@ -4537,14 +4541,8 @@ static int io_sendmsg(struct io_kiocb *req, bool force_nonblock,
 	if (unlikely(!sock))
 		return ret;
 
-	if (req->async_data) {
-		kmsg = req->async_data;
-		kmsg->msg.msg_name = &kmsg->addr;
-		/* if iov is set, it's allocated already */
-		if (!kmsg->iov)
-			kmsg->iov = kmsg->fast_iov;
-		kmsg->msg.msg_iter.iov = kmsg->iov;
-	} else {
+	kmsg = req->async_data;
+	if (!kmsg) {
 		ret = io_sendmsg_copy_hdr(req, &iomsg);
 		if (ret)
 			return ret;
@@ -4563,7 +4561,8 @@ static int io_sendmsg(struct io_kiocb *req, bool force_nonblock,
 	if (ret == -ERESTARTSYS)
 		ret = -EINTR;
 
-	if (kmsg->iov != kmsg->fast_iov)
+	/* it's reportedly faster to check for null here */
+	if (kmsg->iov)
 		kfree(kmsg->iov);
 	req->flags &= ~REQ_F_NEED_CLEANUP;
 	if (ret < 0)
@@ -4765,14 +4764,8 @@ static int io_recvmsg(struct io_kiocb *req, bool force_nonblock,
 	if (unlikely(!sock))
 		return ret;
 
-	if (req->async_data) {
-		kmsg = req->async_data;
-		kmsg->msg.msg_name = &kmsg->addr;
-		/* if iov is set, it's allocated already */
-		if (!kmsg->iov)
-			kmsg->iov = kmsg->fast_iov;
-		kmsg->msg.msg_iter.iov = kmsg->iov;
-	} else {
+	kmsg = req->async_data;
+	if (!kmsg) {
 		ret = io_recvmsg_copy_hdr(req, &iomsg);
 		if (ret)
 			return ret;
@@ -4784,7 +4777,7 @@ static int io_recvmsg(struct io_kiocb *req, bool force_nonblock,
 		if (IS_ERR(kbuf))
 			return PTR_ERR(kbuf);
 		kmsg->fast_iov[0].iov_base = u64_to_user_ptr(kbuf->addr);
-		iov_iter_init(&kmsg->msg.msg_iter, READ, kmsg->iov,
+		iov_iter_init(&kmsg->msg.msg_iter, READ, kmsg->fast_iov,
 				1, req->sr_msg.len);
 	}
 
@@ -4803,7 +4796,8 @@ static int io_recvmsg(struct io_kiocb *req, bool force_nonblock,
 
 	if (req->flags & REQ_F_BUFFER_SELECTED)
 		cflags = io_put_recv_kbuf(req);
-	if (kmsg->iov != kmsg->fast_iov)
+	/* it's reportedly faster to check for null here */
+	if (kmsg->iov)
 		kfree(kmsg->iov);
 	req->flags &= ~REQ_F_NEED_CLEANUP;
 	if (ret < 0)
-- 
2.24.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] io_uring: setup iter for recv BUFFER_SELECT once
  2020-11-15 10:17 [PATCH 5.11 0/2] clean up async msg setup Pavel Begunkov
  2020-11-15 10:17 ` [PATCH 1/2] io_uring: update msg header on copy Pavel Begunkov
@ 2020-11-15 10:17 ` Pavel Begunkov
  1 sibling, 0 replies; 3+ messages in thread
From: Pavel Begunkov @ 2020-11-15 10:17 UTC (permalink / raw)
  To: Jens Axboe, io-uring

Instead of initialising msg.msg_iter with a selected buffer in
io_recv_msg() every time, do it once in io_recvmsg_copy_hdr(). Further
it may be copied into another msg but that's fine as
io_setup_async_msg() handles iovs copy.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
---
 fs/io_uring.c | 53 ++++++++++++++++++++++++++++-----------------------
 1 file changed, 29 insertions(+), 24 deletions(-)

diff --git a/fs/io_uring.c b/fs/io_uring.c
index 02811c90f711..aafdcf94be9d 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -4689,20 +4689,6 @@ static int __io_compat_recvmsg_copy_hdr(struct io_kiocb *req,
 }
 #endif
 
-static int io_recvmsg_copy_hdr(struct io_kiocb *req,
-			       struct io_async_msghdr *iomsg)
-{
-	iomsg->msg.msg_name = &iomsg->addr;
-	iomsg->iov = iomsg->fast_iov;
-
-#ifdef CONFIG_COMPAT
-	if (req->ctx->compat)
-		return __io_compat_recvmsg_copy_hdr(req, iomsg);
-#endif
-
-	return __io_recvmsg_copy_hdr(req, iomsg);
-}
-
 static struct io_buffer *io_recv_buffer_select(struct io_kiocb *req,
 					       bool needs_lock)
 {
@@ -4718,6 +4704,35 @@ static struct io_buffer *io_recv_buffer_select(struct io_kiocb *req,
 	return kbuf;
 }
 
+static int io_recvmsg_copy_hdr(struct io_kiocb *req,
+			       struct io_async_msghdr *iomsg)
+{
+	struct io_buffer *kbuf;
+	int ret;
+
+	iomsg->msg.msg_name = &iomsg->addr;
+	iomsg->iov = iomsg->fast_iov;
+#ifdef CONFIG_COMPAT
+	if (req->ctx->compat)
+		ret = __io_compat_recvmsg_copy_hdr(req, iomsg);
+	else
+#endif
+		ret = __io_recvmsg_copy_hdr(req, iomsg);
+	if (ret < 0)
+		return ret;
+
+	if (req->flags & REQ_F_BUFFER_SELECT) {
+		/* init is always done with uring_lock held */
+		kbuf = io_recv_buffer_select(req, false);
+		if (IS_ERR(kbuf))
+			return PTR_ERR(kbuf);
+		iomsg->fast_iov[0].iov_base = u64_to_user_ptr(kbuf->addr);
+		iov_iter_init(&iomsg->msg.msg_iter, READ, iomsg->fast_iov, 1,
+			      req->sr_msg.len);
+	}
+	return 0;
+}
+
 static inline unsigned int io_put_recv_kbuf(struct io_kiocb *req)
 {
 	return io_put_kbuf(req, req->sr_msg.kbuf);
@@ -4756,7 +4771,6 @@ static int io_recvmsg(struct io_kiocb *req, bool force_nonblock,
 {
 	struct io_async_msghdr iomsg, *kmsg;
 	struct socket *sock;
-	struct io_buffer *kbuf;
 	unsigned flags;
 	int ret, cflags = 0;
 
@@ -4772,15 +4786,6 @@ static int io_recvmsg(struct io_kiocb *req, bool force_nonblock,
 		kmsg = &iomsg;
 	}
 
-	if (req->flags & REQ_F_BUFFER_SELECT) {
-		kbuf = io_recv_buffer_select(req, !force_nonblock);
-		if (IS_ERR(kbuf))
-			return PTR_ERR(kbuf);
-		kmsg->fast_iov[0].iov_base = u64_to_user_ptr(kbuf->addr);
-		iov_iter_init(&kmsg->msg.msg_iter, READ, kmsg->fast_iov,
-				1, req->sr_msg.len);
-	}
-
 	flags = req->sr_msg.msg_flags;
 	if (flags & MSG_DONTWAIT)
 		req->flags |= REQ_F_NOWAIT;
-- 
2.24.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-11-15 10:20 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-11-15 10:17 [PATCH 5.11 0/2] clean up async msg setup Pavel Begunkov
2020-11-15 10:17 ` [PATCH 1/2] io_uring: update msg header on copy Pavel Begunkov
2020-11-15 10:17 ` [PATCH 2/2] io_uring: setup iter for recv BUFFER_SELECT once Pavel Begunkov

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.