poll->canceled may be set from different contexts, even async, so io_poll_rewait() should be prepared that it can change and not read it twice. Signed-off-by: Pavel Begunkov <asml.silence@xxxxxxxxx> --- fs/io_uring.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index de5822350345..376d9c875dc2 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -4897,15 +4897,16 @@ static bool io_poll_rewait(struct io_kiocb *req, struct io_poll_iocb *poll) __acquires(&req->ctx->completion_lock) { struct io_ring_ctx *ctx = req->ctx; + bool canceled = READ_ONCE(poll->canceled); - if (!req->result && !READ_ONCE(poll->canceled)) { + if (!req->result && !canceled) { struct poll_table_struct pt = { ._key = poll->events }; req->result = vfs_poll(req->file, &pt) & poll->events; } spin_lock_irq(&ctx->completion_lock); - if (!req->result && !READ_ONCE(poll->canceled)) { + if (!req->result && !canceled) { add_wait_queue(poll->head, &poll->wait); return true; } -- 2.24.0