Skip to content

Commit 1a8ec63

Browse files
isilenceaxboe
authored andcommitted
io_uring: fix io_queue_proc modifying req->flags
With multiple poll entries __io_queue_proc() might be running in parallel with poll handlers and possibly task_work, we should not be carelessly modifying req->flags there. io_poll_double_prepare() handles a similar case with locking but it's much easier to move it into __io_arm_poll_handler(). Cc: stable@vger.kernel.org Fixes: 595e522 ("io_uring/poll: don't enable lazy wake for POLLEXCLUSIVE") Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> Link: https://lore.kernel.org/r/455cc49e38cf32026fa1b49670be8c162c2cb583.1709834755.git.asml.silence@gmail.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 70581dc commit 1a8ec63

File tree

1 file changed

+11
-8
lines changed

1 file changed

+11
-8
lines changed

io_uring/poll.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -540,14 +540,6 @@ static void __io_queue_proc(struct io_poll *poll, struct io_poll_table *pt,
540540
poll->wait.private = (void *) wqe_private;
541541

542542
if (poll->events & EPOLLEXCLUSIVE) {
543-
/*
544-
* Exclusive waits may only wake a limited amount of entries
545-
* rather than all of them, this may interfere with lazy
546-
* wake if someone does wait(events > 1). Ensure we don't do
547-
* lazy wake for those, as we need to process each one as they
548-
* come in.
549-
*/
550-
req->flags |= REQ_F_POLL_NO_LAZY;
551543
add_wait_queue_exclusive(head, &poll->wait);
552544
} else {
553545
add_wait_queue(head, &poll->wait);
@@ -616,6 +608,17 @@ static int __io_arm_poll_handler(struct io_kiocb *req,
616608
if (issue_flags & IO_URING_F_UNLOCKED)
617609
req->flags &= ~REQ_F_HASH_LOCKED;
618610

611+
612+
/*
613+
* Exclusive waits may only wake a limited amount of entries
614+
* rather than all of them, this may interfere with lazy
615+
* wake if someone does wait(events > 1). Ensure we don't do
616+
* lazy wake for those, as we need to process each one as they
617+
* come in.
618+
*/
619+
if (poll->events & EPOLLEXCLUSIVE)
620+
req->flags |= REQ_F_POLL_NO_LAZY;
621+
619622
mask = vfs_poll(req->file, &ipt->pt) & poll->events;
620623

621624
if (unlikely(ipt->error || !ipt->nr_entries)) {

0 commit comments

Comments
 (0)