io_uring: don't miss setting REQ_F_DOUBLE_POLL
authorPavel Begunkov <asml.silence@gmail.com>
Thu, 7 Jul 2022 14:13:14 +0000 (15:13 +0100)
committerJens Axboe <axboe@kernel.dk>
Mon, 25 Jul 2022 00:39:17 +0000 (18:39 -0600)
When adding a second poll entry we should set REQ_F_DOUBLE_POLL
unconditionally. We might race with the first entry removal but that
doesn't change the rule.

Fixes: a18427bb2d9b ("io_uring: optimise submission side poll_refs")
Reported-and-tested-by: syzbot+49950ba66096b1f0209b@syzkaller.appspotmail.com
Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Link: https://lore.kernel.org/r/8b680d83ded07424db83e8745585e7a6d72826ef.1657203020.git.asml.silence@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
io_uring/poll.c

index 57747d9..3710a0a 100644 (file)
@@ -401,16 +401,18 @@ static void io_poll_double_prepare(struct io_kiocb *req)
        /* head is RCU protected, see io_poll_remove_entries() comments */
        rcu_read_lock();
        head = smp_load_acquire(&poll->head);
-       if (head) {
-               /*
-                * poll arm may not hold ownership and so race with
-                * io_poll_wake() by modifying req->flags. There is only one
-                * poll entry queued, serialise with it by taking its head lock.
-                */
+       /*
+        * poll arm may not hold ownership and so race with
+        * io_poll_wake() by modifying req->flags. There is only one
+        * poll entry queued, serialise with it by taking its head lock.
+        */
+       if (head)
                spin_lock_irq(&head->lock);
-               req->flags |= REQ_F_DOUBLE_POLL;
+
+       req->flags |= REQ_F_DOUBLE_POLL;
+
+       if (head)
                spin_unlock_irq(&head->lock);
-       }
        rcu_read_unlock();
 }