All of lore.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 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.