summaryrefslogtreecommitdiffstats
path: root/io_uring/poll.c
diff options
context:
space:
mode:
authorPavel Begunkov <asml.silence@gmail.com>2022-07-07 16:13:14 +0200
committerJens Axboe <axboe@kernel.dk>2022-07-25 02:39:17 +0200
commit7a121ced6e6430d49fb802067b4f020f6df62362 (patch)
treeb02069f47e97ff3968442b6405dd9014bfb459c6 /io_uring/poll.c
parentio_uring: disable multishot recvmsg (diff)
downloadlinux-7a121ced6e6430d49fb802067b4f020f6df62362.tar.xz
linux-7a121ced6e6430d49fb802067b4f020f6df62362.zip
io_uring: don't miss setting REQ_F_DOUBLE_POLL
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>
Diffstat (limited to 'io_uring/poll.c')
-rw-r--r--io_uring/poll.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/io_uring/poll.c b/io_uring/poll.c
index 57747d92bba4..3710a0a46a87 100644
--- a/io_uring/poll.c
+++ b/io_uring/poll.c
@@ -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();
}