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 <jiayuan.chen@linux.dev>,
	Eric Dumazet <edumazet@google.com>,
	Neal Cardwell <ncardwell@google.com>,
	Kuniyuki Iwashima <kuniyu@google.com>,
	"David S. Miller" <davem@davemloft.net>,
	David Ahern <dsahern@kernel.org>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	Simon Horman <horms@kernel.org>,
	linux-kernel@vger.kernel.org
Subject: [PATCH net-next v1] tcp: remove redundant memset in hot paths with CONFIG_INIT_STACK_ALL_ZERO
Date: Thu, 12 Mar 2026 20:48:06 +0800	[thread overview]
Message-ID: <20260312124807.186341-1-jiayuan.chen@linux.dev> (raw)

Modern compilers with CONFIG_INIT_STACK_ALL_ZERO enabled
(-ftrivial-auto-var-init=zero) automatically zero-initialize all stack
variables via `rep stos` in the function prologue. However, the compiler
cannot eliminate explicit memset() calls on those same variables,
resulting in redundant zeroing of the same memory region.

Replace explicit memset() with `= {0}` initializers for stack variables
in TCP hot path functions. With `= {0}`, the compiler recognizes a single
initialization and generates only one zeroing sequence, whereas a
separate memset() after declaration always produces a second `rep stos`.

scripts/bloat-o-meter -t ../vmlinux.old vmlinux

  add/remove: 0/0 grow/shrink: 0/5 up/down: 0/-148 (-148)
  Function                                     old     new   delta
  __tcp_transmit_skb                          5256    5247      -9
  tcp_v6_send_response                        2629    2612     -17
  tcp_make_synack                             3106    3089     -17
  tcp_v4_send_ack                             1465    1428     -37
  tcp_v4_send_reset                           3269    3201     -68
  Total: Before=30075907, After=30075759, chg -0.00%

No functional change intended.

Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
---
 net/ipv4/tcp_ipv4.c   | 13 ++++---------
 net/ipv4/tcp_output.c |  6 ++----
 net/ipv6/tcp_ipv6.c   |  3 +--
 3 files changed, 7 insertions(+), 15 deletions(-)

diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 2ea8253b737a..1a413ca0e3bf 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -726,10 +726,10 @@ static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb,
 	struct {
 		struct tcphdr th;
 		__be32 opt[REPLY_OPTIONS_LEN];
-	} rep;
+	} rep = {0};
 	const __u8 *md5_hash_location = NULL;
 	const struct tcp_ao_hdr *aoh;
-	struct ip_reply_arg arg;
+	struct ip_reply_arg arg = {0};
 #ifdef CONFIG_TCP_MD5SIG
 	struct tcp_md5sig_key *key = NULL;
 	unsigned char newhash[16];
@@ -751,7 +751,6 @@ static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb,
 		return;
 
 	/* Swap the send and the receive. */
-	memset(&rep, 0, sizeof(rep));
 	rep.th.dest   = th->source;
 	rep.th.source = th->dest;
 	rep.th.doff   = sizeof(struct tcphdr) / 4;
@@ -765,7 +764,6 @@ static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb,
 				       skb->len - (th->doff << 2));
 	}
 
-	memset(&arg, 0, sizeof(arg));
 	arg.iov[0].iov_base = (unsigned char *)&rep;
 	arg.iov[0].iov_len  = sizeof(rep.th);
 
@@ -921,15 +919,12 @@ static void tcp_v4_send_ack(const struct sock *sk,
 	struct {
 		struct tcphdr th;
 		__be32 opt[(MAX_TCP_OPTION_SPACE  >> 2)];
-	} rep;
+	} rep = {0};
 	struct net *net = sock_net(sk);
-	struct ip_reply_arg arg;
+	struct ip_reply_arg arg = {0};
 	struct sock *ctl_sk;
 	u64 transmit_time;
 
-	memset(&rep.th, 0, sizeof(struct tcphdr));
-	memset(&arg, 0, sizeof(arg));
-
 	arg.iov[0].iov_base = (unsigned char *)&rep;
 	arg.iov[0].iov_len  = sizeof(rep.th);
 	if (tsecr) {
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 34a25ef61006..a0d5bed59f44 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1533,7 +1533,7 @@ static int __tcp_transmit_skb(struct sock *sk, struct sk_buff *skb,
 	struct inet_sock *inet;
 	struct tcp_sock *tp;
 	struct tcp_skb_cb *tcb;
-	struct tcp_out_options opts;
+	struct tcp_out_options opts = {0};
 	unsigned int tcp_options_size, tcp_header_size;
 	struct sk_buff *oskb = NULL;
 	struct tcp_key key;
@@ -1566,7 +1566,6 @@ static int __tcp_transmit_skb(struct sock *sk, struct sk_buff *skb,
 
 	inet = inet_sk(sk);
 	tcb = TCP_SKB_CB(skb);
-	memset(&opts.cleared, 0, sizeof(opts.cleared));
 
 	tcp_get_current_key(sk, &key);
 	if (unlikely(tcb->tcp_flags & TCPHDR_SYN)) {
@@ -3934,7 +3933,7 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
 {
 	struct inet_request_sock *ireq = inet_rsk(req);
 	const struct tcp_sock *tp = tcp_sk(sk);
-	struct tcp_out_options opts;
+	struct tcp_out_options opts = {0};
 	struct tcp_key key = {};
 	struct sk_buff *skb;
 	int tcp_header_size;
@@ -3972,7 +3971,6 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
 
 	mss = tcp_mss_clamp(tp, dst_metric_advmss(dst));
 
-	memset(&opts, 0, sizeof(opts));
 	now = tcp_clock_ns();
 #ifdef CONFIG_SYN_COOKIES
 	if (unlikely(synack_type == TCP_SYNACK_COOKIE && ireq->tstamp_ok))
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 8dc3874e8b92..e801927a8ce3 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -847,7 +847,7 @@ static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32
 	struct dst_entry *dst;
 	struct sk_buff *buff;
 	struct tcphdr *t1;
-	struct flowi6 fl6;
+	struct flowi6 fl6 = {0};
 	u32 mark = 0;
 
 	if (tsecr)
@@ -922,7 +922,6 @@ static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32
 	}
 #endif
 
-	memset(&fl6, 0, sizeof(fl6));
 	fl6.daddr = ipv6_hdr(skb)->saddr;
 	fl6.saddr = ipv6_hdr(skb)->daddr;
 	fl6.flowlabel = label;
-- 
2.43.0


             reply	other threads:[~2026-03-12 12:48 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-12 12:48 Jiayuan Chen [this message]
2026-03-12 12:53 ` [PATCH net-next v1] tcp: remove redundant memset in hot paths with CONFIG_INIT_STACK_ALL_ZERO Eric Dumazet
2026-03-12 13:45   ` Jiayuan Chen

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=20260312124807.186341-1-jiayuan.chen@linux.dev \
    --to=jiayuan.chen@linux.dev \
    --cc=davem@davemloft.net \
    --cc=dsahern@kernel.org \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=kuba@kernel.org \
    --cc=kuniyu@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ncardwell@google.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.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.