public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
From: Jiayuan Chen <jiayuan.chen@linux.dev>
To: netdev@vger.kernel.org
Cc: jiayuan.chen@linux.dev, Jiayuan Chen <jiayuan.chen@shopee.com>,
	syzbot+ca1345cca66556f3d79b@syzkaller.appspotmail.com,
	John Fastabend <john.fastabend@gmail.com>,
	Jakub Kicinski <kuba@kernel.org>,
	Sabrina Dubroca <sd@queasysnail.net>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Paolo Abeni <pabeni@redhat.com>, Simon Horman <horms@kernel.org>,
	Vakul Garg <vakul.garg@nxp.com>,
	linux-kernel@vger.kernel.org
Subject: [PATCH net v1] tls: fix hung task in tx_work_handler by using non-blocking sends
Date: Fri, 27 Feb 2026 14:32:31 +0800	[thread overview]
Message-ID: <20260227063231.168520-1-jiayuan.chen@linux.dev> (raw)

From: Jiayuan Chen <jiayuan.chen@shopee.com>

tx_work_handler calls tls_tx_records with flags=-1, which preserves
each record's original tx_flags but results in tcp_sendmsg_locked
using an infinite send timeout. When the peer is unresponsive and the
send buffer is full, tcp_sendmsg_locked blocks indefinitely in
sk_stream_wait_memory. This causes tls_sk_proto_close to hang in
cancel_delayed_work_sync waiting for tx_work_handler to finish,
leading to a hung task:

  INFO: task ...: blocked for more than ... seconds.
  Call Trace:
    cancel_delayed_work_sync
    tls_sw_cancel_work_tx
    tls_sk_proto_close

A workqueue handler should never block indefinitely. Fix this by
introducing __tls_tx_records() with an extra_flags parameter that
gets OR'd into each record's tx_flags. tx_work_handler uses this to
pass MSG_DONTWAIT so tcp_sendmsg_locked returns -EAGAIN immediately
when the send buffer is full, without overwriting the original
per-record flags (MSG_MORE, MSG_NOSIGNAL, etc.). On -EAGAIN, the
existing reschedule mechanism retries after a short delay.

Also consolidate the two identical reschedule paths (lock contention
and -EAGAIN) into one.

Reported-by: syzbot+ca1345cca66556f3d79b@syzkaller.appspotmail.com
Fixes: a42055e8d2c3 ("net/tls: Add support for async encryption of records for performance")
Signed-off-by: Jiayuan Chen <jiayuan.chen@shopee.com>
---
 net/tls/tls_sw.c | 31 +++++++++++++++++++++----------
 1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
index 9937d4c810f2..c9d3d44581da 100644
--- a/net/tls/tls_sw.c
+++ b/net/tls/tls_sw.c
@@ -404,7 +404,7 @@ static void tls_free_open_rec(struct sock *sk)
 	}
 }
 
-int tls_tx_records(struct sock *sk, int flags)
+static int __tls_tx_records(struct sock *sk, int flags, int extra_flags)
 {
 	struct tls_context *tls_ctx = tls_get_ctx(sk);
 	struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx);
@@ -417,9 +417,9 @@ int tls_tx_records(struct sock *sk, int flags)
 				       struct tls_rec, list);
 
 		if (flags == -1)
-			tx_flags = rec->tx_flags;
+			tx_flags = rec->tx_flags | extra_flags;
 		else
-			tx_flags = flags;
+			tx_flags = flags | extra_flags;
 
 		rc = tls_push_partial_record(sk, tls_ctx, tx_flags);
 		if (rc)
@@ -463,6 +463,11 @@ int tls_tx_records(struct sock *sk, int flags)
 	return rc;
 }
 
+int tls_tx_records(struct sock *sk, int flags)
+{
+	return __tls_tx_records(sk, flags, 0);
+}
+
 static void tls_encrypt_done(void *data, int err)
 {
 	struct tls_sw_context_tx *ctx;
@@ -2629,6 +2634,7 @@ static void tx_work_handler(struct work_struct *work)
 	struct sock *sk = tx_work->sk;
 	struct tls_context *tls_ctx = tls_get_ctx(sk);
 	struct tls_sw_context_tx *ctx;
+	int rc;
 
 	if (unlikely(!tls_ctx))
 		return;
@@ -2642,16 +2648,21 @@ static void tx_work_handler(struct work_struct *work)
 
 	if (mutex_trylock(&tls_ctx->tx_lock)) {
 		lock_sock(sk);
-		tls_tx_records(sk, -1);
+		rc = __tls_tx_records(sk, -1, MSG_DONTWAIT);
 		release_sock(sk);
 		mutex_unlock(&tls_ctx->tx_lock);
-	} else if (!test_and_set_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask)) {
-		/* Someone is holding the tx_lock, they will likely run Tx
-		 * and cancel the work on their way out of the lock section.
-		 * Schedule a long delay just in case.
-		 */
-		schedule_delayed_work(&ctx->tx_work.work, msecs_to_jiffies(10));
+		if (rc != -EAGAIN)
+			return;
 	}
+
+	/* Someone is holding the tx_lock, they will likely run Tx
+	 * and cancel the work on their way out of the lock section.
+	 * Schedule a long delay just in case.
+	 * Also reschedule on -EAGAIN when the send buffer is full
+	 * to avoid blocking the workqueue indefinitely.
+	 */
+	if (!test_and_set_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask))
+		schedule_delayed_work(&ctx->tx_work.work, msecs_to_jiffies(10));
 }
 
 static bool tls_is_tx_ready(struct tls_sw_context_tx *ctx)
-- 
2.43.0


             reply	other threads:[~2026-02-27  6:33 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-27  6:32 Jiayuan Chen [this message]
2026-02-28 17:15 ` [PATCH net v1] tls: fix hung task in tx_work_handler by using non-blocking sends Jakub Kicinski
2026-03-01  6:52   ` Jiayuan Chen
2026-03-03  0:38     ` Jakub Kicinski

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=20260227063231.168520-1-jiayuan.chen@linux.dev \
    --to=jiayuan.chen@linux.dev \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=jiayuan.chen@shopee.com \
    --cc=john.fastabend@gmail.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=sd@queasysnail.net \
    --cc=syzbot+ca1345cca66556f3d79b@syzkaller.appspotmail.com \
    --cc=vakul.garg@nxp.com \
    /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