Skip to content

Commit f851453

Browse files
committed
Merge tag 'io_uring-6.2-2023-01-27' of git://git.kernel.dk/linux
Pull io_uring fixes from Jens Axboe: "Two small fixes for this release: - Sanitize how async prep is done for drain requests, so we ensure that it always gets done (Dylan) - A ring provided buffer recycling fix for multishot receive (me)" * tag 'io_uring-6.2-2023-01-27' of git://git.kernel.dk/linux: io_uring: always prep_async for drain requests io_uring/net: cache provided buffer group value for multishot receives
2 parents 28cca23 + ef5c600 commit f851453

File tree

2 files changed

+19
-10
lines changed

2 files changed

+19
-10
lines changed

io_uring/io_uring.c

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1765,17 +1765,12 @@ static __cold void io_drain_req(struct io_kiocb *req)
17651765
}
17661766
spin_unlock(&ctx->completion_lock);
17671767

1768-
ret = io_req_prep_async(req);
1769-
if (ret) {
1770-
fail:
1771-
io_req_defer_failed(req, ret);
1772-
return;
1773-
}
17741768
io_prep_async_link(req);
17751769
de = kmalloc(sizeof(*de), GFP_KERNEL);
17761770
if (!de) {
17771771
ret = -ENOMEM;
1778-
goto fail;
1772+
io_req_defer_failed(req, ret);
1773+
return;
17791774
}
17801775

17811776
spin_lock(&ctx->completion_lock);
@@ -2048,13 +2043,16 @@ static void io_queue_sqe_fallback(struct io_kiocb *req)
20482043
req->flags &= ~REQ_F_HARDLINK;
20492044
req->flags |= REQ_F_LINK;
20502045
io_req_defer_failed(req, req->cqe.res);
2051-
} else if (unlikely(req->ctx->drain_active)) {
2052-
io_drain_req(req);
20532046
} else {
20542047
int ret = io_req_prep_async(req);
20552048

2056-
if (unlikely(ret))
2049+
if (unlikely(ret)) {
20572050
io_req_defer_failed(req, ret);
2051+
return;
2052+
}
2053+
2054+
if (unlikely(req->ctx->drain_active))
2055+
io_drain_req(req);
20582056
else
20592057
io_queue_iowq(req, NULL);
20602058
}

io_uring/net.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ struct io_sr_msg {
6262
u16 flags;
6363
/* initialised and used only by !msg send variants */
6464
u16 addr_len;
65+
u16 buf_group;
6566
void __user *addr;
6667
/* used only for send zerocopy */
6768
struct io_kiocb *notif;
@@ -580,6 +581,15 @@ int io_recvmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
580581
if (req->opcode == IORING_OP_RECV && sr->len)
581582
return -EINVAL;
582583
req->flags |= REQ_F_APOLL_MULTISHOT;
584+
/*
585+
* Store the buffer group for this multishot receive separately,
586+
* as if we end up doing an io-wq based issue that selects a
587+
* buffer, it has to be committed immediately and that will
588+
* clear ->buf_list. This means we lose the link to the buffer
589+
* list, and the eventual buffer put on completion then cannot
590+
* restore it.
591+
*/
592+
sr->buf_group = req->buf_index;
583593
}
584594

585595
#ifdef CONFIG_COMPAT
@@ -596,6 +606,7 @@ static inline void io_recv_prep_retry(struct io_kiocb *req)
596606

597607
sr->done_io = 0;
598608
sr->len = 0; /* get from the provided buffer */
609+
req->buf_index = sr->buf_group;
599610
}
600611

601612
/*

0 commit comments

Comments
 (0)