]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
tcp: remove icsk->icsk_retransmit_timer
authorEric Dumazet <edumazet@google.com>
Mon, 24 Nov 2025 17:50:13 +0000 (17:50 +0000)
committerJakub Kicinski <kuba@kernel.org>
Wed, 26 Nov 2025 03:28:29 +0000 (19:28 -0800)
Now sk->sk_timer is no longer used by TCP keepalive, we can use
its storage for TCP and MPTCP retransmit timers for better
cache locality.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20251124175013.1473655-5-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Documentation/networking/net_cachelines/inet_connection_sock.rst
include/net/inet_connection_sock.h
include/net/sock.h
net/ipv4/inet_connection_sock.c
net/ipv4/tcp_timer.c
net/mptcp/protocol.c
tools/testing/selftests/bpf/progs/bpf_iter_tcp4.c
tools/testing/selftests/bpf/progs/bpf_iter_tcp6.c

index 4f65de2def8c9ccef1108f8f3a3de1d8c12b8497..cc2000f55c29879a12c0e4d238242b01cee18091 100644 (file)
@@ -12,7 +12,6 @@ struct inet_sock                    icsk_inet              read_mostly         r
 struct request_sock_queue           icsk_accept_queue
 struct inet_bind_bucket             icsk_bind_hash         read_mostly                             tcp_set_state
 struct inet_bind2_bucket            icsk_bind2_hash        read_mostly                             tcp_set_state,inet_put_port
-struct timer_list                   icsk_retransmit_timer  read_write                              inet_csk_reset_xmit_timer,tcp_connect
 struct timer_list                   icsk_delack_timer      read_mostly                             inet_csk_reset_xmit_timer,tcp_connect
 struct timer_list                   icsk_keepalive_timer
 u32                                 icsk_rto               read_write                              tcp_cwnd_validate,tcp_schedule_loss_probe,tcp_connect_init,tcp_connect,tcp_write_xmit,tcp_push_one
