From 8ec093aa7ba6462a9fdb4172a97fb899fc940720 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Sun, 28 Jun 2020 20:47:11 +0800 Subject: [PATCH] io_uring: reap poll completions while waiting for refs to drop on exit to #28736503 commit 56952e91acc93ed624fe9da840900defb75f1323 upstream If we're doing polled IO and end up having requests being submitted async, then completions can come in while we're waiting for refs to drop. We need to reap these manually, as nobody else will be looking for them. Break the wait into 1/20th of a second time waits, and check for done poll completions if we time out. Otherwise we can have done poll completions sitting in ctx->poll_list, which needs us to reap them but we're just waiting for them. Cc: stable@vger.kernel.org Signed-off-by: Jens Axboe Signed-off-by: Xiaoguang Wang Acked-by: Joseph Qi --- fs/io_uring.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 4345aa3d3778..5a45da2b87e9 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -7333,7 +7333,17 @@ static void io_ring_exit_work(struct work_struct *work) if (ctx->rings) io_cqring_overflow_flush(ctx, true); - wait_for_completion(&ctx->ref_comp); + /* + * If we're doing polled IO and end up having requests being + * submitted async (out-of-line), then completions can come in while + * we're waiting for refs to drop. We need to reap these manually, + * as nobody else will be looking for them. + */ + while (!wait_for_completion_timeout(&ctx->ref_comp, HZ/20)) { + io_iopoll_reap_events(ctx); + if (ctx->rings) + io_cqring_overflow_flush(ctx, true); + } io_ring_ctx_free(ctx); } -- GitLab