diff options
author | Pavel Begunkov <asml.silence@gmail.com> | 2021-09-08 22:49:17 +0300 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2021-09-08 22:57:56 +0300 |
commit | c57a91fb1ccfa203ba3e31e5a389cb04de5b0561 (patch) | |
tree | d03ab06beb7d97625301c48c80df6b3d9fef5489 /fs | |
parent | 713b9825a4c47897f66ad69409581e7734a8728e (diff) | |
download | linux-c57a91fb1ccfa203ba3e31e5a389cb04de5b0561.tar.xz |
io_uring: fix missing mb() before waitqueue_active
In case of !SQPOLL, io_cqring_ev_posted_iopoll() doesn't provide a
memory barrier required by waitqueue_active(&ctx->poll_wait). There is
a wq_has_sleeper(), which does smb_mb() inside, but it's called only for
SQPOLL.
Fixes: 5fd4617840596 ("io_uring: be smarter about waking multiple CQ ring waiters")
Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Link: https://lore.kernel.org/r/2982e53bcea2274006ed435ee2a77197107d8a29.1631130542.git.asml.silence@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/io_uring.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c index d816c09c88a5..d80d8359501f 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1619,8 +1619,11 @@ static void io_cqring_ev_posted(struct io_ring_ctx *ctx) static void io_cqring_ev_posted_iopoll(struct io_ring_ctx *ctx) { + /* see waitqueue_active() comment */ + smp_mb(); + if (ctx->flags & IORING_SETUP_SQPOLL) { - if (wq_has_sleeper(&ctx->cq_wait)) + if (waitqueue_active(&ctx->cq_wait)) wake_up_all(&ctx->cq_wait); } if (io_should_trigger_evfd(ctx)) |