summaryrefslogtreecommitdiff
path: root/fs/io_uring.c
diff options
context:
space:
mode:
authorPavel Begunkov <asml.silence@gmail.com>2020-07-06 17:59:29 +0300
committerJens Axboe <axboe@kernel.dk>2020-07-06 09:06:20 -0600
commit3aadc23e6054353ca056bf14e87250c79efbd7ed (patch)
tree78402f4b738e24c646cf9f2f9b8dc66aabc78f30 /fs/io_uring.c
parent8b3656af2a37dc538d21e144a5a94bacae05e9f1 (diff)
downloadlwn-3aadc23e6054353ca056bf14e87250c79efbd7ed.tar.gz
lwn-3aadc23e6054353ca056bf14e87250c79efbd7ed.zip
io_uring: don't delay iopoll'ed req completion
->iopoll() may have completed current request, but instead of reaping it, io_do_iopoll() just continues with the next request in the list. As a result it can leave just polled and completed request in the list up until next syscall. Even outer loop in io_iopoll_getevents() doesn't help the situation. E.g. poll_list: req0 -> req1 If req0->iopoll() completed both requests, and @min<=1, then @req0 will be left behind. Check whether a req was completed after ->iopoll(). Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'fs/io_uring.c')
-rw-r--r--fs/io_uring.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c
index 9464f9470bbc..60f1a81c6c35 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -2015,6 +2015,10 @@ static int io_do_iopoll(struct io_ring_ctx *ctx, unsigned int *nr_events,
if (ret < 0)
break;
+ /* iopoll may have completed current req */
+ if (READ_ONCE(req->iopoll_completed))
+ list_move_tail(&req->list, &done);
+
if (ret && spin)
spin = false;
ret = 0;