public inbox for [email protected]
 help / color / mirror / Atom feed
* [PATCH for-next 0/9] mix of 6.1 net patches
@ 2022-09-21 11:17 Pavel Begunkov
  2022-09-21 11:17 ` [PATCH 1/9] io_uring: add custom opcode hooks on fail Pavel Begunkov
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: Pavel Begunkov @ 2022-09-21 11:17 UTC (permalink / raw)
  To: io-uring; +Cc: Jens Axboe, asml.silence

0-4 fix a rare scenario when a partial I/O is completed with an error
code rather than the number of bytes processed, which is especially
bad with sockets and other non-idempotent files.

5-9 add some net features, specifically 6/9 optionally transforms normal
sends into sendto, and 9/9 adds zerocopy sendmsg.

Pavel Begunkov (9):
  io_uring: add custom opcode hooks on fail
  io_uring/rw: don't lose partial IO result on fail
  io_uring/net: don't lose partial send/recv on fail
  io_uring/net: don't lose partial send_zc on fail
  io_uring/net: refactor io_setup_async_addr
  io_uring/net: support non-zerocopy sendto
  io_uring/net: rename io_sendzc()
  io_uring/net: combine fail handlers
  io_uring/net: zerocopy sendmsg

 include/uapi/linux/io_uring.h |   1 +
 io_uring/io_uring.c           |   4 +
 io_uring/net.c                | 176 +++++++++++++++++++++++++++++-----
 io_uring/net.h                |  12 ++-
 io_uring/opdef.c              |  41 +++++++-
 io_uring/opdef.h              |   1 +
 io_uring/rw.c                 |   8 ++
 io_uring/rw.h                 |   1 +
 8 files changed, 214 insertions(+), 30 deletions(-)

-- 
2.37.2


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

* [PATCH 1/9] io_uring: add custom opcode hooks on fail
  2022-09-21 11:17 [PATCH for-next 0/9] mix of 6.1 net patches Pavel Begunkov
@ 2022-09-21 11:17 ` Pavel Begunkov
  2022-09-21 11:17 ` [PATCH 2/9] io_uring/rw: don't lose partial IO result " Pavel Begunkov
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Pavel Begunkov @ 2022-09-21 11:17 UTC (permalink / raw)
  To: io-uring; +Cc: Jens Axboe, asml.silence

Sometimes we have to do a little bit of a fixup on a request failuer in
io_req_complete_failed(). Add a callback in opdef for that.

Cc: [email protected]
Signed-off-by: Pavel Begunkov <[email protected]>
---
 io_uring/io_uring.c | 4 ++++
 io_uring/opdef.h    | 1 +
 2 files changed, 5 insertions(+)

diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
index 433466455a5f..3875ea897cdf 100644
--- a/io_uring/io_uring.c
+++ b/io_uring/io_uring.c
@@ -865,8 +865,12 @@ inline void __io_req_complete(struct io_kiocb *req, unsigned issue_flags)
 
 void io_req_complete_failed(struct io_kiocb *req, s32 res)
 {
+	const struct io_op_def *def = &io_op_defs[req->opcode];
+
 	req_set_fail(req);
 	io_req_set_res(req, res, io_put_kbuf(req, IO_URING_F_UNLOCKED));
+	if (def->fail)
+		def->fail(req);
 	io_req_complete_post(req);
 }
 
diff --git a/io_uring/opdef.h b/io_uring/opdef.h
index 763c6e54e2ee..3efe06d25473 100644
--- a/io_uring/opdef.h
+++ b/io_uring/opdef.h
@@ -36,6 +36,7 @@ struct io_op_def {
 	int (*issue)(struct io_kiocb *, unsigned int);
 	int (*prep_async)(struct io_kiocb *);
 	void (*cleanup)(struct io_kiocb *);
+	void (*fail)(struct io_kiocb *);
 };
 
 extern const struct io_op_def io_op_defs[];
-- 
2.37.2


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

* [PATCH 2/9] io_uring/rw: don't lose partial IO result on fail
  2022-09-21 11:17 [PATCH for-next 0/9] mix of 6.1 net patches Pavel Begunkov
  2022-09-21 11:17 ` [PATCH 1/9] io_uring: add custom opcode hooks on fail Pavel Begunkov
@ 2022-09-21 11:17 ` Pavel Begunkov
  2022-09-21 11:17 ` [PATCH 3/9] io_uring/net: don't lose partial send/recv " Pavel Begunkov
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Pavel Begunkov @ 2022-09-21 11:17 UTC (permalink / raw)
  To: io-uring; +Cc: Jens Axboe, asml.silence

A partially done read/write may end up in io_req_complete_failed() and
loose the result, make sure we return the number of bytes processed.

Cc: [email protected]
Signed-off-by: Pavel Begunkov <[email protected]>
---
 io_uring/opdef.c | 6 ++++++
 io_uring/rw.c    | 8 ++++++++
 io_uring/rw.h    | 1 +
 3 files changed, 15 insertions(+)

