public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
From: Jakub Kicinski <kuba@kernel.org>
To: Chuck Lever <cel@kernel.org>
Cc: John Fastabend <john.fastabend@gmail.com>,
	Sabrina Dubroca <sd@queasysnail.net>,
	Eric Dumazet <edumazet@google.com>,
	Simon Horman <horms@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	netdev@vger.kernel.org, kernel-tls-handshake@lists.linux.dev,
	Chuck Lever <chuck.lever@oracle.com>
Subject: Re: [PATCH net-next v9 4/5] tls: Suppress spurious saved_data_ready on all receive paths
Date: Sat, 2 May 2026 18:19:21 -0700	[thread overview]
Message-ID: <20260502181921.6d74ac78@kernel.org> (raw)
In-Reply-To: <20260429-tls-read-sock-v9-4-39e71aa7810f@oracle.com>

On Wed, 29 Apr 2026 17:48:11 -0400 Chuck Lever wrote:
> -void tls_strp_check_rcv(struct tls_strparser *strp)
> +/**
> + * tls_strp_check_rcv - parse queued data and optionally notify
> + * @strp: TLS stream parser instance
> + * @wake: if true, fire consumer notification when a record is newly
> + *        parsed by this call
> + *
> + * Returns immediately when a record is already ready; the wake fires
> + * only on transitions from no-record to record-ready. Callers that
> + * need to notify a waiter about a record parsed by another path
> + * should invoke tls_rx_msg_ready() directly.
> + */

nit/reminder: no kdoc

> +void tls_strp_check_rcv(struct tls_strparser *strp, bool wake)

I wonder if it'd make sense to s/wake/announce/ for consistency?

>  {
>  	if (unlikely(strp->stopped) || strp->msg_ready)
>  		return;
>  
>  	if (tls_strp_read_sock(strp) == -ENOMEM)
>  		queue_work(tls_strp_wq, &strp->work);
> +	else if (wake && strp->msg_ready)
> +		tls_rx_msg_ready(strp);
>  }

> diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
> index c58d3b0b0a8a..cbb068266bab 100644
> --- a/net/tls/tls_sw.c
> +++ b/net/tls/tls_sw.c
> @@ -1383,7 +1383,11 @@ tls_rx_rec_wait(struct sock *sk, struct sk_psock *psock, bool nonblock,
>  			return ret;
>  
>  		if (!skb_queue_empty(&sk->sk_receive_queue)) {
> -			tls_strp_check_rcv(&ctx->strp);
> +			/* Defer notification to the exit point;
> +			 * this thread will consume the record
> +			 * directly.

this line could be un-wrapped AFAICT

> +			 */
> +			tls_strp_check_rcv(&ctx->strp, false);
>  			if (tls_strp_msg_ready(ctx))
>  				break;
>  		}
> @@ -1869,9 +1873,17 @@ static int tls_record_content_type(struct msghdr *msg, struct tls_msg *tlm,
>  	return 1;
>  }
>  
> -static void tls_rx_rec_done(struct tls_sw_context_rx *ctx)
> +/* Parse any data left in the lower socket and hand off a single
> + * notification to the next reader. tls_rx_msg_ready() is a no-op
> + * when the current record has already been announced, so paths
> + * that drained ctx->rx_list without touching the strparser do
> + * not re-fire saved_data_ready() for a record BH or the worker
> + * already announced.
> + */
> +static void tls_rx_handoff(struct tls_sw_context_rx *ctx)
>  {
> -	tls_strp_msg_done(&ctx->strp);
> +	tls_strp_check_rcv(&ctx->strp, false);
> +	tls_rx_msg_ready(&ctx->strp);
>  }
>  
>  /* This function traverses the rx_list in tls receive context to copies the
> @@ -2152,7 +2164,7 @@ int tls_sw_recvmsg(struct sock *sk,
>  		err = tls_record_content_type(msg, tls_msg(darg.skb), &control);
>  		if (err <= 0) {
>  			DEBUG_NET_WARN_ON_ONCE(darg.zc);
> -			tls_rx_rec_done(ctx);
> +			tls_strp_msg_release(&ctx->strp);
>  put_on_rx_list_err:
>  			__skb_queue_tail(&ctx->rx_list, darg.skb);
>  			goto recv_end;
> @@ -2166,7 +2178,8 @@ int tls_sw_recvmsg(struct sock *sk,
>  		/* TLS 1.3 may have updated the length by more than overhead */
>  		rxm = strp_msg(darg.skb);
>  		chunk = rxm->full_len;
> -		tls_rx_rec_done(ctx);
> +		tls_strp_msg_release(&ctx->strp);
> +		tls_strp_check_rcv(&ctx->strp, false);
>  
>  		if (!darg.zc) {
>  			bool partially_consumed = chunk > len;
> @@ -2260,6 +2273,7 @@ int tls_sw_recvmsg(struct sock *sk,
>  	copied += decrypted;
>  
>  end:
> +	tls_rx_handoff(ctx);
>  	tls_rx_reader_unlock(sk, ctx);
>  	if (psock)
>  		sk_psock_put(sk, psock);
> @@ -2300,7 +2314,7 @@ ssize_t tls_sw_splice_read(struct socket *sock,  loff_t *ppos,
>  		if (err < 0)
>  			goto splice_read_end;
>  
> -		tls_rx_rec_done(ctx);
> +		tls_strp_msg_release(&ctx->strp);
>  		skb = darg.skb;
>  	}
>  
> @@ -2327,6 +2341,7 @@ ssize_t tls_sw_splice_read(struct socket *sock,  loff_t *ppos,
>  	consume_skb(skb);
>  
>  splice_read_end:
> +	tls_rx_handoff(ctx);

I don't get why the tls_rx_handoff() thing exists, TBH
Maybe it made sense in the context of the code which is no longer part
of the series. But without it it looks pretty odd. Fells like you should
simply be suppressing notifications when tls_strp_check_rcv() is called
by tls_rx_rec_done() and then tls_rx_reader_release() should make sure
it flushes the ->data_ready if it's exiting on a read && !announced
condition. In rcvmsg() path you're now calling tls_strp_check_rcv()
twice.

>  	tls_rx_reader_unlock(sk, ctx);
>  	return copied ? : err;
>  
> @@ -2392,7 +2407,7 @@ int tls_sw_read_sock(struct sock *sk, read_descriptor_t *desc,
>  			tlm = tls_msg(skb);
>  			decrypted += rxm->full_len;
>  
> -			tls_rx_rec_done(ctx);
> +			tls_strp_msg_release(&ctx->strp);
>  		}
>  
>  		/* read_sock does not support reading control messages */
> @@ -2420,6 +2435,7 @@ int tls_sw_read_sock(struct sock *sk, read_descriptor_t *desc,
>  	}
>  
>  read_sock_end:
> +	tls_rx_handoff(ctx);
>  	tls_rx_reader_release(sk, ctx);
>  	return copied ? : err;
>  
> @@ -2504,10 +2520,18 @@ int tls_rx_msg_size(struct tls_strparser *strp, struct sk_buff *skb)
>  	return ret;
>  }
>  
> +/* Fire saved_data_ready() at most once per parsed record.
> + * msg_announced is cleared by tls_strp_msg_release() when the
> + * current record is consumed, arming the next announcement.
> + */
>  void tls_rx_msg_ready(struct tls_strparser *strp)

Given the change to the semantics maybe this should be named
tls_rx_msg_maybe_announce() or _flush_announce() now ?

>  {
>  	struct tls_sw_context_rx *ctx;
>  
> +	if (!READ_ONCE(strp->msg_ready) || strp->msg_announced)
> +		return;
> +	strp->msg_announced = 1;
> +
>  	ctx = container_of(strp, struct tls_sw_context_rx, strp);
>  	ctx->saved_data_ready(strp->sk);
>  }
> 


  reply	other threads:[~2026-05-03  1:19 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-29 21:48 [PATCH net-next v9 0/5] TLS read_sock performance scalability Chuck Lever
2026-04-29 21:48 ` [PATCH net-next v9 1/5] tls: Abort the connection on decrypt failure Chuck Lever
2026-05-03  1:20   ` Jakub Kicinski
2026-04-29 21:48 ` [PATCH net-next v9 2/5] tls: Fix dangling skb pointer in tls_sw_read_sock() Chuck Lever
2026-05-03  1:05   ` Jakub Kicinski
2026-04-29 21:48 ` [PATCH net-next v9 3/5] tls: Factor tls_strp_msg_release() from tls_strp_msg_done() Chuck Lever
2026-05-03  1:09   ` Jakub Kicinski
2026-04-29 21:48 ` [PATCH net-next v9 4/5] tls: Suppress spurious saved_data_ready on all receive paths Chuck Lever
2026-05-03  1:19   ` Jakub Kicinski [this message]
2026-04-29 21:48 ` [PATCH net-next v9 5/5] tls: Flush backlog before waiting for a new record Chuck Lever
2026-04-29 23:13 ` [PATCH net-next v9 0/5] TLS read_sock performance scalability Jakub Kicinski
2026-04-29 23:15   ` Chuck Lever
2026-05-03  1:04 ` Jakub Kicinski
2026-05-03 19:34   ` Chuck Lever
2026-05-04 13:33     ` Sabrina Dubroca
2026-05-04 15:59       ` Chuck Lever

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=20260502181921.6d74ac78@kernel.org \
    --to=kuba@kernel.org \
    --cc=cel@kernel.org \
    --cc=chuck.lever@oracle.com \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=john.fastabend@gmail.com \
    --cc=kernel-tls-handshake@lists.linux.dev \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=sd@queasysnail.net \
    /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