index e0d90b996348d895256191a5f10275d8f3f3a69a..ecb362025c4e5183ec78aef4b45c249da87c19ea 100644 (file)
@@ -56,7 +56,6 @@ struct inet_connection_sock_af_ops {
  * @icsk_accept_queue:    FIFO of established children
  * @icsk_bind_hash:       Bind node
  * @icsk_bind2_hash:      Bind node in the bhash2 table
- * @icsk_retransmit_timer: Resend (no ack)
  * @icsk_delack_timer:     Delayed ACK timer
  * @icsk_keepalive_timer:  Keepalive timer
  * @mptcp_tout_timer: mptcp timer
@@ -84,7 +83,6 @@ struct inet_connection_sock {
        struct request_sock_queue icsk_accept_queue;
        struct inet_bind_bucket   *icsk_bind_hash;
        struct inet_bind2_bucket  *icsk_bind2_hash;
-       struct timer_list         icsk_retransmit_timer;
        struct timer_list         icsk_delack_timer;
        union {
                struct timer_list icsk_keepalive_timer;
@@ -193,7 +191,7 @@ static inline void inet_csk_delack_init(struct sock *sk)
 
 static inline unsigned long tcp_timeout_expires(const struct sock *sk)
 {
-       return READ_ONCE(inet_csk(sk)->icsk_retransmit_timer.expires);
+       return READ_ONCE(sk->tcp_retransmit_timer.expires);
 }
 
 static inline unsigned long
@@ -209,7 +207,7 @@ static inline void inet_csk_clear_xmit_timer(struct sock *sk, const int what)
        if (what == ICSK_TIME_RETRANS || what == ICSK_TIME_PROBE0) {
                smp_store_release(&icsk->icsk_pending, 0);
 #ifdef INET_CSK_CLEAR_TIMERS
-               sk_stop_timer(sk, &icsk->icsk_retransmit_timer);
+               sk_stop_timer(sk, &sk->tcp_retransmit_timer);
 #endif
        } else if (what == ICSK_TIME_DACK) {
                smp_store_release(&icsk->icsk_ack.pending, 0);
@@ -241,7 +239,7 @@ static inline void inet_csk_reset_xmit_timer(struct sock *sk, const int what,
        if (what == ICSK_TIME_RETRANS || what == ICSK_TIME_PROBE0 ||
            what == ICSK_TIME_LOSS_PROBE || what == ICSK_TIME_REO_TIMEOUT) {
                smp_store_release(&icsk->icsk_pending, what);
-               sk_reset_timer(sk, &icsk->icsk_retransmit_timer, when);
+               sk_reset_timer(sk, &sk->tcp_retransmit_timer, when);
        } else if (what == ICSK_TIME_DACK) {
                smp_store_release(&icsk->icsk_ack.pending,
                                  icsk->icsk_ack.pending | ICSK_ACK_TIMER);
index a89aa97151f54b19bf1d0742a93ca1b10c8fd830..02253c6a578b6c4ac6a34c4a4303b3bbbdf045b7 100644 (file)
@@ -305,6 +305,8 @@ struct sk_filter;
   *    @sk_txrehash: enable TX hash rethink
   *    @sk_filter: socket filtering instructions
   *    @sk_timer: sock cleanup timer
+  *    @tcp_retransmit_timer: tcp retransmit timer
+  *    @mptcp_retransmit_timer: mptcp retransmit timer
   *    @sk_stamp: time stamp of last packet received
   *    @sk_stamp_seq: lock for accessing sk_stamp on 32 bit architectures only
   *    @sk_tsflags: SO_TIMESTAMPING flags
@@ -482,8 +484,11 @@ struct sock {
        };
        struct sk_buff_head     sk_write_queue;
        struct page_frag        sk_frag;
-       struct timer_list       sk_timer;
-
+       union {
+               struct timer_list       sk_timer;
+               struct timer_list       tcp_retransmit_timer;
+               struct timer_list       mptcp_retransmit_timer;
+       };
        unsigned long           sk_pacing_rate; /* bytes per second */
        atomic_t                sk_zckey;
        atomic_t                sk_tskey;
index 4fc09f9bf25d59e8155107eba391f5c566f290a0..97d57c52b9ad953d7ec1ad679237b5d122f47470 100644 (file)
@@ -737,7 +737,7 @@ void inet_csk_init_xmit_timers(struct sock *sk,
 {
        struct inet_connection_sock *icsk = inet_csk(sk);
 
-       timer_setup(&icsk->icsk_retransmit_timer, retransmit_handler, 0);
+       timer_setup(&sk->tcp_retransmit_timer, retransmit_handler, 0);
        timer_setup(&icsk->icsk_delack_timer, delack_handler, 0);
        timer_setup(&icsk->icsk_keepalive_timer, keepalive_handler, 0);
        icsk->icsk_pending = icsk->icsk_ack.pending = 0;
@@ -750,7 +750,7 @@ void inet_csk_clear_xmit_timers(struct sock *sk)
        smp_store_release(&icsk->icsk_pending, 0);
        smp_store_release(&icsk->icsk_ack.pending, 0);
 
-       sk_stop_timer(sk, &icsk->icsk_retransmit_timer);
+       sk_stop_timer(sk, &sk->tcp_retransmit_timer);
        sk_stop_timer(sk, &icsk->icsk_delack_timer);
        sk_stop_timer(sk, &icsk->icsk_keepalive_timer);
 }
@@ -765,7 +765,7 @@ void inet_csk_clear_xmit_timers_sync(struct sock *sk)
        smp_store_release(&icsk->icsk_pending, 0);
        smp_store_release(&icsk->icsk_ack.pending, 0);
 
-       sk_stop_timer_sync(sk, &icsk->icsk_retransmit_timer);
+       sk_stop_timer_sync(sk, &sk->tcp_retransmit_timer);
        sk_stop_timer_sync(sk, &icsk->icsk_delack_timer);
        sk_stop_timer_sync(sk, &icsk->icsk_keepalive_timer);
 }
index d2678dfd811806840cb332d47750dd771b20d6af..160080c9021d0717605520af3f1a47d071e7bf4d 100644 (file)
@@ -698,7 +698,7 @@ void tcp_write_timer_handler(struct sock *sk)
                return;
 
        if (time_after(tcp_timeout_expires(sk), jiffies)) {
-               sk_reset_timer(sk, &icsk->icsk_retransmit_timer,
+               sk_reset_timer(sk, &sk->tcp_retransmit_timer,
                               tcp_timeout_expires(sk));
                return;
        }
@@ -725,12 +725,10 @@ void tcp_write_timer_handler(struct sock *sk)
 
 static void tcp_write_timer(struct timer_list *t)
 {
-       struct inet_connection_sock *icsk =
-                       timer_container_of(icsk, t, icsk_retransmit_timer);
-       struct sock *sk = &icsk->icsk_inet.sk;
+       struct sock *sk = timer_container_of(sk, t, tcp_retransmit_timer);
 
        /* Avoid locking the socket when there is no pending event. */
-       if (!smp_load_acquire(&icsk->icsk_pending))
+       if (!smp_load_acquire(&inet_csk(sk)->icsk_pending))
                goto out;
 
        bh_lock_sock(sk);
index 89a5f63921e6afc60e9c49ea49f2fd7c8331d377..bb7d634cf31258673730c4de902f97b90db866ee 100644 (file)
@@ -411,9 +411,7 @@ static bool __mptcp_move_skb(struct sock *sk, struct sk_buff *skb)
 
 static void mptcp_stop_rtx_timer(struct sock *sk)
 {
-       struct inet_connection_sock *icsk = inet_csk(sk);
-
-       sk_stop_timer(sk, &icsk->icsk_retransmit_timer);
+       sk_stop_timer(sk, &sk->mptcp_retransmit_timer);
        mptcp_sk(sk)->timer_ival = 0;
 }
 
@@ -954,12 +952,11 @@ static void __mptcp_flush_join_list(struct sock *sk, struct list_head *join_list
 
 static bool mptcp_rtx_timer_pending(struct sock *sk)
 {
-       return timer_pending(&inet_csk(sk)->icsk_retransmit_timer);
+       return timer_pending(&sk->mptcp_retransmit_timer);
 }
 
 static void mptcp_reset_rtx_timer(struct sock *sk)
 {
-       struct inet_connection_sock *icsk = inet_csk(sk);
        unsigned long tout;
 
        /* prevent rescheduling on close */
@@ -967,7 +964,7 @@ static void mptcp_reset_rtx_timer(struct sock *sk)
                return;
 
        tout = mptcp_sk(sk)->timer_ival;
-       sk_reset_timer(sk, &icsk->icsk_retransmit_timer, jiffies + tout);
+       sk_reset_timer(sk, &sk->mptcp_retransmit_timer, jiffies + tout);
 }
 
 bool mptcp_schedule_work(struct sock *sk)
@@ -2354,9 +2351,7 @@ out_err:
 
 static void mptcp_retransmit_timer(struct timer_list *t)
 {
-       struct inet_connection_sock *icsk = timer_container_of(icsk, t,
-                                                              icsk_retransmit_timer);
-       struct sock *sk = &icsk->icsk_inet.sk;
+       struct sock *sk = timer_container_of(sk, t, mptcp_retransmit_timer);
        struct mptcp_sock *msk = mptcp_sk(sk);
 
        bh_lock_sock(sk);
@@ -2975,7 +2970,7 @@ static void __mptcp_init_sock(struct sock *sk)
        spin_lock_init(&msk->fallback_lock);
 
        /* re-use the csk retrans timer for MPTCP-level retrans */
-       timer_setup(&msk->sk.icsk_retransmit_timer, mptcp_retransmit_timer, 0);
+       timer_setup(&sk->mptcp_retransmit_timer, mptcp_retransmit_timer, 0);
        timer_setup(&msk->sk.mptcp_tout_timer, mptcp_tout_timer, 0);
 }
 
index 685811326a04126f411da2199cbb5dba576cdde7..b1e509b231cd97dcc863db84ffa9bfa5897ca4ce 100644 (file)
@@ -99,10 +99,10 @@ static int dump_tcp_sock(struct seq_file *seq, struct tcp_sock *tp,
            icsk->icsk_pending == ICSK_TIME_REO_TIMEOUT ||
            icsk->icsk_pending == ICSK_TIME_LOSS_PROBE) {
                timer_active = 1;
-               timer_expires = icsk->icsk_retransmit_timer.expires;
+               timer_expires = sp->tcp_retransmit_timer.expires;
        } else if (icsk->icsk_pending == ICSK_TIME_PROBE0) {
                timer_active = 4;
-               timer_expires = icsk->icsk_retransmit_timer.expires;
+               timer_expires = sp->tcp_retransmit_timer.expires;
        } else if (timer_pending(&icsk->icsk_keepalive_timer)) {
                timer_active = 2;
                timer_expires = icsk->icsk_keepalive_timer.expires;
index 0f4a927127517ce3d156c718c3ddece0407c3137..dbc7166aee91f5403d3e275522cb652f104ac9c5 100644 (file)
@@ -99,10 +99,10 @@ static int dump_tcp6_sock(struct seq_file *seq, struct tcp6_sock *tp,
            icsk->icsk_pending == ICSK_TIME_REO_TIMEOUT ||
            icsk->icsk_pending == ICSK_TIME_LOSS_PROBE) {
                timer_active = 1;
-               timer_expires = icsk->icsk_retransmit_timer.expires;
+               timer_expires = sp->tcp_retransmit_timer.expires;
        } else if (icsk->icsk_pending == ICSK_TIME_PROBE0) {
                timer_active = 4;
-               timer_expires = icsk->icsk_retransmit_timer.expires;
+               timer_expires = sp->tcp_retransmit_timer.expires;
        } else if (timer_pending(&icsk->icsk_keepalive_timer)) {
                timer_active = 2;
                timer_expires = icsk->icsk_keepalive_timer.expires;