coml_nr in ctx_flush_and_put() is not protected by uring_lock, this may cause problems when accessing it parallelly: say coml_nr > 0 ctx_flush_and put other context if (compl_nr) get mutex coml_nr > 0 do flush coml_nr = 0 release mutex get mutex do flush (*) release mutex in (*) place, we call io_cqring_ev_posted() and users likely get none events there. Fixes: 2c32395d8111 ("io_uring: fix __tctx_task_work() ctx race") Signed-off-by: Hao Xu <haoxu@xxxxxxxxxxxxxxxxx> --- fs/io_uring.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index c755efdac71f..c3bd2b3fc46b 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -2005,7 +2005,8 @@ static void ctx_flush_and_put(struct io_ring_ctx *ctx) return; if (ctx->submit_state.compl_nr) { mutex_lock(&ctx->uring_lock); - io_submit_flush_completions(ctx); + if (ctx->submit_state.compl_nr) + io_submit_flush_completions(ctx); mutex_unlock(&ctx->uring_lock); } percpu_ref_put(&ctx->refs); -- 2.24.4