@@ -623,10 +623,9 @@ static bool mptcp_check_data_fin(struct sock *sk)
623623
624624static void mptcp_dss_corruption (struct mptcp_sock * msk , struct sock * ssk )
625625{
626- if (READ_ONCE ( msk -> allow_infinite_fallback )) {
626+ if (mptcp_try_fallback ( ssk )) {
627627 MPTCP_INC_STATS (sock_net (ssk ),
628628 MPTCP_MIB_DSSCORRUPTIONFALLBACK );
629- mptcp_do_fallback (ssk );
630629 } else {
631630 MPTCP_INC_STATS (sock_net (ssk ), MPTCP_MIB_DSSCORRUPTIONRESET );
632631 mptcp_subflow_reset (ssk );
@@ -889,6 +888,14 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk)
889888 if (sk -> sk_state != TCP_ESTABLISHED )
890889 return false;
891890
891+ spin_lock_bh (& msk -> fallback_lock );
892+ if (__mptcp_check_fallback (msk )) {
893+ spin_unlock_bh (& msk -> fallback_lock );
894+ return false;
895+ }
896+ mptcp_subflow_joined (msk , ssk );
897+ spin_unlock_bh (& msk -> fallback_lock );
898+
892899 /* attach to msk socket only after we are sure we will deal with it
893900 * at close time
894901 */
@@ -897,7 +904,6 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk)
897904
898905 mptcp_subflow_ctx (ssk )-> subflow_id = msk -> subflow_id ++ ;
899906 mptcp_sockopt_sync_locked (msk , ssk );
900- mptcp_subflow_joined (msk , ssk );
901907 mptcp_stop_tout_timer (sk );
902908 __mptcp_propagate_sndbuf (sk , ssk );
903909 return true;
@@ -1236,10 +1242,14 @@ static void mptcp_update_infinite_map(struct mptcp_sock *msk,
12361242 mpext -> infinite_map = 1 ;
12371243 mpext -> data_len = 0 ;
12381244
1245+ if (!mptcp_try_fallback (ssk )) {
1246+ mptcp_subflow_reset (ssk );
1247+ return ;
1248+ }
1249+
12391250 MPTCP_INC_STATS (sock_net (ssk ), MPTCP_MIB_INFINITEMAPTX );
12401251 mptcp_subflow_ctx (ssk )-> send_infinite_map = 0 ;
12411252 pr_fallback (msk );
1242- mptcp_do_fallback (ssk );
12431253}
12441254
12451255#define MPTCP_MAX_GSO_SIZE (GSO_LEGACY_MAX_SIZE - (MAX_TCP_HEADER + 1))
@@ -2643,9 +2653,9 @@ static void mptcp_check_fastclose(struct mptcp_sock *msk)
26432653
26442654static void __mptcp_retrans (struct sock * sk )
26452655{
2656+ struct mptcp_sendmsg_info info = { .data_lock_held = true, };
26462657 struct mptcp_sock * msk = mptcp_sk (sk );
26472658 struct mptcp_subflow_context * subflow ;
2648- struct mptcp_sendmsg_info info = {};
26492659 struct mptcp_data_frag * dfrag ;
26502660 struct sock * ssk ;
26512661 int ret , err ;
@@ -2690,6 +2700,18 @@ static void __mptcp_retrans(struct sock *sk)
26902700 info .sent = 0 ;
26912701 info .limit = READ_ONCE (msk -> csum_enabled ) ? dfrag -> data_len :
26922702 dfrag -> already_sent ;
2703+
2704+ /*
2705+ * make the whole retrans decision, xmit, disallow
2706+ * fallback atomic
2707+ */
2708+ spin_lock_bh (& msk -> fallback_lock );
2709+ if (__mptcp_check_fallback (msk )) {
2710+ spin_unlock_bh (& msk -> fallback_lock );
2711+ release_sock (ssk );
2712+ return ;
2713+ }
2714+
26932715 while (info .sent < info .limit ) {
26942716 ret = mptcp_sendmsg_frag (sk , ssk , dfrag , & info );
26952717 if (ret <= 0 )
@@ -2705,6 +2727,7 @@ static void __mptcp_retrans(struct sock *sk)
27052727 info .size_goal );
27062728 WRITE_ONCE (msk -> allow_infinite_fallback , false);
27072729 }
2730+ spin_unlock_bh (& msk -> fallback_lock );
27082731
27092732 release_sock (ssk );
27102733 }
@@ -2841,6 +2864,7 @@ static void __mptcp_init_sock(struct sock *sk)
28412864 msk -> last_ack_recv = tcp_jiffies32 ;
28422865
28432866 mptcp_pm_data_init (msk );
2867+ spin_lock_init (& msk -> fallback_lock );
28442868
28452869 /* re-use the csk retrans timer for MPTCP-level retrans */
28462870 timer_setup (& msk -> sk .icsk_retransmit_timer , mptcp_retransmit_timer , 0 );
@@ -3637,7 +3661,13 @@ bool mptcp_finish_join(struct sock *ssk)
36373661
36383662 /* active subflow, already present inside the conn_list */
36393663 if (!list_empty (& subflow -> node )) {
3664+ spin_lock_bh (& msk -> fallback_lock );
3665+ if (__mptcp_check_fallback (msk )) {
3666+ spin_unlock_bh (& msk -> fallback_lock );
3667+ return false;
3668+ }
36403669 mptcp_subflow_joined (msk , ssk );
3670+ spin_unlock_bh (& msk -> fallback_lock );
36413671 mptcp_propagate_sndbuf (parent , ssk );
36423672 return true;
36433673 }
0 commit comments