* [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