* [PATCH net-next] tcp: add sk->sk_synq_overflow_ts
@ 2026-04-29 1:49 Eric Dumazet
2026-04-29 1:58 ` Eric Dumazet
0 siblings, 1 reply; 2+ messages in thread
From: Eric Dumazet @ 2026-04-29 1:49 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Neal Cardwell, Kuniyuki Iwashima, netdev,
eric.dumazet, Eric Dumazet
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
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH net-next] tcp: add sk->sk_synq_overflow_ts
2026-04-29 1:49 [PATCH net-next] tcp: add sk->sk_synq_overflow_ts Eric Dumazet
@ 2026-04-29 1:58 ` Eric Dumazet
0 siblings, 0 replies; 2+ messages in thread
From: Eric Dumazet @ 2026-04-29 1:58 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Neal Cardwell, Kuniyuki Iwashima, netdev,
eric.dumazet
On Tue, Apr 28, 2026 at 6:49 PM Eric Dumazet <edumazet@google.com> wrote:
>
> 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.
Please disregard this, I sent a wrong version of this patch.
pw-bot: cr
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-04-29 1:58 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-29 1:49 [PATCH net-next] tcp: add sk->sk_synq_overflow_ts Eric Dumazet
2026-04-29 1:58 ` Eric Dumazet
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox