On 8/20/21 9:39 PM, Hao Xu wrote: > 在 2021/8/21 上午2:59, Pavel Begunkov 写道: >> On 8/20/21 7:40 PM, Hao Xu wrote: >>> coml_nr in ctx_flush_and_put() is not protected by uring_lock, this >>> may cause problems when accessing it parallelly. >> >> Did you hit any problem? It sounds like it should be fine as is: >> >> The trick is that it's only responsible to flush requests added >> during execution of current call to tctx_task_work(), and those >> naturally synchronised with the current task. All other potentially >> enqueued requests will be of someone else's responsibility. >> >> So, if nobody flushed requests, we're finely in-sync. If we see >> 0 there, but actually enqueued a request, it means someone >> actually flushed it after the request had been added. >> >> Probably, needs a more formal explanation with happens-before >> and so. > I should put more detail in the commit message, the thing is: > 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 do a bunch of unnecessary works, moreover, we I wouldn't care about overhead, that shouldn't be much > call io_cqring_ev_posted() which I think we shouldn't. IMHO, users should expect spurious io_cqring_ev_posted(), though there were some eventfd users complaining before, so for them we can do if (state->nr) { lock(); if (state->nr) flush(); unlock(); } >>> Fixes: d10299e14aae ("io_uring: inline struct io_comp_state") >> >> FWIW, it came much earlier than this commit, IIRC >> >> commit 2c32395d8111037ae2cb8cab883e80bcdbb70713 >> Author: Pavel Begunkov <asml.silence@xxxxxxxxx> >> Date: Sun Feb 28 22:04:53 2021 +0000 >> >> io_uring: fix __tctx_task_work() ctx race >> >> >>> Signed-off-by: Hao Xu <haoxu@xxxxxxxxxxxxxxxxx> >>> --- >>> fs/io_uring.c | 7 +++---- >>> 1 file changed, 3 insertions(+), 4 deletions(-) >>> >>> diff --git a/fs/io_uring.c b/fs/io_uring.c >>> index c755efdac71f..420f8dfa5327 100644 >>> --- a/fs/io_uring.c >>> +++ b/fs/io_uring.c >>> @@ -2003,11 +2003,10 @@ static void ctx_flush_and_put(struct io_ring_ctx *ctx) >>> { >>> if (!ctx) >>> return; >>> - if (ctx->submit_state.compl_nr) { >>> - mutex_lock(&ctx->uring_lock); >>> + mutex_lock(&ctx->uring_lock); >>> + if (ctx->submit_state.compl_nr) >>> io_submit_flush_completions(ctx); >>> - mutex_unlock(&ctx->uring_lock); >>> - } >>> + mutex_unlock(&ctx->uring_lock); >>> percpu_ref_put(&ctx->refs); >>> } >>> >> > -- Pavel Begunkov