summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Begunkov <asml.silence@gmail.com>2024-03-15 15:29:51 +0000
committerSasha Levin <sashal@kernel.org>2024-03-26 18:18:55 -0400
commitcc67ef53bfae809af34ded5007758fd2de800597 (patch)
tree2ed528abf79792ee3e75f884a00ceaef7109291c
parent49202a8256fc50517ef06fd5e2084c4febde6369 (diff)
downloadlinux-stable-cc67ef53bfae809af34ded5007758fd2de800597.tar.gz
linux-stable-cc67ef53bfae809af34ded5007758fd2de800597.tar.bz2
linux-stable-cc67ef53bfae809af34ded5007758fd2de800597.zip
io_uring: fix poll_remove stalled req completion
[ Upstream commit 5e3afe580a9f5ca173a6bd55ffe10948796ef7e5 ] Taking the ctx lock is not enough to use the deferred request completion infrastructure, it'll get queued into the list but no one would expect it there, so it will sit there until next io_submit_flush_completions(). It's hard to care about the cancellation path, so complete it via tw. Fixes: ef7dfac51d8ed ("io_uring/poll: serialize poll linked timer start with poll removal") Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> Link: https://lore.kernel.org/r/c446740bc16858f8a2a8dcdce899812f21d15f23.1710514702.git.asml.silence@gmail.com Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--io_uring/poll.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/io_uring/poll.c b/io_uring/poll.c
index 7513afc7b702..58b7556f621e 100644
--- a/io_uring/poll.c
+++ b/io_uring/poll.c
@@ -995,7 +995,6 @@ int io_poll_remove(struct io_kiocb *req, unsigned int issue_flags)
struct io_hash_bucket *bucket;
struct io_kiocb *preq;
int ret2, ret = 0;
- struct io_tw_state ts = { .locked = true };
io_ring_submit_lock(ctx, issue_flags);
preq = io_poll_find(ctx, true, &cd, &ctx->cancel_table, &bucket);
@@ -1044,7 +1043,8 @@ found:
req_set_fail(preq);
io_req_set_res(preq, -ECANCELED, 0);
- io_req_task_complete(preq, &ts);
+ preq->io_task_work.func = io_req_task_complete;
+ io_req_task_work_add(preq);
out:
io_ring_submit_unlock(ctx, issue_flags);
if (ret < 0) {