[PATCH 1/3] io_uring: Avoid msghdr on op_connect/op_bind async data

Gabriel Krisman Bertazi <[email protected]>
Newsgroups org.kernel.vger.io-uring
Message-ID <[email protected]>
Both IORING_OP_CONNECT and IORING_OP_BIND reuse the msghdr object for
just to store sockaddr.  Beyond allocating a much larger object than
needed, msghdr can also wrap an iovec, which will be recycled
unnecessarily.  This splits the sockaddr into an async type.

Signed-off-by: Gabriel Krisman Bertazi <[email protected]>
---
 io_uring/net.c   | 15 +++++++--------
 io_uring/net.h   |  4 ++++
 io_uring/opdef.c |  4 ++--
 3 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/io_uring/net.c b/io_uring/net.c
index cceb5c1409ca..1da811100132 100644
--- a/io_uring/net.c
+++ b/io_uring/net.c
@@ -1677,7 +1677,7 @@ void io_socket_bpf_populate(struct io_uring_bpf_ctx *bctx, struct io_kiocb *req)
 void io_connect_bpf_populate(struct io_uring_bpf_ctx *bctx, struct io_kiocb *req)
 {
 	struct io_connect *conn = io_kiocb_to_cmd(req, struct io_connect);
-	struct io_async_msghdr *iomsg = req->async_data;
+	struct io_async_sockaddr *iomsg = req->async_data;
 	struct sockaddr_storage *ss = &iomsg->addr;
 
 	/*
@@ -1772,7 +1772,7 @@ int io_socket(struct io_kiocb *req, unsigned int issue_flags)
 int io_connect_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 {
 	struct io_connect *conn = io_kiocb_to_cmd(req, struct io_connect);
-	struct io_async_msghdr *io;
+	struct io_async_sockaddr *io;
 
 	if (sqe->len || sqe->buf_index || sqe->rw_flags || sqe->splice_fd_in)
 		return -EINVAL;
@@ -1781,7 +1781,7 @@ int io_connect_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 	conn->addr_len =  READ_ONCE(sqe->addr2);
 	conn->in_progress = conn->seen_econnaborted = false;
 
-	io = io_msg_alloc_async(req);
+	io = io_uring_alloc_async_data(NULL, req);
 	if (unlikely(!io))
 		return -ENOMEM;
 
@@ -1791,7 +1791,7 @@ int io_connect_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 int io_connect(struct io_kiocb *req, unsigned int issue_flags)
 {
 	struct io_connect *connect = io_kiocb_to_cmd(req, struct io_connect);
-	struct io_async_msghdr *io = req->async_data;
+	struct io_async_sockaddr *io = req->async_data;
 	unsigned file_flags;
 	int ret;
 	bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK;
@@ -1835,7 +1835,6 @@ int io_connect(struct io_kiocb *req, unsigned int issue_flags)
 out:
 	if (ret < 0)
 		req_set_fail(req);
-	io_req_msg_cleanup(req, issue_flags);
 	io_req_set_res(req, ret, 0);
 	return IOU_COMPLETE;
 }
@@ -1844,7 +1843,7 @@ int io_bind_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 {
 	struct io_bind *bind = io_kiocb_to_cmd(req, struct io_bind);
 	struct sockaddr __user *uaddr;
-	struct io_async_msghdr *io;
+	struct io_async_sockaddr *io;
 
 	if (sqe->len || sqe->buf_index || sqe->rw_flags || sqe->splice_fd_in)
 		return -EINVAL;
@@ -1852,7 +1851,7 @@ int io_bind_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 	uaddr = u64_to_user_ptr(READ_ONCE(sqe->addr));
 	bind->addr_len =  READ_ONCE(sqe->addr2);
 
-	io = io_msg_alloc_async(req);
+	io = io_uring_alloc_async_data(NULL, req);
 	if (unlikely(!io))
 		return -ENOMEM;
 	return move_addr_to_kernel(uaddr, bind->addr_len, &io->addr);
@@ -1861,7 +1860,7 @@ int io_bind_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 int io_bind(struct io_kiocb *req, unsigned int issue_flags)
 {
 	struct io_bind *bind = io_kiocb_to_cmd(req, struct io_bind);
-	struct io_async_msghdr *io = req->async_data;
+	struct io_async_sockaddr *io = req->async_data;
 	struct socket *sock;
 	int ret;
 
diff --git a/io_uring/net.h b/io_uring/net.h
index 51fda715d3c0..b296ec4eefb2 100644
--- a/io_uring/net.h
+++ b/io_uring/net.h
@@ -5,6 +5,10 @@
 #include <linux/io_uring_types.h>
 #include <uapi/linux/io_uring/bpf_filter.h>
 
+struct io_async_sockaddr {
+	struct sockaddr_storage		addr;
+};
+
 struct io_async_msghdr {
 #if defined(CONFIG_NET)
 	struct iou_vec				vec;
diff --git a/io_uring/opdef.c b/io_uring/opdef.c
index 8ea6bd274607..ffa28224cc8f 100644
--- a/io_uring/opdef.c
+++ b/io_uring/opdef.c
@@ -204,7 +204,7 @@ const struct io_issue_def io_issue_defs[] = {
 		.pollout		= 1,
 #if defined(CONFIG_NET)
 		.filter_pdu_size	= sizeof_field(struct io_uring_bpf_ctx, connect),
-		.async_size		= sizeof(struct io_async_msghdr),
+		.async_size		= sizeof(struct io_async_sockaddr),
 		.prep			= io_connect_prep,
 		.issue			= io_connect,
 		.filter_populate	= io_connect_bpf_populate,
@@ -505,7 +505,7 @@ const struct io_issue_def io_issue_defs[] = {
 		.needs_file		= 1,
 		.prep			= io_bind_prep,
 		.issue			= io_bind,
-		.async_size		= sizeof(struct io_async_msghdr),
+		.async_size		= sizeof(struct io_async_sockaddr),
 #else
 		.prep			= io_eopnotsupp_prep,
 #endif
-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.