Linux USB
 help / color / mirror / Atom feed
From: Sven Peter <sven@kernel.org>
To: Andreas Noever <andreas.noever@gmail.com>,
	 Mika Westerberg <westeri@kernel.org>,
	 Yehezkel Bernat <YehezkelShB@gmail.com>
Cc: asahi@lists.linux.dev, linux-usb@vger.kernel.org,
	 linux-kernel@vger.kernel.org,
	Konrad Dybcio <konradybcio@kernel.org>,
	 Sven Peter <sven@kernel.org>,
	stable@vger.kernel.org
Subject: [PATCH 3/5] thunderbolt: Fix domain reference leak when DPRX read is canceled
Date: Mon, 17 Aug 2026 21:54:00 +0200	[thread overview]
Message-ID: <20260817-b4-tbt-fixes-v1-3-eded2461f5fc@kernel.org> (raw)
In-Reply-To: <20260817-b4-tbt-fixes-v1-0-eded2461f5fc@kernel.org>

tb_tunnel_one_dp takes a domain reference which is only dropped once
tb_dp_tunnel_active has run on the work queue. If that work is
cancelled that reference is leaked. Since
commit f5cc545f5969 ("thunderbolt: Wait for tb_domain_release() to
complete when driver is removed") instead of just leaking memory this
now also blocks in the completion wait forever when unbinding the
driver.

That reference only exists to keep the domain around while the DPRX work
is scheduled so let the work itself own it: take it in tb_dp_dprx_start
and drop it in both places that end the work. Get/put are then paired
inside the same file and it doesn't matter anymore if the callback ever
runs.

Fixes: d6d458d42e1e ("thunderbolt: Handle DisplayPort tunnel activation asynchronously")
Cc: stable@vger.kernel.org
Signed-off-by: Sven Peter <sven@kernel.org>
---
 drivers/thunderbolt/tb.c     |  6 +-----
 drivers/thunderbolt/tunnel.c | 12 +++++++++---
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
index f43f2d952372..fb9da53fe391 100644
--- a/drivers/thunderbolt/tb.c
+++ b/drivers/thunderbolt/tb.c
@@ -1964,8 +1964,6 @@ static void tb_dp_tunnel_active(struct tb_tunnel *tunnel, void *data)
 		tb_dp_resource_unavailable(tb, in, "DPRX negotiation failed");
 	}
 	mutex_unlock(&tb->lock);
-
-	tb_domain_put(tb);
 }
 
 static void tb_tunnel_one_dp(struct tb *tb, struct tb_port *in,
@@ -2026,8 +2024,7 @@ static void tb_tunnel_one_dp(struct tb *tb, struct tb_port *in,
 	       available_up, available_down);
 
 	tunnel = tb_tunnel_alloc_dp(tb, in, out, link_nr, available_up,
-				    available_down, tb_dp_tunnel_active,
-				    tb_domain_get(tb));
+				    available_down, tb_dp_tunnel_active, tb);
 	if (!tunnel) {
 		tb_port_dbg(out, "could not allocate DP tunnel\n");
 		goto err_reclaim_usb;
@@ -2048,7 +2045,6 @@ static void tb_tunnel_one_dp(struct tb *tb, struct tb_port *in,
 	tb_tunnel_put(tunnel);
 err_reclaim_usb:
 	tb_reclaim_usb3_bandwidth(tb, in, out);
-	tb_domain_put(tb);
 err_detach_group:
 	tb_detach_bandwidth_group(in);
 err_dealloc_dp:
diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c
index 50580ebdac4b..82d9c0b556dd 100644
--- a/drivers/thunderbolt/tunnel.c
+++ b/drivers/thunderbolt/tunnel.c
@@ -1109,16 +1109,18 @@ static void tb_dp_dprx_work(struct work_struct *work)
 	if (tunnel->callback)
 		tunnel->callback(tunnel, tunnel->callback_data);
 	tb_tunnel_put(tunnel);
+	tb_domain_put(tb);
 }
 
 static int tb_dp_dprx_start(struct tb_tunnel *tunnel)
 {
 	if (tunnel->callback) {
 		/*
-		 * Bump up the reference to keep the tunnel around until the
-		 * work has run or has been canceled.
+		 * Bump up the references to keep the tunnel and the domain
+		 * around until the work has run or has been canceled.
 		 */
 		tb_tunnel_get(tunnel);
+		tb_domain_get(tunnel->tb);
 
 		tunnel->dprx_started = true;
 		tunnel->dprx_timeout = dprx_timeout_to_ktime(dprx_timeout);
@@ -1132,11 +1134,15 @@ static int tb_dp_dprx_start(struct tb_tunnel *tunnel)
 
 static void tb_dp_dprx_stop(struct tb_tunnel *tunnel)
 {
+	struct tb *tb = tunnel->tb;
+
 	if (tunnel->dprx_started) {
 		tunnel->dprx_started = false;
 		tunnel->dprx_canceled = true;
-		if (cancel_delayed_work(&tunnel->dprx_work))
+		if (cancel_delayed_work(&tunnel->dprx_work)) {
 			tb_tunnel_put(tunnel);
+			tb_domain_put(tb);
+		}
 	}
 }
 

-- 
2.55.0



  parent reply	other threads:[~2026-08-17 19:54 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-17 19:53 [PATCH 0/5] thunderbolt: Fix DP tunnel teardown while an async DPRX read is running Sven Peter
2026-08-17 19:53 ` [PATCH 1/5] thunderbolt: Fix tunnel reference leak when the DPRX work is not started Sven Peter
2026-08-18  4:42   ` Mika Westerberg
2026-08-18  5:44     ` Sven Peter
2026-08-18  6:00       ` Mika Westerberg
2026-08-18  6:11         ` Sven Peter
2026-08-18  6:19           ` Mika Westerberg
2026-08-17 19:53 ` [PATCH 2/5] thunderbolt: Hold a switch reference for each path hop Sven Peter
2026-08-18  6:05   ` Mika Westerberg
2026-08-17 19:54 ` Sven Peter [this message]
2026-08-17 19:54 ` [PATCH 4/5] thunderbolt: Don't access a DP tunnel after its DPRX read was canceled Sven Peter
2026-08-18  6:09   ` Mika Westerberg
2026-08-17 19:54 ` [PATCH 5/5] thunderbolt: Cancel the DPRX read when the domain is stopped Sven Peter
2026-08-18  6:17   ` Mika Westerberg
2026-08-21 17:58     ` Sven Peter
2026-08-23 11:34       ` Sven Peter

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=20260817-b4-tbt-fixes-v1-3-eded2461f5fc@kernel.org \
    --to=sven@kernel.org \
    --cc=YehezkelShB@gmail.com \
    --cc=andreas.noever@gmail.com \
    --cc=asahi@lists.linux.dev \
    --cc=konradybcio@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=westeri@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox