[PATCH PATCH net-next v4 1/8] tls: Factor tls_decrypt_async_drain() from recvmsg

Chuck Lever <[email protected]> Tue, 17 Mar 2026 11:04:14 -0400
Newsgroups dev.linux.lists.kernel-tls-handshake,org.kernel.vger.netdev
Message-ID <[email protected]>
From: Chuck Lever <[email protected]>

The recvmsg path pairs tls_decrypt_async_wait() with
__skb_queue_purge(&ctx->async_hold). Bundling the two into
tls_decrypt_async_drain() gives later patches a single call
for async teardown.

The purge is kept separate from tls_decrypt_async_wait()
because other callers (the -EBUSY fallback in
tls_do_decryption and the tls_strp_msg_hold error path)
need to synchronize without discarding held skbs that
are still awaiting delivery.

Reviewed-by: Hannes Reinecke <[email protected]>
Reviewed-by: Alistair Francis <[email protected]>
Signed-off-by: Chuck Lever <[email protected]>
---
 net/tls/tls_sw.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
index a656ce2357589672bcef24343fef0aa83606cf41..09ccfe82af1a6c38978327e941de34818b5da7a8 100644
--- a/net/tls/tls_sw.c
+++ b/net/tls/tls_sw.c
@@ -249,6 +249,18 @@ static int tls_decrypt_async_wait(struct tls_sw_context_rx *ctx)
 	return ctx->async_wait.err;
 }
 
+/* Collect all pending async AEAD completions and release the
+ * skbs held for them.  Returns the crypto error if any
+ * operation failed, zero otherwise.
+ */
+static int tls_decrypt_async_drain(struct tls_sw_context_rx *ctx)
+{
+	int ret = tls_decrypt_async_wait(ctx);
+
+	__skb_queue_purge(&ctx->async_hold);
+	return ret;
+}
+
 static int tls_do_decryption(struct sock *sk,
 			     struct scatterlist *sgin,
 			     struct scatterlist *sgout,
@@ -2222,9 +2234,8 @@ int tls_sw_recvmsg(struct sock *sk,
 	if (async) {
 		int ret;
 
-		/* Wait for all previously submitted records to be decrypted */
-		ret = tls_decrypt_async_wait(ctx);
-		__skb_queue_purge(&ctx->async_hold);
+		/* Drain all pending async decryptions and their held skbs */
+		ret = tls_decrypt_async_drain(ctx);
 
 		if (ret) {
 			if (err >= 0 || err == -EINPROGRESS)

-- 
2.53.0