86b71d0daee05 ("io_uring: deduplicate freeing linked timeouts") actually fixed one bug, where io_fail_links() doesn't consider REQ_F_COMP_LOCKED, but added another -- io_cqring_fill_event() without any locking Return locking back there and do it right with REQ_F_COMP_LOCKED check. Fixes: 86b71d0daee05 ("io_uring: deduplicate freeing linked timeouts") Signed-off-by: Pavel Begunkov <asml.silence@xxxxxxxxx> --- fs/io_uring.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/io_uring.c b/fs/io_uring.c index 5928404acb17..a1ea41b7b811 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1620,6 +1620,10 @@ static struct io_kiocb *io_req_link_next(struct io_kiocb *req) static void io_fail_links(struct io_kiocb *req) { struct io_ring_ctx *ctx = req->ctx; + unsigned long flags = 0; + + if (!(req->flags & REQ_F_COMP_LOCKED)) + spin_lock_irqsave(&ctx->completion_lock, flags); while (!list_empty(&req->link_list)) { struct io_kiocb *link = list_first_entry(&req->link_list, @@ -1634,6 +1638,8 @@ static void io_fail_links(struct io_kiocb *req) } io_commit_cqring(ctx); + if (!(req->flags & REQ_F_COMP_LOCKED)) + spin_unlock_irqrestore(&ctx->completion_lock, flags); io_cqring_ev_posted(ctx); } -- 2.24.0