diff --git a/io_uring/opdef.c b/io_uring/opdef.c
index c6e089900394..788393ec3ff4 100644
--- a/io_uring/opdef.c
+++ b/io_uring/opdef.c
@@ -69,6 +69,7 @@ const struct io_op_def io_op_defs[] = {
 		.issue			= io_read,
 		.prep_async		= io_readv_prep_async,
 		.cleanup		= io_readv_writev_cleanup,
+		.fail			= io_rw_fail,
 	},
 	[IORING_OP_WRITEV] = {
 		.needs_file		= 1,
@@ -85,6 +86,7 @@ const struct io_op_def io_op_defs[] = {
 		.issue			= io_write,
 		.prep_async		= io_writev_prep_async,
 		.cleanup		= io_readv_writev_cleanup,
+		.fail			= io_rw_fail,
 	},
 	[IORING_OP_FSYNC] = {
 		.needs_file		= 1,
@@ -105,6 +107,7 @@ const struct io_op_def io_op_defs[] = {
 		.name			= "READ_FIXED",
 		.prep			= io_prep_rw,
 		.issue			= io_read,
+		.fail			= io_rw_fail,
 	},
 	[IORING_OP_WRITE_FIXED] = {
 		.needs_file		= 1,
@@ -119,6 +122,7 @@ const struct io_op_def io_op_defs[] = {
 		.name			= "WRITE_FIXED",
 		.prep			= io_prep_rw,
 		.issue			= io_write,
+		.fail			= io_rw_fail,
 	},
 	[IORING_OP_POLL_ADD] = {
 		.needs_file		= 1,
@@ -275,6 +279,7 @@ const struct io_op_def io_op_defs[] = {
 		.name			= "READ",
 		.prep			= io_prep_rw,
 		.issue			= io_read,
+		.fail			= io_rw_fail,
 	},
 	[IORING_OP_WRITE] = {
 		.needs_file		= 1,
@@ -289,6 +294,7 @@ const struct io_op_def io_op_defs[] = {
 		.name			= "WRITE",
 		.prep			= io_prep_rw,
 		.issue			= io_write,
+		.fail			= io_rw_fail,
 	},
 	[IORING_OP_FADVISE] = {
 		.needs_file		= 1,
diff --git a/io_uring/rw.c b/io_uring/rw.c
index b777c35378b9..8f4e6b3f2b3f 100644
--- a/io_uring/rw.c
+++ b/io_uring/rw.c
@@ -954,6 +954,14 @@ static void io_cqring_ev_posted_iopoll(struct io_ring_ctx *ctx)
 		io_cqring_wake(ctx);
 }
 
+void io_rw_fail(struct io_kiocb *req)
+{
+	int res;
+
+	res = io_fixup_rw_res(req, req->cqe.res);
+	io_req_set_res(req, res, req->cqe.flags);
+}
+
 int io_do_iopoll(struct io_ring_ctx *ctx, bool force_nonspin)
 {
 	struct io_wq_work_node *pos, *start, *prev;
diff --git a/io_uring/rw.h b/io_uring/rw.h
index 0204c3fcafa5..3b733f4b610a 100644
--- a/io_uring/rw.h
+++ b/io_uring/rw.h
@@ -21,3 +21,4 @@ int io_readv_prep_async(struct io_kiocb *req);
 int io_write(struct io_kiocb *req, unsigned int issue_flags);
 int io_writev_prep_async(struct io_kiocb *req);
 void io_readv_writev_cleanup(struct io_kiocb *req);
+void io_rw_fail(struct io_kiocb *req);
-- 
2.37.2


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

* [PATCH 3/9] io_uring/net: don't lose partial send/recv on fail
  2022-09-21 11:17 [PATCH for-next 0/9] mix of 6.1 net patches Pavel Begunkov
  2022-09-21 11:17 ` [PATCH 1/9] io_uring: add custom opcode hooks on fail Pavel Begunkov
  2022-09-21 11:17 ` [PATCH 2/9] io_uring/rw: don't lose partial IO result " Pavel Begunkov
@ 2022-09-21 11:17 ` Pavel Begunkov
  2022-09-21 11:17 ` [PATCH 4/9] io_uring/net: don't lose partial send_zc " Pavel Begunkov
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Pavel Begunkov @ 2022-09-21 11:17 UTC (permalink / raw)
  To: io-uring; +Cc: Jens Axboe, asml.silence

Just as with rw, partial send/recv may end up in
io_req_complete_failed() and loose the result, make sure we return the
number of bytes processed.

Cc: [email protected]
Signed-off-by: Pavel Begunkov <[email protected]>
---
 io_uring/net.c   | 10 ++++++++++
 io_uring/net.h   |  2 ++
 io_uring/opdef.c |  4 ++++
 3 files changed, 16 insertions(+)

diff --git a/io_uring/net.c b/io_uring/net.c
index 84df6d4253b7..e86a82ef4fbf 100644
--- a/io_uring/net.c
+++ b/io_uring/net.c
@@ -1093,6 +1093,16 @@ int io_sendzc(struct io_kiocb *req, unsigned int issue_flags)
 	return IOU_OK;
 }
 
+void io_sendrecv_fail(struct io_kiocb *req)
+{
+	struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
+	int res = req->cqe.res;
+
+	if (req->flags & REQ_F_PARTIAL_IO)
+		res = sr->done_io;
+	io_req_set_res(req, res, req->cqe.flags);
+}
+
 int io_accept_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 {
 	struct io_accept *accept = io_kiocb_to_cmd(req, struct io_accept);
diff --git a/io_uring/net.h b/io_uring/net.h
index d744a0a874e7..109ffb3a1a3f 100644
--- a/io_uring/net.h
+++ b/io_uring/net.h
@@ -43,6 +43,8 @@ int io_recvmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
 int io_recvmsg(struct io_kiocb *req, unsigned int issue_flags);
 int io_recv(struct io_kiocb *req, unsigned int issue_flags);
 
+void io_sendrecv_fail(struct io_kiocb *req);
+
 int io_accept_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
 int io_accept(struct io_kiocb *req, unsigned int issue_flags);
 
diff --git a/io_uring/opdef.c b/io_uring/opdef.c
index 788393ec3ff4..8d8a0f9bb5b6 100644
--- a/io_uring/opdef.c
+++ b/io_uring/opdef.c
@@ -158,6 +158,7 @@ const struct io_op_def io_op_defs[] = {
 		.issue			= io_sendmsg,
 		.prep_async		= io_sendmsg_prep_async,
 		.cleanup		= io_sendmsg_recvmsg_cleanup,
+		.fail			= io_sendrecv_fail,
 #else
 		.prep			= io_eopnotsupp_prep,
 #endif
@@ -176,6 +177,7 @@ const struct io_op_def io_op_defs[] = {
 		.issue			= io_recvmsg,
 		.prep_async		= io_recvmsg_prep_async,
 		.cleanup		= io_sendmsg_recvmsg_cleanup,
+		.fail			= io_sendrecv_fail,
 #else
 		.prep			= io_eopnotsupp_prep,
 #endif
@@ -318,6 +320,7 @@ const struct io_op_def io_op_defs[] = {
 #if defined(CONFIG_NET)
 		.prep			= io_sendmsg_prep,
 		.issue			= io_send,
+		.fail			= io_sendrecv_fail,
 #else
 		.prep			= io_eopnotsupp_prep,
 #endif
@@ -333,6 +336,7 @@ const struct io_op_def io_op_defs[] = {
 #if defined(CONFIG_NET)
 		.prep			= io_recvmsg_prep,
 		.issue			= io_recv,
+		.fail			= io_sendrecv_fail,
 #else
 		.prep			= io_eopnotsupp_prep,
 #endif
-- 
2.37.2


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

* [PATCH 4/9] io_uring/net: don't lose partial send_zc on fail
  2022-09-21 11:17 [PATCH for-next 0/9] mix of 6.1 net patches Pavel Begunkov
                   ` (2 preceding siblings ...)
  2022-09-21 11:17 ` [PATCH 3/9] io_uring/net: don't lose partial send/recv " Pavel Begunkov
@ 2022-09-21 11:17 ` Pavel Begunkov
  2022-09-21 11:17 ` [PATCH 5/9] io_uring/net: refactor io_setup_async_addr Pavel Begunkov
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Pavel Begunkov @ 2022-09-21 11:17 UTC (permalink / raw)
  To: io-uring; +Cc: Jens Axboe, asml.silence

Partial zc send may end up in io_req_complete_failed(), which not only
would return invalid result but also mask out the notification leading
to lifetime issues.

Cc: [email protected]
Signed-off-by: Pavel Begunkov <[email protected]>
---
 io_uring/net.c   | 16 ++++++++++++++++
 io_uring/net.h   |  1 +
 io_uring/opdef.c |  1 +
 3 files changed, 18 insertions(+)

diff --git a/io_uring/net.c b/io_uring/net.c
index e86a82ef4fbf..5e7fadefe2d5 100644
--- a/io_uring/net.c
+++ b/io_uring/net.c
@@ -1103,6 +1103,22 @@ void io_sendrecv_fail(struct io_kiocb *req)
 	io_req_set_res(req, res, req->cqe.flags);
 }
 
+void io_send_zc_fail(struct io_kiocb *req)
+{
+	struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
+	int res = req->cqe.res;
+
+	if (req->flags & REQ_F_PARTIAL_IO) {
+		if (req->flags & REQ_F_NEED_CLEANUP) {
+			io_notif_flush(sr->notif);
+			sr->notif = NULL;
+			req->flags &= ~REQ_F_NEED_CLEANUP;
+		}
+		res = sr->done_io;
+	}
+	io_req_set_res(req, res, req->cqe.flags);
+}
+
 int io_accept_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 {
 	struct io_accept *accept = io_kiocb_to_cmd(req, struct io_accept);
diff --git a/io_uring/net.h b/io_uring/net.h
index 109ffb3a1a3f..e7366aac335c 100644
--- a/io_uring/net.h
+++ b/io_uring/net.h
@@ -58,6 +58,7 @@ int io_connect(struct io_kiocb *req, unsigned int issue_flags);
 int io_sendzc(struct io_kiocb *req, unsigned int issue_flags);
 int io_sendzc_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
 void io_sendzc_cleanup(struct io_kiocb *req);
+void io_send_zc_fail(struct io_kiocb *req);
 
 void io_netmsg_cache_free(struct io_cache_entry *entry);
 #else
diff --git a/io_uring/opdef.c b/io_uring/opdef.c
index 8d8a0f9bb5b6..f5e7a0e01729 100644
--- a/io_uring/opdef.c
+++ b/io_uring/opdef.c
@@ -497,6 +497,7 @@ const struct io_op_def io_op_defs[] = {
 		.issue			= io_sendzc,
 		.prep_async		= io_sendzc_prep_async,
 		.cleanup		= io_sendzc_cleanup,
+		.fail			= io_send_zc_fail,
 #else
 		.prep			= io_eopnotsupp_prep,
 #endif
-- 
2.37.2


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

* [PATCH 5/9] io_uring/net: refactor io_setup_async_addr
  2022-09-21 11:17 [PATCH for-next 0/9] mix of 6.1 net patches Pavel Begunkov
                   ` (3 preceding siblings ...)
  2022-09-21 11:17 ` [PATCH 4/9] io_uring/net: don't lose partial send_zc " Pavel Begunkov
@ 2022-09-21 11:17 ` Pavel Begunkov
  2022-09-21 11:17 ` [PATCH 6/9] io_uring/net: support non-zerocopy sendto Pavel Begunkov
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Pavel Begunkov @ 2022-09-21 11:17 UTC (permalink / raw)
  To: io-uring; +Cc: Jens Axboe, asml.silence

Instead of passing the right address into io_setup_async_addr() only
specify local on-stack storage and let the function infer where to grab
it from. It optimises out one local variable we have to deal with.

Signed-off-by: Pavel Begunkov <[email protected]>
---
 io_uring/net.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/io_uring/net.c b/io_uring/net.c
index 5e7fadefe2d5..a190e022a9de 100644
--- a/io_uring/net.c
+++ b/io_uring/net.c
@@ -196,17 +196,18 @@ int io_sendzc_prep_async(struct io_kiocb *req)
 }
 
 static int io_setup_async_addr(struct io_kiocb *req,
-			      struct sockaddr_storage *addr,
+			      struct sockaddr_storage *addr_storage,
 			      unsigned int issue_flags)
 {
+	struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
 	struct io_async_msghdr *io;
 
-	if (!addr || req_has_async_data(req))
+	if (!sr->addr || req_has_async_data(req))
 		return -EAGAIN;
 	io = io_msg_alloc_async(req, issue_flags);
 	if (!io)
 		return -ENOMEM;
-	memcpy(&io->addr, addr, sizeof(io->addr));
+	memcpy(&io->addr, addr_storage, sizeof(io->addr));
 	return -EAGAIN;
 }
 
@@ -1000,7 +1001,7 @@ static int io_sg_from_iter(struct sock *sk, struct sk_buff *skb,
 
 int io_sendzc(struct io_kiocb *req, unsigned int issue_flags)
 {
-	struct sockaddr_storage __address, *addr = NULL;
+	struct sockaddr_storage __address;
 	struct io_sr_msg *zc = io_kiocb_to_cmd(req, struct io_sr_msg);
 	struct msghdr msg;
 	struct iovec iov;
@@ -1021,20 +1022,19 @@ int io_sendzc(struct io_kiocb *req, unsigned int issue_flags)
 		if (req_has_async_data(req)) {
 			struct io_async_msghdr *io = req->async_data;
 
-			msg.msg_name = addr = &io->addr;
+			msg.msg_name = &io->addr;
 		} else {
 			ret = move_addr_to_kernel(zc->addr, zc->addr_len, &__address);
 			if (unlikely(ret < 0))
 				return ret;
 			msg.msg_name = (struct sockaddr *)&__address;
-			addr = &__address;
 		}
 		msg.msg_namelen = zc->addr_len;
 	}
 
 	if (!(req->flags & REQ_F_POLLED) &&
 	    (zc->flags & IORING_RECVSEND_POLL_FIRST))
-		return io_setup_async_addr(req, addr, issue_flags);
+		return io_setup_async_addr(req, &__address, issue_flags);
 
 	if (zc->flags & IORING_RECVSEND_FIXED_BUF) {
 		ret = io_import_fixed(WRITE, &msg.msg_iter, req->imu,
@@ -1065,14 +1065,14 @@ int io_sendzc(struct io_kiocb *req, unsigned int issue_flags)
 
 	if (unlikely(ret < min_ret)) {
 		if (ret == -EAGAIN && (issue_flags & IO_URING_F_NONBLOCK))
-			return io_setup_async_addr(req, addr, issue_flags);
+			return io_setup_async_addr(req, &__address, issue_flags);
 
 		if (ret > 0 && io_net_retry(sock, msg.msg_flags)) {
 			zc->len -= ret;
 			zc->buf += ret;
 			zc->done_io += ret;
 			req->flags |= REQ_F_PARTIAL_IO;
-			return io_setup_async_addr(req, addr, issue_flags);
+			return io_setup_async_addr(req, &__address, issue_flags);
 		}
 		if (ret < 0 && !zc->done_io)
 			zc->notif->flags |= REQ_F_CQE_SKIP;
-- 
2.37.2


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

* [PATCH 6/9] io_uring/net: support non-zerocopy sendto
  2022-09-21 11:17 [PATCH for-next 0/9] mix of 6.1 net patches Pavel Begunkov
                   ` (4 preceding siblings ...)
  2022-09-21 11:17 ` [PATCH 5/9] io_uring/net: refactor io_setup_async_addr Pavel Begunkov
@ 2022-09-21 11:17 ` Pavel Begunkov
  2022-09-21 11:17 ` [PATCH 7/9] io_uring/net: rename io_sendzc() Pavel Begunkov
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Pavel Begunkov @ 2022-09-21 11:17 UTC (permalink / raw)
  To: io-uring; +Cc: Jens Axboe, asml.silence

We have normal sends, but what is missing is sendto-like requests. Add
sendto() capabilities to IORING_OP_SEND by passing in addr just as we do
for IORING_OP_SEND_ZC.

Signed-off-by: Pavel Begunkov <[email protected]>
---
 io_uring/net.c   | 35 +++++++++++++++++++++++++++++------
 io_uring/net.h   |  3 ++-
 io_uring/opdef.c |  5 ++++-
 3 files changed, 35 insertions(+), 8 deletions(-)

diff --git a/io_uring/net.c b/io_uring/net.c
index a190e022a9de..aa2c819cd85d 100644
--- a/io_uring/net.c
+++ b/io_uring/net.c
@@ -59,9 +59,10 @@ struct io_sr_msg {
 	unsigned			done_io;
 	unsigned			msg_flags;
 	u16				flags;
-	/* used only for sendzc */
+	/* initialised and used only by !msg send variants */
 	u16				addr_len;
 	void __user			*addr;
+	/* used only for send zerocopy */
 	struct io_kiocb 		*notif;
 };
 
@@ -180,7 +181,7 @@ static int io_sendmsg_copy_hdr(struct io_kiocb *req,
 					&iomsg->free_iov);
 }
 
-int io_sendzc_prep_async(struct io_kiocb *req)
+int io_send_prep_async(struct io_kiocb *req)
 {
 	struct io_sr_msg *zc = io_kiocb_to_cmd(req, struct io_sr_msg);
 	struct io_async_msghdr *io;
@@ -234,8 +235,14 @@ int io_sendmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 {
 	struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
 
-	if (unlikely(sqe->file_index || sqe->addr2))
+	if (req->opcode == IORING_OP_SEND) {
+		if (READ_ONCE(sqe->__pad3[0]))
+			return -EINVAL;
+		sr->addr = u64_to_user_ptr(READ_ONCE(sqe->addr2));
+		sr->addr_len = READ_ONCE(sqe->addr_len);
+	} else if (sqe->addr2 || sqe->file_index) {
 		return -EINVAL;
+	}
 
 	sr->umsg = u64_to_user_ptr(READ_ONCE(sqe->addr));
 	sr->len = READ_ONCE(sqe->len);
@@ -315,6 +322,7 @@ int io_sendmsg(struct io_kiocb *req, unsigned int issue_flags)
 
 int io_send(struct io_kiocb *req, unsigned int issue_flags)
 {
+	struct sockaddr_storage __address;
 	struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
 	struct msghdr msg;
 	struct iovec iov;
@@ -323,9 +331,23 @@ int io_send(struct io_kiocb *req, unsigned int issue_flags)
 	int min_ret = 0;
 	int ret;
 
+	if (sr->addr) {
+		if (req_has_async_data(req)) {
+			struct io_async_msghdr *io = req->async_data;
+
+			msg.msg_name = &io->addr;
+		} else {
+			ret = move_addr_to_kernel(sr->addr, sr->addr_len, &__address);
+			if (unlikely(ret < 0))
+				return ret;
+			msg.msg_name = (struct sockaddr *)&__address;
+		}
+		msg.msg_namelen = sr->addr_len;
+	}
+
 	if (!(req->flags & REQ_F_POLLED) &&
 	    (sr->flags & IORING_RECVSEND_POLL_FIRST))
-		return -EAGAIN;
+		return io_setup_async_addr(req, &__address, issue_flags);
 
 	sock = sock_from_file(req->file);
 	if (unlikely(!sock))
@@ -351,13 +373,14 @@ int io_send(struct io_kiocb *req, unsigned int issue_flags)
 	ret = sock_sendmsg(sock, &msg);
 	if (ret < min_ret) {
 		if (ret == -EAGAIN && (issue_flags & IO_URING_F_NONBLOCK))
-			return -EAGAIN;
+			return io_setup_async_addr(req, &__address, issue_flags);
+
 		if (ret > 0 && io_net_retry(sock, flags)) {
 			sr->len -= ret;
 			sr->buf += ret;
 			sr->done_io += ret;
 			req->flags |= REQ_F_PARTIAL_IO;
-			return -EAGAIN;
+			return io_setup_async_addr(req, &__address, issue_flags);
 		}
 		if (ret == -ERESTARTSYS)
 			ret = -EINTR;
diff --git a/io_uring/net.h b/io_uring/net.h
index e7366aac335c..488d4dc7eee2 100644
--- a/io_uring/net.h
+++ b/io_uring/net.h
@@ -31,12 +31,13 @@ struct io_async_connect {
 int io_shutdown_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
 int io_shutdown(struct io_kiocb *req, unsigned int issue_flags);
 
-int io_sendzc_prep_async(struct io_kiocb *req);
 int io_sendmsg_prep_async(struct io_kiocb *req);
 void io_sendmsg_recvmsg_cleanup(struct io_kiocb *req);
 int io_sendmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
 int io_sendmsg(struct io_kiocb *req, unsigned int issue_flags);
+
 int io_send(struct io_kiocb *req, unsigned int issue_flags);
+int io_send_prep_async(struct io_kiocb *req);
 
 int io_recvmsg_prep_async(struct io_kiocb *req);
 int io_recvmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
diff --git a/io_uring/opdef.c b/io_uring/opdef.c
index f5e7a0e01729..8fb4d98c9f36 100644
--- a/io_uring/opdef.c
+++ b/io_uring/opdef.c
@@ -316,11 +316,14 @@ const struct io_op_def io_op_defs[] = {
 		.pollout		= 1,
 		.audit_skip		= 1,
 		.ioprio			= 1,
+		.manual_alloc		= 1,
 		.name			= "SEND",
 #if defined(CONFIG_NET)
+		.async_size		= sizeof(struct io_async_msghdr),
 		.prep			= io_sendmsg_prep,
 		.issue			= io_send,
 		.fail			= io_sendrecv_fail,
+		.prep_async		= io_send_prep_async,
 #else
 		.prep			= io_eopnotsupp_prep,
 #endif
@@ -495,7 +498,7 @@ const struct io_op_def io_op_defs[] = {
 		.async_size		= sizeof(struct io_async_msghdr),
 		.prep			= io_sendzc_prep,
 		.issue			= io_sendzc,
-		.prep_async		= io_sendzc_prep_async,
+		.prep_async		= io_send_prep_async,
 		.cleanup		= io_sendzc_cleanup,
 		.fail			= io_send_zc_fail,
 #else
-- 
2.37.2


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

* [PATCH 7/9] io_uring/net: rename io_sendzc()
  2022-09-21 11:17 [PATCH for-next 0/9] mix of 6.1 net patches Pavel Begunkov
                   ` (5 preceding siblings ...)
  2022-09-21 11:17 ` [PATCH 6/9] io_uring/net: support non-zerocopy sendto Pavel Begunkov
@ 2022-09-21 11:17 ` Pavel Begunkov
  2022-09-21 11:17 ` [PATCH 8/9] io_uring/net: combine fail handlers Pavel Begunkov
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Pavel Begunkov @ 2022-09-21 11:17 UTC (permalink / raw)
  To: io-uring; +Cc: Jens Axboe, asml.silence

Simple renaming of io_sendzc*() functions in preparatio to adding
a zerocopy sendmsg variant.

Signed-off-by: Pavel Begunkov <[email protected]>
---
 io_uring/net.c   | 6 +++---
 io_uring/net.h   | 6 +++---
 io_uring/opdef.c | 6 +++---
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/io_uring/net.c b/io_uring/net.c
index aa2c819cd85d..06c132edfd91 100644
--- a/io_uring/net.c
+++ b/io_uring/net.c
@@ -904,7 +904,7 @@ int io_recv(struct io_kiocb *req, unsigned int issue_flags)
 	return ret;
 }
 
-void io_sendzc_cleanup(struct io_kiocb *req)
+void io_send_zc_cleanup(struct io_kiocb *req)
 {
 	struct io_sr_msg *zc = io_kiocb_to_cmd(req, struct io_sr_msg);
 
@@ -913,7 +913,7 @@ void io_sendzc_cleanup(struct io_kiocb *req)
 	zc->notif = NULL;
 }
 
-int io_sendzc_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+int io_send_zc_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 {
 	struct io_sr_msg *zc = io_kiocb_to_cmd(req, struct io_sr_msg);
 	struct io_ring_ctx *ctx = req->ctx;
@@ -1022,7 +1022,7 @@ static int io_sg_from_iter(struct sock *sk, struct sk_buff *skb,
 	return ret;
 }
 
-int io_sendzc(struct io_kiocb *req, unsigned int issue_flags)
+int io_send_zc(struct io_kiocb *req, unsigned int issue_flags)
 {
 	struct sockaddr_storage __address;
 	struct io_sr_msg *zc = io_kiocb_to_cmd(req, struct io_sr_msg);
diff --git a/io_uring/net.h b/io_uring/net.h
index 488d4dc7eee2..337541f25b79 100644
--- a/io_uring/net.h
+++ b/io_uring/net.h
@@ -56,9 +56,9 @@ int io_connect_prep_async(struct io_kiocb *req);
 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);
 
-int io_sendzc(struct io_kiocb *req, unsigned int issue_flags);
-int io_sendzc_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
-void io_sendzc_cleanup(struct io_kiocb *req);
+int io_send_zc(struct io_kiocb *req, unsigned int issue_flags);
+int io_send_zc_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
+void io_send_zc_cleanup(struct io_kiocb *req);
 void io_send_zc_fail(struct io_kiocb *req);
 
 void io_netmsg_cache_free(struct io_cache_entry *entry);
diff --git a/io_uring/opdef.c b/io_uring/opdef.c
index 8fb4d98c9f36..36590f9ab37b 100644
--- a/io_uring/opdef.c
+++ b/io_uring/opdef.c
@@ -496,10 +496,10 @@ const struct io_op_def io_op_defs[] = {
 		.manual_alloc		= 1,
 #if defined(CONFIG_NET)
 		.async_size		= sizeof(struct io_async_msghdr),
-		.prep			= io_sendzc_prep,
-		.issue			= io_sendzc,
+		.prep			= io_send_zc_prep,
+		.issue			= io_send_zc,
 		.prep_async		= io_send_prep_async,
-		.cleanup		= io_sendzc_cleanup,
+		.cleanup		= io_send_zc_cleanup,
 		.fail			= io_send_zc_fail,
 #else
 		.prep			= io_eopnotsupp_prep,
-- 
2.37.2


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

* [PATCH 8/9] io_uring/net: combine fail handlers
  2022-09-21 11:17 [PATCH for-next 0/9] mix of 6.1 net patches Pavel Begunkov
                   ` (6 preceding siblings ...)
  2022-09-21 11:17 ` [PATCH 7/9] io_uring/net: rename io_sendzc() Pavel Begunkov
@ 2022-09-21 11:17 ` Pavel Begunkov
  2022-09-21 11:17 ` [PATCH 9/9] io_uring/net: zerocopy sendmsg Pavel Begunkov
  2022-09-21 16:37 ` [PATCH for-next 0/9] mix of 6.1 net patches Jens Axboe
  9 siblings, 0 replies; 11+ messages in thread
From: Pavel Begunkov @ 2022-09-21 11:17 UTC (permalink / raw)
  To: io-uring; +Cc: Jens Axboe, asml.silence

Merge io_send_zc_fail() into io_sendrecv_fail(), saves a few lines of
code and some headache for following patch.

Signed-off-by: Pavel Begunkov <[email protected]>
---
 io_uring/net.c   | 31 ++++++++++++++++---------------
 io_uring/net.h   |  1 -
 io_uring/opdef.c |  2 +-
 3 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/io_uring/net.c b/io_uring/net.c
index 06c132edfd91..4bcc2675001f 100644
--- a/io_uring/net.c
+++ b/io_uring/net.c
@@ -192,6 +192,7 @@ int io_send_prep_async(struct io_kiocb *req)
 	io = io_msg_alloc_async_prep(req);
 	if (!io)
 		return -ENOMEM;
+	io->free_iov = NULL;
 	ret = move_addr_to_kernel(zc->addr, zc->addr_len, &io->addr);
 	return ret;
 }
@@ -208,6 +209,7 @@ static int io_setup_async_addr(struct io_kiocb *req,
 	io = io_msg_alloc_async(req, issue_flags);
 	if (!io)
 		return -ENOMEM;
+	io->free_iov = NULL;
 	memcpy(&io->addr, addr_storage, sizeof(io->addr));
 	return -EAGAIN;
 }
@@ -1119,26 +1121,25 @@ int io_send_zc(struct io_kiocb *req, unsigned int issue_flags)
 void io_sendrecv_fail(struct io_kiocb *req)
 {
 	struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
+	struct io_async_msghdr *io;
 	int res = req->cqe.res;
 
 	if (req->flags & REQ_F_PARTIAL_IO)
 		res = sr->done_io;
-	io_req_set_res(req, res, req->cqe.flags);
-}
-
-void io_send_zc_fail(struct io_kiocb *req)
-{
-	struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
-	int res = req->cqe.res;
-
-	if (req->flags & REQ_F_PARTIAL_IO) {
-		if (req->flags & REQ_F_NEED_CLEANUP) {
-			io_notif_flush(sr->notif);
-			sr->notif = NULL;
-			req->flags &= ~REQ_F_NEED_CLEANUP;
-		}
-		res = sr->done_io;
+	if ((req->flags & REQ_F_NEED_CLEANUP) &&
+	    req->opcode == IORING_OP_SEND_ZC) {
+		/* preserve notification for partial I/O */
+		if (res < 0)
+			sr->notif->flags |= REQ_F_CQE_SKIP;
+		io_notif_flush(sr->notif);
+		sr->notif = NULL;
 	}
+	if (req_has_async_data(req)) {
+		io = req->async_data;
+		kfree(io->free_iov);
+		io->free_iov = NULL;
+	}
+	req->flags &= ~REQ_F_NEED_CLEANUP;
 	io_req_set_res(req, res, req->cqe.flags);
 }
 
diff --git a/io_uring/net.h b/io_uring/net.h
index 337541f25b79..45558e2b0a83 100644
--- a/io_uring/net.h
+++ b/io_uring/net.h
@@ -59,7 +59,6 @@ int io_connect(struct io_kiocb *req, unsigned int issue_flags);
 int io_send_zc(struct io_kiocb *req, unsigned int issue_flags);
 int io_send_zc_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
 void io_send_zc_cleanup(struct io_kiocb *req);
-void io_send_zc_fail(struct io_kiocb *req);
 
 void io_netmsg_cache_free(struct io_cache_entry *entry);
 #else
diff --git a/io_uring/opdef.c b/io_uring/opdef.c
index 36590f9ab37b..e9fd940c2ee1 100644
--- a/io_uring/opdef.c
+++ b/io_uring/opdef.c
@@ -500,7 +500,7 @@ const struct io_op_def io_op_defs[] = {
 		.issue			= io_send_zc,
 		.prep_async		= io_send_prep_async,
 		.cleanup		= io_send_zc_cleanup,
-		.fail			= io_send_zc_fail,
+		.fail			= io_sendrecv_fail,
 #else
 		.prep			= io_eopnotsupp_prep,
 #endif
-- 
2.37.2


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

* [PATCH 9/9] io_uring/net: zerocopy sendmsg
  2022-09-21 11:17 [PATCH for-next 0/9] mix of 6.1 net patches Pavel Begunkov
                   ` (7 preceding siblings ...)
  2022-09-21 11:17 ` [PATCH 8/9] io_uring/net: combine fail handlers Pavel Begunkov
@ 2022-09-21 11:17 ` Pavel Begunkov
  2022-09-21 16:37 ` [PATCH for-next 0/9] mix of 6.1 net patches Jens Axboe
  9 siblings, 0 replies; 11+ messages in thread
From: Pavel Begunkov @ 2022-09-21 11:17 UTC (permalink / raw)
  To: io-uring; +Cc: Jens Axboe, asml.silence

Add a zerocopy version of sendmsg.

Signed-off-by: Pavel Begunkov <[email protected]>
---
 include/uapi/linux/io_uring.h |  1 +
 io_uring/net.c                | 92 +++++++++++++++++++++++++++++++++--
 io_uring/net.h                |  1 +
 io_uring/opdef.c              | 19 ++++++++
 4 files changed, 108 insertions(+), 5 deletions(-)

diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h
index 972b179bc07a..92f29d9505a6 100644
--- a/include/uapi/linux/io_uring.h
+++ b/include/uapi/linux/io_uring.h
@@ -213,6 +213,7 @@ enum io_uring_op {
 	IORING_OP_SOCKET,
 	IORING_OP_URING_CMD,
 	IORING_OP_SEND_ZC,
+	IORING_OP_SENDMSG_ZC,
 
 	/* this goes last, obviously */
 	IORING_OP_LAST,
diff --git a/io_uring/net.c b/io_uring/net.c
index 4bcc2675001f..d086f397d4d0 100644
--- a/io_uring/net.c
+++ b/io_uring/net.c
@@ -909,7 +909,12 @@ int io_recv(struct io_kiocb *req, unsigned int issue_flags)
 void io_send_zc_cleanup(struct io_kiocb *req)
 {
 	struct io_sr_msg *zc = io_kiocb_to_cmd(req, struct io_sr_msg);
+	struct io_async_msghdr *io;
 
+	if (req_has_async_data(req)) {
+		io = req->async_data;
+		kfree(io->free_iov);
+	}
 	zc->notif->flags |= REQ_F_CQE_SKIP;
 	io_notif_flush(zc->notif);
 	zc->notif = NULL;
@@ -921,8 +926,7 @@ int io_send_zc_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 	struct io_ring_ctx *ctx = req->ctx;
 	struct io_kiocb *notif;
 
-	if (READ_ONCE(sqe->__pad2[0]) || READ_ONCE(sqe->addr3) ||
-	    READ_ONCE(sqe->__pad3[0]))
+	if (unlikely(READ_ONCE(sqe->__pad2[0]) || READ_ONCE(sqe->addr3)))
 		return -EINVAL;
 	/* we don't support IOSQE_CQE_SKIP_SUCCESS just yet */
 	if (req->flags & REQ_F_CQE_SKIP)
@@ -941,6 +945,19 @@ int io_send_zc_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 		req->imu = READ_ONCE(ctx->user_bufs[idx]);
 		io_req_set_rsrc_node(req, ctx, 0);
 	}
+
+	if (req->opcode == IORING_OP_SEND_ZC) {
+		if (READ_ONCE(sqe->__pad3[0]))
+			return -EINVAL;
+		zc->addr = u64_to_user_ptr(READ_ONCE(sqe->addr2));
+		zc->addr_len = READ_ONCE(sqe->addr_len);
+	} else {
+		if (unlikely(sqe->addr2 || sqe->file_index))
+			return -EINVAL;
+		if (unlikely(zc->flags & IORING_RECVSEND_FIXED_BUF))
+			return -EINVAL;
+	}
+
 	notif = zc->notif = io_alloc_notif(ctx);
 	if (!notif)
 		return -ENOMEM;
@@ -955,8 +972,6 @@ int io_send_zc_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 	if (zc->msg_flags & MSG_DONTWAIT)
 		req->flags |= REQ_F_NOWAIT;
 
-	zc->addr = u64_to_user_ptr(READ_ONCE(sqe->addr2));
-	zc->addr_len = READ_ONCE(sqe->addr_len);
 	zc->done_io = 0;
 
 #ifdef CONFIG_COMPAT
@@ -1118,6 +1133,73 @@ int io_send_zc(struct io_kiocb *req, unsigned int issue_flags)
 	return IOU_OK;
 }
 
+int io_sendmsg_zc(struct io_kiocb *req, unsigned int issue_flags)
+{
+	struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
+	struct io_async_msghdr iomsg, *kmsg;
+	struct socket *sock;
+	unsigned flags, cflags;
+	int ret, min_ret = 0;
+
+	sock = sock_from_file(req->file);
+	if (unlikely(!sock))
+		return -ENOTSOCK;
+
+	if (req_has_async_data(req)) {
+		kmsg = req->async_data;
+	} else {
+		ret = io_sendmsg_copy_hdr(req, &iomsg);
+		if (ret)
+			return ret;
+		kmsg = &iomsg;
+	}
+
+	if (!(req->flags & REQ_F_POLLED) &&
+	    (sr->flags & IORING_RECVSEND_POLL_FIRST))
+		return io_setup_async_msg(req, kmsg, issue_flags);
+
+	flags = sr->msg_flags | MSG_ZEROCOPY;
+	if (issue_flags & IO_URING_F_NONBLOCK)
+		flags |= MSG_DONTWAIT;
+	if (flags & MSG_WAITALL)
+		min_ret = iov_iter_count(&kmsg->msg.msg_iter);
+
+	kmsg->msg.msg_ubuf = &io_notif_to_data(sr->notif)->uarg;
+	kmsg->msg.sg_from_iter = io_sg_from_iter_iovec;
+	ret = __sys_sendmsg_sock(sock, &kmsg->msg, flags);
+
+	if (unlikely(ret < min_ret)) {
+		if (ret == -EAGAIN && (issue_flags & IO_URING_F_NONBLOCK))
+			return io_setup_async_msg(req, kmsg, issue_flags);
+
+		if (ret > 0 && io_net_retry(sock, flags)) {
+			sr->done_io += ret;
+			req->flags |= REQ_F_PARTIAL_IO;
+			return io_setup_async_msg(req, kmsg, issue_flags);
+		}
+		if (ret < 0 && !sr->done_io)
+			sr->notif->flags |= REQ_F_CQE_SKIP;
+		if (ret == -ERESTARTSYS)
+			ret = -EINTR;
+		req_set_fail(req);
+	}
+	/* fast path, check for non-NULL to avoid function call */
+	if (kmsg->free_iov)
+		kfree(kmsg->free_iov);
+
+	io_netmsg_recycle(req, issue_flags);
+	if (ret >= 0)
+		ret += sr->done_io;
+	else if (sr->done_io)
+		ret = sr->done_io;
+
+	io_notif_flush(sr->notif);
+	req->flags &= ~REQ_F_NEED_CLEANUP;
+	cflags = ret >= 0 ? IORING_CQE_F_MORE : 0;
+	io_req_set_res(req, ret, cflags);
+	return IOU_OK;
+}
+
 void io_sendrecv_fail(struct io_kiocb *req)
 {
 	struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
@@ -1127,7 +1209,7 @@ void io_sendrecv_fail(struct io_kiocb *req)
 	if (req->flags & REQ_F_PARTIAL_IO)
 		res = sr->done_io;
 	if ((req->flags & REQ_F_NEED_CLEANUP) &&
-	    req->opcode == IORING_OP_SEND_ZC) {
+	    (req->opcode == IORING_OP_SEND_ZC || req->opcode == IORING_OP_SENDMSG_ZC)) {
 		/* preserve notification for partial I/O */
 		if (res < 0)
 			sr->notif->flags |= REQ_F_CQE_SKIP;
diff --git a/io_uring/net.h b/io_uring/net.h
index 45558e2b0a83..5ffa11bf5d2e 100644
--- a/io_uring/net.h
+++ b/io_uring/net.h
@@ -57,6 +57,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);
 
 int io_send_zc(struct io_kiocb *req, unsigned int issue_flags);
+int io_sendmsg_zc(struct io_kiocb *req, unsigned int issue_flags);
 int io_send_zc_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
 void io_send_zc_cleanup(struct io_kiocb *req);
 
diff --git a/io_uring/opdef.c b/io_uring/opdef.c
index e9fd940c2ee1..3c930fef255b 100644
--- a/io_uring/opdef.c
+++ b/io_uring/opdef.c
@@ -503,6 +503,25 @@ const struct io_op_def io_op_defs[] = {
 		.fail			= io_sendrecv_fail,
 #else
 		.prep			= io_eopnotsupp_prep,
+#endif
+	},
+	[IORING_OP_SENDMSG_ZC] = {
+		.name			= "SENDMSG_ZC",
+		.needs_file		= 1,
+		.unbound_nonreg_file	= 1,
+		.pollout		= 1,
+		.audit_skip		= 1,
+		.ioprio			= 1,
+		.manual_alloc		= 1,
+#if defined(CONFIG_NET)
+		.async_size		= sizeof(struct io_async_msghdr),
+		.prep			= io_send_zc_prep,
+		.issue			= io_sendmsg_zc,
+		.prep_async		= io_sendmsg_prep_async,
+		.cleanup		= io_send_zc_cleanup,
+		.fail			= io_sendrecv_fail,
+#else
+		.prep			= io_eopnotsupp_prep,
 #endif
 	},
 };
-- 
2.37.2


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

* Re: [PATCH for-next 0/9] mix of 6.1 net patches
  2022-09-21 11:17 [PATCH for-next 0/9] mix of 6.1 net patches Pavel Begunkov
                   ` (8 preceding siblings ...)
  2022-09-21 11:17 ` [PATCH 9/9] io_uring/net: zerocopy sendmsg Pavel Begunkov
@ 2022-09-21 16:37 ` Jens Axboe
  9 siblings, 0 replies; 11+ messages in thread
From: Jens Axboe @ 2022-09-21 16:37 UTC (permalink / raw)
  To: Pavel Begunkov, io-uring

On Wed, 21 Sep 2022 12:17:45 +0100, Pavel Begunkov wrote:
> 0-4 fix a rare scenario when a partial I/O is completed with an error
> code rather than the number of bytes processed, which is especially
> bad with sockets and other non-idempotent files.
> 
> 5-9 add some net features, specifically 6/9 optionally transforms normal
> sends into sendto, and 9/9 adds zerocopy sendmsg.
> 
> [...]

Applied, thanks!

[1/9] io_uring: add custom opcode hooks on fail
      commit: 18b24300d6d3223192e69216d76ea273fa4b4f25
[2/9] io_uring/rw: don't lose partial IO result on fail
      commit: 7f4149434dbd8a9c356a959263b9e327bc5ed65b
[3/9] io_uring/net: don't lose partial send/recv on fail
      commit: 9a837772f2745351610e3554e193caf82e315bb3
[4/9] io_uring/net: don't lose partial send_zc on fail
      commit: 98e7a0e1c8102354ab28b46be737258739f7c92c
[5/9] io_uring/net: refactor io_setup_async_addr
      commit: 9f60a56760986bf3f2be3f906d2cd65215d0c065
[6/9] io_uring/net: support non-zerocopy sendto
      commit: ce6a8fdbb23f05cb3f6ddc6d0d76274eadf56a10
[7/9] io_uring/net: rename io_sendzc()
      commit: a7093eb542f723cc8f8e9d122d0aa82061f59ab4
[8/9] io_uring/net: combine fail handlers
      commit: 8cf8464184f4141294a9e86820b74a49e18a2436
[9/9] io_uring/net: zerocopy sendmsg
      commit: 2ec37c3b63d326147d7b70913b17c4ea3295c47b

Best regards,
-- 
Jens Axboe



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

end of thread, other threads:[~2022-09-21 16:46 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-09-21 11:17 [PATCH for-next 0/9] mix of 6.1 net patches Pavel Begunkov
2022-09-21 11:17 ` [PATCH 1/9] io_uring: add custom opcode hooks on fail Pavel Begunkov
2022-09-21 11:17 ` [PATCH 2/9] io_uring/rw: don't lose partial IO result " Pavel Begunkov
2022-09-21 11:17 ` [PATCH 3/9] io_uring/net: don't lose partial send/recv " Pavel Begunkov
2022-09-21 11:17 ` [PATCH 4/9] io_uring/net: don't lose partial send_zc " Pavel Begunkov
2022-09-21 11:17 ` [PATCH 5/9] io_uring/net: refactor io_setup_async_addr Pavel Begunkov
2022-09-21 11:17 ` [PATCH 6/9] io_uring/net: support non-zerocopy sendto Pavel Begunkov
2022-09-21 11:17 ` [PATCH 7/9] io_uring/net: rename io_sendzc() Pavel Begunkov
2022-09-21 11:17 ` [PATCH 8/9] io_uring/net: combine fail handlers Pavel Begunkov
2022-09-21 11:17 ` [PATCH 9/9] io_uring/net: zerocopy sendmsg Pavel Begunkov
2022-09-21 16:37 ` [PATCH for-next 0/9] mix of 6.1 net patches Jens Axboe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox