Commit cd664b0e authored by Pavel Begunkov's avatar Pavel Begunkov Committed by Jens Axboe
Browse files

io_uring: fix hanging iopoll in case of -EAGAIN



io_do_iopoll() won't do anything with a request unless
req->iopoll_completed is set. So io_complete_rw_iopoll() has to set
it, otherwise io_do_iopoll() will poll a file again and again even
though the request of interest was completed long time ago.

Also, remove -EAGAIN check from io_issue_sqe() as it races with
the changed lines. The request will take the long way and be
resubmitted from io_iopoll*().

io_kiocb's result and iopoll_completed")

Fixes: bbde017a ("io_uring: add memory barrier to synchronize
Signed-off-by: default avatarPavel Begunkov <asml.silence@gmail.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent b772f07a
Loading
Loading
Loading
Loading
+2 −7
Original line number Diff line number Diff line
@@ -1994,11 +1994,9 @@ static void io_complete_rw_iopoll(struct kiocb *kiocb, long res, long res2)

	WRITE_ONCE(req->result, res);
	/* order with io_poll_complete() checking ->result */
	if (res != -EAGAIN) {
	smp_wmb();
	WRITE_ONCE(req->iopoll_completed, 1);
}
}

/*
 * After the iocb has been issued, it's safe to be found on the poll list.
@@ -5353,9 +5351,6 @@ static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
	if ((ctx->flags & IORING_SETUP_IOPOLL) && req->file) {
		const bool in_async = io_wq_current_is_worker();

		if (req->result == -EAGAIN)
			return -EAGAIN;

		/* workqueue context doesn't hold uring_lock, grab it now */
		if (in_async)
			mutex_lock(&ctx->uring_lock);