All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jens Axboe <axboe@kernel.dk>
To: stable@vger.kernel.org
Subject: [PATCH 7.3.y 12/16] io_uring: free the task context after a grace period
Date: Wed,  4 Nov 2026 11:44:43 -0700	[thread overview]
Message-ID: <20261104184447.516768-13-axboe@kernel.dk> (raw)
In-Reply-To: <20261104184447.516768-1-axboe@kernel.dk>

From: Chris Mason <mason@kernel.org>

Commit 9f5315d3f4368590c9fe06d4313b7247470bcf15 upstream.

A task other than the owner can free a request, io_ring_exit_work()
running the local task_work of a DEFER_TASKRUN ring for example, or
io_do_iopoll() reaping completions. io_put_task() then takes the else
branch:

    percpu_counter_sub(&tctx->inflight, 1);
    if (unlikely(atomic_read(&tctx->in_cancel)))
            wake_up(&tctx->wait);
    put_task_struct(tctx->task);

The first line is what lets the owner leave io_uring_cancel_generic(),
and on exec it frees the tctx right after. Nothing holds that off for
the remaining three lines, the task reference only covers a tctx freed
along with the task_struct. It used to work out because
io_uring_del_tctx_node() took the uring_lock that the freeing side holds
across io_put_task(), until that moved to tctx_lock.

Free the tctx with kfree_rcu(), and enter an RCU read section in
io_put_task() before the count is dropped.

Fixes: 5623eb1ed035 ("io_uring/tctx: add separate lock for list of tctx's in ctx")
Signed-off-by: Chris Mason <mason@kernel.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
---
 include/linux/io_uring_types.h | 3 +++
 io_uring/io_uring.c            | 2 ++
 io_uring/tctx.c                | 2 +-
 3 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/include/linux/io_uring_types.h b/include/linux/io_uring_types.h
index c5edf6246a4b..1c85ce0e471d 100644
--- a/include/linux/io_uring_types.h
+++ b/include/linux/io_uring_types.h
@@ -161,6 +161,9 @@ struct io_uring_task {
 	/* drains ->task_list once the task can no longer run task_work */
 	struct work_struct		fallback_work;
 
+	/* the tctx is freed after a grace period, see io_put_task() */
+	struct rcu_head			rcu;
+
 	struct { /* task_work */
 		struct mpscq		task_list;
 		struct callback_head	task_work;
diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
index 880be1fed3a6..c8aa6ca4a7cc 100644
--- a/io_uring/io_uring.c
+++ b/io_uring/io_uring.c
@@ -634,6 +634,8 @@ static inline void io_put_task(struct io_kiocb *req)
 	if (likely(tctx->task == current)) {
 		tctx->cached_refs++;
 	} else {
+		guard(rcu)();
+
 		percpu_counter_sub(&tctx->inflight, 1);
 		if (unlikely(atomic_read(&tctx->in_cancel)))
 			wake_up(&tctx->wait);
diff --git a/io_uring/tctx.c b/io_uring/tctx.c
index 291e30e00e45..b4fecea3ea47 100644
--- a/io_uring/tctx.c
+++ b/io_uring/tctx.c
@@ -64,7 +64,7 @@ void io_uring_free_tctx(struct task_struct *tsk)
 		WARN_ON_ONCE(tctx->cached_refs);
 
 		percpu_counter_destroy(&tctx->inflight);
-		kfree(tctx);
+		kfree_rcu(tctx, rcu);
 		tsk->io_uring = NULL;
 	}
 }
-- 
2.56.0


  parent reply	other threads:[~2026-11-04 18:45 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-04 18:44 [PATCH 7.3.y 00/16] io_uring fixes for 7.3-stable Jens Axboe
2026-11-04 18:44 ` [PATCH 7.3.y 01/16] io_uring/kbuf: advance head when a pickup empties the buffer ring Jens Axboe
2026-11-04 18:44 ` [PATCH 7.3.y 02/16] io_uring/net: keep recvmsg buffer select length within MAX_RW_COUNT Jens Axboe
2026-11-04 18:44 ` [PATCH 7.3.y 03/16] io_uring/net: mask socket type with SOCK_TYPE_MASK in io_socket_bpf_populate() Jens Axboe
2026-11-04 18:44 ` [PATCH 7.3.y 04/16] io_uring/register: enforce per-task restrictions in io_uring_register_blind() Jens Axboe
2026-11-04 18:44 ` [PATCH 7.3.y 05/16] io_uring/net: don't retry a non-blocking connect() that fails with -EAGAIN Jens Axboe
2026-11-04 18:44 ` [PATCH 7.3.y 06/16] io_uring: keep the drain active when a deferred drain request is started Jens Axboe
2026-11-04 18:44 ` [PATCH 7.3.y 07/16] io_uring/io-wq: no new workers once the exit has begun Jens Axboe
2026-11-04 18:44 ` [PATCH 7.3.y 08/16] io_uring/rsrc: charge buffer arrays and nodes to memcg Jens Axboe
2026-11-04 18:44 ` [PATCH 7.3.y 09/16] io_uring: charge tctx nodes and personalities Jens Axboe
2026-11-04 18:44 ` [PATCH 7.3.y 10/16] io_uring: free XArray nodes left by a failed store Jens Axboe
2026-11-04 18:44 ` [PATCH 7.3.y 11/16] io_uring/bpf-ops: clear bpf_ctx while submitting SQEs Jens Axboe
2026-11-04 18:44 ` Jens Axboe [this message]
2026-11-04 18:44 ` [PATCH 7.3.y 13/16] io_uring/sqpoll: don't wait for the thread to exit Jens Axboe
2026-11-04 18:44 ` [PATCH 7.3.y 14/16] io_uring: defer foreign io-wq enqueues to task_work Jens Axboe
2026-11-04 18:44 ` [PATCH 7.3.y 15/16] io_uring/timeout: count cancelled timeouts in cq_timeouts Jens Axboe
2026-11-04 18:44 ` [PATCH 7.3.y 16/16] io_uring/net: fix multishot recv length limit accounting Jens Axboe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261104184447.516768-13-axboe@kernel.dk \
    --to=axboe@kernel.dk \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.