Netdev List
 help / color / mirror / Atom feed
From: Eric Dumazet <edumazet@google.com>
To: "David S . Miller" <davem@davemloft.net>,
	Jakub Kicinski <kuba@kernel.org>,
	 Paolo Abeni <pabeni@redhat.com>
Cc: Simon Horman <horms@kernel.org>,
	Neal Cardwell <ncardwell@google.com>,
	 Kuniyuki Iwashima <kuniyu@google.com>,
	netdev@vger.kernel.org, eric.dumazet@gmail.com,
	 Eric Dumazet <edumazet@google.com>
Subject: [PATCH net-next] tcp: add sk->sk_synq_overflow_ts
Date: Wed, 29 Apr 2026 01:49:13 +0000	[thread overview]
Message-ID: <20260429014913.1043836-1-edumazet@google.com> (raw)

tcp_synq_overflow() and tcp_synq_no_recent_overflow() are currently
using tp->rx_opt.ts_recent_stamp to store a 32bit jiffie value.

Use instead full "unsigned long" storage, as an union with sk->sk_stamp
which is not used by a TCP listener.

As a bonus, we can remove time_between32() from include/linux/time.h.

Signed-off-by: Eric Dumazet <edumazet@google.com>
---
 include/linux/time.h         | 13 ---------
 include/net/sock.h           |  5 +++-
 include/net/sock_reuseport.h |  2 +-
 include/net/tcp.h            | 56 ++++++++++++------------------------
 4 files changed, 24 insertions(+), 52 deletions(-)

diff --git a/include/linux/time.h b/include/linux/time.h
index 16cf4522d6f338176f1fa753360e8bdec2c7bc8d..7554e44ea4a9472d306c770e2e6d2907ef5f244a 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -84,19 +84,6 @@ static inline bool itimerspec64_valid(const struct itimerspec64 *its)
 #define time_after32(a, b)	((s32)((u32)(b) - (u32)(a)) < 0)
 #define time_before32(b, a)	time_after32(a, b)
 
-/**
- * time_between32 - check if a 32-bit timestamp is within a given time range
- * @t:	the time which may be within [l,h]
- * @l:	the lower bound of the range
- * @h:	the higher bound of the range
- *
- * time_before32(t, l, h) returns true if @l <= @t <= @h. All operands are
- * treated as 32-bit integers.
- *
- * Equivalent to !(time_before32(@t, @l) || time_after32(@t, @h)).
- */
-#define time_between32(t, l, h) ((u32)(h) - (u32)(l) >= (u32)(t) - (u32)(l))
-
 # include <vdso/time.h>
 
 #endif
