From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C87BC29E04F; Mon, 12 May 2025 18:05:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747073111; cv=none; b=VpOycqMwQFutXtOR3ihku7PeaB8YDAwgKpeGe7q3LNVECwZ4aXESEwCs0aUf+pU5as0gQlg5oO2i7dVXHYxaC3BlgPSxx3XuQPJ7jnmoBcatYHKjmFVCe43+rYLotlgNIXYwIs1gUcgQd2guVHWlFGTBotHPp+qjsmm/CDtsnFw= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747073111; c=relaxed/simple; bh=Ui/npbgSS/tq8IKw2Tuu5il/T7BEa3dczYtyDt3Neg8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qILK0Sobstcp4zMPpu2BZwNotb9dUGiNQOtcnVyrxXHfrKdTUWWfjBV+3aSDDFncj4kG2P31vCcfztDGUanj7p/x+0+6x57cyWLL3l+T9CxFSBfop7Y25PhS8JZqGhwiLrEqiDmcnx9N7oVfeV2FKoHINyUYTOuuLtBll63SZiw= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=Eh/SoiZH; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="Eh/SoiZH" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4F9E8C4CEF1; Mon, 12 May 2025 18:05:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1747073111; bh=Ui/npbgSS/tq8IKw2Tuu5il/T7BEa3dczYtyDt3Neg8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Eh/SoiZH0EjpMZtnMJx0F80DgVi2DoDbatHqcLBsrJ6/nd4PPl9+LGyk7IAOw1QFL tagD4XfXGrBLNDTjf8o+g95kZ+vFZgDLVXKegaTiHU36rc01dxXfEJETysETQAfWU3 HeTMyx8B/ukrFkTbqB+fiw4S1/odXUShcBPw8Z88= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Chase Hiltz , Jens Axboe Subject: [PATCH 6.12 156/184] io_uring: always arm linked timeouts prior to issue Date: Mon, 12 May 2025 19:45:57 +0200 Message-ID: <20250512172048.171659591@linuxfoundation.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250512172041.624042835@linuxfoundation.org> References: <20250512172041.624042835@linuxfoundation.org> User-Agent: quilt/0.68 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.12-stable review patch. If anyone has any objections, please let me know. ------------------ From: Jens Axboe Commit b53e523261bf058ea4a518b482222e7a277b186b upstream. There are a few spots where linked timeouts are armed, and not all of them adhere to the pre-arm, attempt issue, post-arm pattern. This can be problematic if the linked request returns that it will trigger a callback later, and does so before the linked timeout is fully armed. Consolidate all the linked timeout handling into __io_issue_sqe(), rather than have it spread throughout the various issue entry points. Cc: stable@vger.kernel.org Link: https://github.com/axboe/liburing/issues/1390 Reported-by: Chase Hiltz Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- io_uring/io_uring.c | 50 +++++++++++++++----------------------------------- 1 file changed, 15 insertions(+), 35 deletions(-) --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -441,24 +441,6 @@ static struct io_kiocb *__io_prep_linked return req->link; } -static inline struct io_kiocb *io_prep_linked_timeout(struct io_kiocb *req) -{ - if (likely(!(req->flags & REQ_F_ARM_LTIMEOUT))) - return NULL; - return __io_prep_linked_timeout(req); -} - -static noinline void __io_arm_ltimeout(struct io_kiocb *req) -{ - io_queue_linked_timeout(__io_prep_linked_timeout(req)); -} - -static inline void io_arm_ltimeout(struct io_kiocb *req) -{ - if (unlikely(req->flags & REQ_F_ARM_LTIMEOUT)) - __io_arm_ltimeout(req); -} - static void io_prep_async_work(struct io_kiocb *req) { const struct io_issue_def *def = &io_issue_defs[req->opcode]; @@ -511,7 +493,6 @@ static void io_prep_async_link(struct io static void io_queue_iowq(struct io_kiocb *req) { - struct io_kiocb *link = io_prep_linked_timeout(req); struct io_uring_task *tctx = req->task->io_uring; BUG_ON(!tctx); @@ -536,8 +517,6 @@ static void io_queue_iowq(struct io_kioc trace_io_uring_queue_async_work(req, io_wq_is_hashed(&req->work)); io_wq_enqueue(tctx->io_wq, &req->work); - if (link) - io_queue_linked_timeout(link); } static void io_req_queue_iowq_tw(struct io_kiocb *req, struct io_tw_state *ts) @@ -1731,17 +1710,24 @@ static bool io_assign_file(struct io_kio return !!req->file; } +#define REQ_ISSUE_SLOW_FLAGS (REQ_F_CREDS | REQ_F_ARM_LTIMEOUT) + static int io_issue_sqe(struct io_kiocb *req, unsigned int issue_flags) { const struct io_issue_def *def = &io_issue_defs[req->opcode]; const struct cred *creds = NULL; + struct io_kiocb *link = NULL; int ret; if (unlikely(!io_assign_file(req, def, issue_flags))) return -EBADF; - if (unlikely((req->flags & REQ_F_CREDS) && req->creds != current_cred())) - creds = override_creds(req->creds); + if (unlikely(req->flags & REQ_ISSUE_SLOW_FLAGS)) { + if ((req->flags & REQ_F_CREDS) && req->creds != current_cred()) + creds = override_creds(req->creds); + if (req->flags & REQ_F_ARM_LTIMEOUT) + link = __io_prep_linked_timeout(req); + } if (!def->audit_skip) audit_uring_entry(req->opcode); @@ -1751,8 +1737,12 @@ static int io_issue_sqe(struct io_kiocb if (!def->audit_skip) audit_uring_exit(!ret, ret); - if (creds) - revert_creds(creds); + if (unlikely(creds || link)) { + if (creds) + revert_creds(creds); + if (link) + io_queue_linked_timeout(link); + } if (ret == IOU_OK) { if (issue_flags & IO_URING_F_COMPLETE_DEFER) @@ -1765,7 +1755,6 @@ static int io_issue_sqe(struct io_kiocb if (ret == IOU_ISSUE_SKIP_COMPLETE) { ret = 0; - io_arm_ltimeout(req); /* If the op doesn't have a file, we're not polling for it */ if ((req->ctx->flags & IORING_SETUP_IOPOLL) && def->iopoll_queue) @@ -1808,8 +1797,6 @@ void io_wq_submit_work(struct io_wq_work else req_ref_get(req); - io_arm_ltimeout(req); - /* either cancelled or io-wq is dying, so don't touch tctx->iowq */ if (atomic_read(&work->flags) & IO_WQ_WORK_CANCEL) { fail: @@ -1929,15 +1916,11 @@ struct file *io_file_get_normal(struct i static void io_queue_async(struct io_kiocb *req, int ret) __must_hold(&req->ctx->uring_lock) { - struct io_kiocb *linked_timeout; - if (ret != -EAGAIN || (req->flags & REQ_F_NOWAIT)) { io_req_defer_failed(req, ret); return; } - linked_timeout = io_prep_linked_timeout(req); - switch (io_arm_poll_handler(req, 0)) { case IO_APOLL_READY: io_kbuf_recycle(req, 0); @@ -1950,9 +1933,6 @@ static void io_queue_async(struct io_kio case IO_APOLL_OK: break; } - - if (linked_timeout) - io_queue_linked_timeout(linked_timeout); } static inline void io_queue_sqe(struct io_kiocb *req)