FAILED: patch "[PATCH] mptcp: prevent race between disconnect() and rtx" failed to apply to 6.1-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 6.1-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.1.y
git checkout FETCH_HEAD
git cherry-pick -x 85c580b0d8590520ae00a15c29e9fb9c99427a3e
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026091622-thieving-raffle-4915@gregkh' --subject-prefix 'PATCH 6.1.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 85c580b0d8590520ae00a15c29e9fb9c99427a3e Mon Sep 17 00:00:00 2001
From: Paolo Abeni <[email protected]>
Date: Tue, 8 Sep 2026 16:07:11 +0200
Subject: [PATCH] mptcp: prevent race between disconnect() and rtx
Sashiko noted that the two event can race, leading to inconsistent status. Prevent the race using the synchronous timer stop operation.
net/mptcp/protocol.c +8 -2
@@ -3588,6 +3588,7 @@ static void mptcp_destroy_common(struct mptcp_sock *msk)static int mptcp_disconnect (struct sock *sk,int flags) { +struct inet_connection_sock *icsk =inet_csk (sk);struct mptcp_sock *msk =mptcp_sk (sk);/* We are on the fastopen error path. We can't call straight into the
@@ -3600,8 +3601,13 @@ static int mptcp_disconnect(struct sock *sk, int flags)mptcp_check_listen_stop (sk);mptcp_set_state (sk,TCP_CLOSE ); -mptcp_stop_rtx_timer (sk); -mptcp_stop_tout_timer (sk); +/* The later subflow close can not kick again the tout timer, +* as the msk is already in closed status. +*/ + msk->timer_ival = icsk->icsk_rto_min; +sk_stop_timer_sync (sk, &sk->mptcp_retransmit_timer); + icsk->icsk_mtup.probe_timestamp =0 ; +sk_stop_timer_sync (sk, &icsk->mptcp_tout_timer);mptcp_pm_connection_closed (msk);
Sasha Levin
maintainerPATCH 1/2 tcp: introduce icsk->icsk_keepalive_timer
From: Eric Dumazet <[email protected]>
[ Upstream commit 08dfe370239e53494453cee1e2ded2cdaa1efd12 ]
sk->sk_timer has been used for TCP keepalives.
Keepalive timers are not in fast path, we want to use sk->sk_timer storage for retransmit timers, for better cache locality.
Create icsk->icsk_keepalive_timer and change keepalive code to no longer use sk->sk_timer.
Added space is reclaimed in the following patch.
This includes changes to MPTCP, which was also using sk_timer.
Alias icsk->mptcp_tout_timer and icsk->icsk_keepalive_timer for inet_sk_diag_fill() sake.
Backport to 6.1 as a dependency of 85c580b0d859 ("mptcp: prevent race between disconnect() and rtx"):
Keep icsk_timeout and the existing TCP retransmit timer. Update the existing inet_csk keepalive helpers in inet_connection_sock.c instead of introducing the newer TCP helpers, and use from_timer() in the callbacks. Adjust the DCCP callback, since DCCP still shares the inet_csk timer setup in this branch. Omit the absent net_cachelines document.
Also alias sk_timer as mptcp_retransmit_timer and move all MPTCP retransmit timer users there. The target directly stops this timer and the new mptcp_tout_timer, so both names must identify the timers actually in use. Initialize the MPTCP icsk_rto_min to this branch's TCP_RTO_MIN so the target restores a valid retransmit interval during disconnect. No functions are added.
[ sashal: Reduced backport -- upstream 08dfe370239e5 touches 11 file(s), this
backport carries 12. Not backported here:
Documentation/networking/net_cachelines/inet_connection_sock.rst This note is generated from the file lists only; see the resolution record for the reasoning. ]
Stable-dep-of: 85c580b0d859 ("mptcp: prevent race between disconnect() and rtx")
--- include/net/inet_connection_sock.h | 11 ++++++-- include/net/sock.h | 6 +++- net/dccp/timer.c | 4 ++- net/ipv4/inet_connection_sock.c | 10 +++---- net/ipv4/inet_diag.c | 4 +-- net/ipv4/tcp_ipv4.c | 4 +-- net/ipv4/tcp_timer.c | 5 ++-- net/ipv6/tcp_ipv6.c | 4 +-- net/mptcp/protocol.c | 28 +++++++++---------- net/mptcp/protocol.h | 2 +- .../selftests/bpf/progs/bpf_iter_tcp4.c | 4 +-- .../selftests/bpf/progs/bpf_iter_tcp6.c | 4 +-- 12 files changed, 49 insertions(+), 37 deletions(-)
include/net/inet_connection_sock.h +9 -2
@@ -63,6 +63,9 @@ struct inet_connection_sock_af_ops {* @icsk_bind2_hash: Bind node in the bhash2 table * @icsk_timeout: Timeout * @icsk_retransmit_timer: Resend (no ack) +* @icsk_delack_timer: Delayed ACK timer +* @icsk_keepalive_timer: Keepalive timer +* @mptcp_tout_timer: MPTCP timeout timer * @icsk_rto: Retransmit timeout * @icsk_pmtu_cookie Last pmtu seen by socket * @icsk_ca_ops Pluggable congestion control hook
@@ -89,8 +92,12 @@ struct inet_connection_sock {struct inet_bind_bucket *icsk_bind_hash;struct inet_bind2_bucket *icsk_bind2_hash;unsigned long icsk_timeout; -struct timer_list icsk_retransmit_timer; -struct timer_list icsk_delack_timer; +struct timer_list icsk_retransmit_timer; +struct timer_list icsk_delack_timer; +union { +struct timer_list icsk_keepalive_timer; +struct timer_list mptcp_tout_timer; + };__u32 icsk_rto;__u32 icsk_rto_min;__u32 icsk_delack_max;
include/net/sock.h +5 -1
@@ -315,6 +315,7 @@ struct sk_filter;* @sk_txrehash: enable TX hash rethink * @sk_filter: socket filtering instructions * @sk_timer: sock cleanup 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
@@ -459,7 +460,10 @@ struct sock {__u32 sk_dst_pending_confirm;u32 sk_pacing_status;/* see enum sk_pacing */ long sk_sndtimeo; -struct timer_list sk_timer; +union { +struct timer_list sk_timer; +struct timer_list mptcp_retransmit_timer; + };__u32 sk_priority;__u32 sk_mark;unsigned long sk_pacing_rate;/* bytes per second */
net/dccp/timer.c +3 -1
@@ -160,7 +160,9 @@ static void dccp_write_timer(struct timer_list *t)static void dccp_keepalive_timer (struct timer_list *t) { -struct sock *sk =from_timer (sk, t, sk_timer); +struct inet_connection_sock *icsk = +from_timer (icsk, t, icsk_keepalive_timer); +struct sock *sk = &icsk->icsk_inet.sk;pr_err ("dccp should not use a keepalive timer !\n" );sock_put (sk);
net/ipv4/inet_connection_sock.c +5 -5
@@ -749,7 +749,7 @@ void inet_csk_init_xmit_timers(struct sock *sk,timer_setup (&icsk->icsk_retransmit_timer, retransmit_handler,0 );timer_setup (&icsk->icsk_delack_timer, delack_handler,0 ); -timer_setup (&sk->sk_timer, keepalive_handler,0 ); +timer_setup (&icsk->icsk_keepalive_timer, keepalive_handler,0 ); icsk->icsk_pending = icsk->icsk_ack.pending =0 ; }EXPORT_SYMBOL (inet_csk_init_xmit_timers);
@@ -762,7 +762,7 @@ void inet_csk_clear_xmit_timers(struct sock *sk)sk_stop_timer (sk, &icsk->icsk_retransmit_timer);sk_stop_timer (sk, &icsk->icsk_delack_timer); -sk_stop_timer (sk, &sk->sk_timer); +sk_stop_timer (sk, &icsk->icsk_keepalive_timer); }EXPORT_SYMBOL (inet_csk_clear_xmit_timers);
@@ -777,18 +777,18 @@ void inet_csk_clear_xmit_timers_sync(struct sock *sk)sk_stop_timer_sync (sk, &icsk->icsk_retransmit_timer);sk_stop_timer_sync (sk, &icsk->icsk_delack_timer); -sk_stop_timer_sync (sk, &sk->sk_timer); +sk_stop_timer_sync (sk, &icsk->icsk_keepalive_timer); }void inet_csk_delete_keepalive_timer (struct sock *sk) { -sk_stop_timer (sk, &sk->sk_timer); +sk_stop_timer (sk, &inet_csk (sk)->icsk_keepalive_timer); }EXPORT_SYMBOL (inet_csk_delete_keepalive_timer);void inet_csk_reset_keepalive_timer (struct sock *sk,unsigned long len) { -sk_reset_timer (sk, &sk->sk_timer, jiffies + len); +sk_reset_timer (sk, &inet_csk (sk)->icsk_keepalive_timer, jiffies + len); }EXPORT_SYMBOL (inet_csk_reset_keepalive_timer);
net/ipv4/inet_diag.c +2 -2
@@ -310,11 +310,11 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, r->idiag_retrans = icsk->icsk_probes_out; r->idiag_expires =jiffies_delta_to_msecs (icsk->icsk_timeout - jiffies); - }else if (timer_pending (&sk->sk_timer)) { + }else if (timer_pending (&icsk->icsk_keepalive_timer)) { r->idiag_timer =2 ; r->idiag_retrans = icsk->icsk_probes_out; r->idiag_expires = -jiffies_delta_to_msecs (sk->sk_timer.expires - jiffies); +jiffies_delta_to_msecs (icsk->icsk_keepalive_timer.expires - jiffies); }if ((ext & (1 << (INET_DIAG_INFO -1 ))) && handler->idiag_info_size) {
net/ipv4/tcp_ipv4.c +2 -2
@@ -2646,9 +2646,9 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i) }else if (icsk->icsk_pending ==ICSK_TIME_PROBE0 ) { timer_active =4 ; timer_expires = icsk->icsk_timeout; - }else if (timer_pending (&sk->sk_timer)) { + }else if (timer_pending (&icsk->icsk_keepalive_timer)) { timer_active =2 ; - timer_expires = sk->sk_timer.expires; + timer_expires = icsk->icsk_keepalive_timer.expires; }else { timer_active =0 ; timer_expires = jiffies;
net/ipv4/tcp_timer.c +3 -2
@@ -706,8 +706,9 @@ EXPORT_SYMBOL_GPL(tcp_set_keepalive);static void tcp_keepalive_timer (struct timer_list *t) { -struct sock *sk =from_timer (sk, t, sk_timer); -struct inet_connection_sock *icsk =inet_csk (sk); +struct inet_connection_sock *icsk = +from_timer (icsk, t, icsk_keepalive_timer); +struct sock *sk = &icsk->icsk_inet.sk;struct tcp_sock *tp =tcp_sk (sk);u32 elapsed;
net/ipv6/tcp_ipv6.c +2 -2
@@ -2000,9 +2000,9 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i) }else if (icsk->icsk_pending ==ICSK_TIME_PROBE0 ) { timer_active =4 ; timer_expires = icsk->icsk_timeout; - }else if (timer_pending (&sp->sk_timer)) { + }else if (timer_pending (&icsk->icsk_keepalive_timer)) { timer_active =2 ; - timer_expires = sp->sk_timer.expires; + timer_expires = icsk->icsk_keepalive_timer.expires; }else { timer_active =0 ; timer_expires = jiffies;
net/mptcp/protocol.c +13 -15
@@ -426,9 +426,7 @@ static bool __mptcp_move_skb(struct mptcp_sock *msk, struct sock *ssk,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 ; }
@@ -976,12 +974,11 @@ static void __mptcp_flush_join_list(struct sock *sk, struct list_head *join_liststatic 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 */
@@ -989,7 +986,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)
@@ -2347,9 +2344,7 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,static void mptcp_retransmit_timer (struct timer_list *t) { -struct inet_connection_sock *icsk =from_timer (icsk, t, - icsk_retransmit_timer); -struct sock *sk = &icsk->icsk_inet.sk; +struct sock *sk =from_timer (sk, t, mptcp_retransmit_timer);struct mptcp_sock *msk =mptcp_sk (sk);bh_lock_sock (sk);
@@ -2367,7 +2362,9 @@ static void mptcp_retransmit_timer(struct timer_list *t)static void mptcp_tout_timer (struct timer_list *t) { -struct sock *sk =from_timer (sk, t, sk_timer); +struct inet_connection_sock *icsk = +from_timer (icsk, t, mptcp_tout_timer); +struct sock *sk = &icsk->icsk_inet.sk;mptcp_schedule_work (sk);sock_put (sk);
@@ -2799,7 +2796,7 @@ void mptcp_reset_tout_timer(struct mptcp_sock *msk, unsigned long fail_tout)*/ timeout =inet_csk (sk)->icsk_mtup.probe_timestamp ? close_timeout : fail_tout; -sk_reset_timer (sk, &sk->sk_timer, timeout); +sk_reset_timer (sk, &inet_csk (sk)->mptcp_tout_timer, timeout); }static void mptcp_mp_fail_no_response (struct mptcp_sock *msk)
@@ -2917,6 +2914,8 @@ static int __mptcp_init_sock(struct sock *sk) msk->first_pending =NULL ; msk->rmem_fwd_alloc =0 ;WRITE_ONCE (msk->rmem_released,0 ); +/* MPTCP sockets do not go through tcp_init_sock(). */ +inet_csk (sk)->icsk_rto_min =TCP_RTO_MIN ; msk->timer_ival =TCP_RTO_MIN ;WRITE_ONCE (msk->first,NULL );
@@ -2929,9 +2928,8 @@ static int __mptcp_init_sock(struct sock *sk)mptcp_pm_data_init (msk);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->sk_timer, mptcp_tout_timer,0 ); +timer_setup (&sk->mptcp_retransmit_timer, mptcp_retransmit_timer,0 ); +timer_setup (&msk->sk.mptcp_tout_timer, mptcp_tout_timer,0 );return 0 ; }
@@ -3108,7 +3106,7 @@ static void __mptcp_destroy_sock(struct sock *sk)might_sleep ();mptcp_stop_rtx_timer (sk); -sk_stop_timer (sk, &sk->sk_timer); +sk_stop_timer (sk, &inet_csk (sk)->mptcp_tout_timer); msk->pm.status =0 ; sk->sk_prot->destroy (sk);
net/mptcp/protocol.h +1 -1
@@ -697,7 +697,7 @@ static inline void mptcp_stop_tout_timer(struct sock *sk)if (!inet_csk (sk)->icsk_mtup.probe_timestamp)return ; -sk_stop_timer (sk, &sk->sk_timer); +sk_stop_timer (sk, &inet_csk (sk)->mptcp_tout_timer);inet_csk (sk)->icsk_mtup.probe_timestamp =0 ; }
tools/testing/selftests/bpf/progs/bpf_iter_tcp4.c +2 -2
@@ -103,9 +103,9 @@ static int dump_tcp_sock(struct seq_file *seq, struct tcp_sock *tp, }else if (icsk->icsk_pending ==ICSK_TIME_PROBE0 ) { timer_active =4 ; timer_expires = icsk->icsk_timeout; - }else if (timer_pending (&sp->sk_timer)) { + }else if (timer_pending (&icsk->icsk_keepalive_timer)) { timer_active =2 ; - timer_expires = sp->sk_timer.expires; + timer_expires = icsk->icsk_keepalive_timer.expires; }else { timer_active =0 ; timer_expires =bpf_jiffies64 ();
tools/testing/selftests/bpf/progs/bpf_iter_tcp6.c +2 -2
@@ -103,9 +103,9 @@ static int dump_tcp6_sock(struct seq_file *seq, struct tcp6_sock *tp, }else if (icsk->icsk_pending ==ICSK_TIME_PROBE0 ) { timer_active =4 ; timer_expires = icsk->icsk_timeout; - }else if (timer_pending (&sp->sk_timer)) { + }else if (timer_pending (&icsk->icsk_keepalive_timer)) { timer_active =2 ; - timer_expires = sp->sk_timer.expires; + timer_expires = icsk->icsk_keepalive_timer.expires; }else { timer_active =0 ; timer_expires =bpf_jiffies64 ();
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/2 mptcp: prevent race between disconnect() and rtx
From: Paolo Abeni <[email protected]>
[ Upstream commit 85c580b0d8590520ae00a15c29e9fb9c99427a3e ]
Sashiko noted that the two event can race, leading to inconsistent status. Prevent the race using the synchronous timer stop operation.
--- net/mptcp/protocol.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
net/mptcp/protocol.c +8 -2
@@ -3267,6 +3267,7 @@ static void mptcp_copy_inaddrs(struct sock *msk, const struct sock *ssk)static int mptcp_disconnect (struct sock *sk,int flags) { +struct inet_connection_sock *icsk =inet_csk (sk);struct mptcp_sock *msk =mptcp_sk (sk);/* We are on the fastopen error path. We can't call straight into the
@@ -3279,8 +3280,13 @@ static int mptcp_disconnect(struct sock *sk, int flags)mptcp_check_listen_stop (sk);inet_sk_state_store (sk,TCP_CLOSE ); -mptcp_stop_rtx_timer (sk); -mptcp_stop_tout_timer (sk); +/* The later subflow close can not kick again the tout timer, +* as the msk is already in closed status. +*/ + msk->timer_ival = icsk->icsk_rto_min; +sk_stop_timer_sync (sk, &sk->mptcp_retransmit_timer); + icsk->icsk_mtup.probe_timestamp =0 ; +sk_stop_timer_sync (sk, &icsk->mptcp_tout_timer);if (mptcp_sk (sk)->token)mptcp_event (MPTCP_EVENT_CLOSED ,mptcp_sk (sk),NULL ,GFP_KERNEL );
Signature · 1 line
2.53.0
Matthieu Baerts
maintainerRe: [PATCH 6.1.y 2/2] mptcp: prevent race between disconnect() and rtx
Hi Sasha,
Quoted 3 lines · Sasha Levin
From: Paolo Abeni <[email protected]>
[ Upstream commit
85c580b0d8590520ae00a15c29e9fb9c99427a3e]
Thank you for the backport!
Quoted 28 lines
Sashiko noted that the two event can race, leading to inconsistent status. Prevent the race using the synchronous timer stop operation.
Fixes b29fcfb54cd7 ("mptcp: full disconnect implementation")Signed-off-by Paolo Abeni <[email protected]>Reviewed-by Matthieu Baerts (NGI0) <[email protected]>Signed-off-by Matthieu Baerts (NGI0) <[email protected]>Link https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-6-df1de70348b6@kernel.org open hereSigned-off-by Jakub Kicinski <[email protected]>Signed-off-by Sasha Levin <[email protected]>--- net/mptcp/protocol.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)net/mptcp/protocol.c +1
-0@@ -3267,6 +3267,7 @@ static void mptcp_copy_inaddrs(struct sock *msk, const struct sock *ssk)static int mptcp_disconnect (struct sock *sk,int flags) { +struct inet_connection_sock *icsk =inet_csk (sk);struct mptcp_sock *msk =mptcp_sk (sk);/* We are on the fastopen error path. We can't call straight into the
net/mptcp/protocol.c static int mptcp_disconnect(struct sock *sk, int flags) · line 3286
Quoted 9 lines
net/mptcp/protocol.c +4
-2@@ -3279,8 +3280,13 @@ static int mptcp_disconnect(struct sock *sk, int flags)mptcp_check_listen_stop (sk);inet_sk_state_store (sk,TCP_CLOSE ); -mptcp_stop_rtx_timer (sk); -mptcp_stop_tout_timer (sk); +/* The later subflow close can not kick again the tout timer, +* as the msk is already in closed status. +*/ + msk->timer_ival = icsk->icsk_rto_min;
Same here in this version, and also because commit ea4eb2adb0d3 ("mptcp:
honour configured min/max RTO in retransmit paths") is not in this version, this line should be adapted to:
msk->timer_ival = TCP_RTO_MIN;
net/mptcp/protocol.c static int mptcp_disconnect(struct sock *sk, int flags) · line 3292
Quoted 6 lines
net/mptcp/protocol.c +3
-0+sk_stop_timer_sync (sk, &sk->mptcp_retransmit_timer); + icsk->icsk_mtup.probe_timestamp =0 ; +sk_stop_timer_sync (sk, &icsk->mptcp_tout_timer);if (mptcp_sk (sk)->token)mptcp_event (MPTCP_EVENT_CLOSED ,mptcp_sk (sk),NULL ,GFP_KERNEL );
Cheers,
Matt
Signature · 1 line
Sponsored by the NGI0 Core fund.
Re: [PATCH 6.1.y 2/2] mptcp: prevent race between disconnect() and rtx
Quoted 5 lines
Same here in this version, and also because commit
ea4eb2adb0d3("mptcp:
honour configured min/max RTO in retransmit paths") is not in this version, this line should be adapted to:msk->timer_ival = TCP_RTO_MIN;
Queued the series for 6.1 with msk->timer_ival = TCP_RTO_MIN, thanks.
Signature · 2 lines
Thanks, Sasha