diff --git a/include/net/sock.h b/include/net/sock.h
index dccd3738c3687056b67c8de44fce9842dcc365ec..ed1e52de43c3394fae74f45a85527dec08c7ec48 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -548,7 +548,10 @@ struct sock {
 	struct pid		*sk_peer_pid;
 	const struct cred	*sk_peer_cred;
 
-	ktime_t			sk_stamp;
+	union {
+		ktime_t		sk_stamp;
+		unsigned long	sk_synq_overflow_ts; /* tcp_synq_overflow */
+	};
 #if BITS_PER_LONG==32
 	seqlock_t		sk_stamp_seq;
 #endif
diff --git a/include/net/sock_reuseport.h b/include/net/sock_reuseport.h
index 6e4faf3ee76fbd86e2c4ac6ff13ead5c9a9187d6..a6beda5dca40777e27ef071d777081fd8af6ea03 100644
--- a/include/net/sock_reuseport.h
+++ b/include/net/sock_reuseport.h
@@ -20,7 +20,7 @@ struct sock_reuseport {
 	/* The last synq overflow event timestamp of this
 	 * reuse->socks[] group.
 	 */
-	unsigned int		synq_overflow_ts;
+	unsigned long		synq_overflow_ts;
 	/* ID stays the same even after the size of socks[] grows. */
 	unsigned int		reuseport_id;
 	unsigned int		bind_inany:1;
diff --git a/include/net/tcp.h b/include/net/tcp.h
index ecbadcb3a7446cb18c245e670ba49ff574dfaff7..78ca1e336321da50953e6268c4a5d5185eb7791a 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -634,56 +634,38 @@ struct bpf_tcp_req_attrs {
  */
 static inline void tcp_synq_overflow(const struct sock *sk)
 {
-	unsigned int last_overflow;
-	unsigned int now = jiffies;
-
-	if (sk->sk_reuseport) {
-		struct sock_reuseport *reuse;
-
-		reuse = rcu_dereference(sk->sk_reuseport_cb);
-		if (likely(reuse)) {
-			last_overflow = READ_ONCE(reuse->synq_overflow_ts);
-			if (!time_between32(now, last_overflow,
-					    last_overflow + HZ))
-				WRITE_ONCE(reuse->synq_overflow_ts, now);
-			return;
-		}
-	}
+	unsigned long last_overflow, now = jiffies;
+	struct sock_reuseport *reuse;
+	unsigned long *ptr;
+
+	reuse = sk->sk_reuseport ? rcu_dereference(sk->sk_reuseport_cb) : NULL;
+	ptr = reuse ? &reuse->synq_overflow_ts : &((struct sock *)sk)->sk_synq_overflow_ts;
+	last_overflow = READ_ONCE(*ptr);
 
-	last_overflow = READ_ONCE(tcp_sk(sk)->rx_opt.ts_recent_stamp);
-	if (!time_between32(now, last_overflow, last_overflow + HZ))
-		WRITE_ONCE(tcp_sk_rw(sk)->rx_opt.ts_recent_stamp, now);
+	if (time_after(now, last_overflow + HZ))
+		WRITE_ONCE(*ptr, now);
 }
 
 /* syncookies: no recent synqueue overflow on this listening socket? */
 static inline bool tcp_synq_no_recent_overflow(const struct sock *sk)
 {
-	unsigned int last_overflow;
-	unsigned int now = jiffies;
-
-	if (sk->sk_reuseport) {
-		struct sock_reuseport *reuse;
-
-		reuse = rcu_dereference(sk->sk_reuseport_cb);
-		if (likely(reuse)) {
-			last_overflow = READ_ONCE(reuse->synq_overflow_ts);
-			return !time_between32(now, last_overflow - HZ,
-					       last_overflow +
-					       TCP_SYNCOOKIE_VALID);
-		}
-	}
+	unsigned long last_overflow, now = jiffies;
+	const struct sock_reuseport *reuse;
+	const unsigned long *ptr;
 
-	last_overflow = READ_ONCE(tcp_sk(sk)->rx_opt.ts_recent_stamp);
+	reuse = sk->sk_reuseport ? rcu_dereference(sk->sk_reuseport_cb) : NULL;
+	ptr = reuse ? &reuse->synq_overflow_ts : &sk->sk_synq_overflow_ts;
+	last_overflow = READ_ONCE(*ptr);
 
 	/* If last_overflow <= jiffies <= last_overflow + TCP_SYNCOOKIE_VALID,
 	 * then we're under synflood. However, we have to use
 	 * 'last_overflow - HZ' as lower bound. That's because a concurrent
-	 * tcp_synq_overflow() could update .ts_recent_stamp after we read
-	 * jiffies but before we store .ts_recent_stamp into last_overflow,
+	 * tcp_synq_overflow() could update synq_overflow_ts after we read
+	 * jiffies but before we store synq_overflow_ts into last_overflow,
 	 * which could lead to rejecting a valid syncookie.
 	 */
-	return !time_between32(now, last_overflow - HZ,
-			       last_overflow + TCP_SYNCOOKIE_VALID);
+	return !time_in_range(now, last_overflow - HZ,
+			      last_overflow + TCP_SYNCOOKIE_VALID);
 }
 
 static inline u32 tcp_cookie_time(void)
-- 
2.54.0.545.g6539524ca2-goog


             reply	other threads:[~2026-04-29  1:49 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-29  1:49 Eric Dumazet [this message]
2026-04-29  1:58 ` [PATCH net-next] tcp: add sk->sk_synq_overflow_ts Eric Dumazet

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=20260429014913.1043836-1-edumazet@google.com \
    --to=edumazet@google.com \
    --cc=davem@davemloft.net \
    --cc=eric.dumazet@gmail.com \
    --cc=horms@kernel.org \
    --cc=kuba@kernel.org \
    --cc=kuniyu@google.com \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox