@@ -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 );
@@ -887,6 +886,14 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk)
887886 if (sk -> sk_state != TCP_ESTABLISHED )
888887 return false;
889888
889+ spin_lock_bh (& msk -> fallback_lock );
890+ if (__mptcp_check_fallback (msk )) {
891+ spin_unlock_bh (& msk -> fallback_lock );
892+ return false;
893+ }
894+ mptcp_subflow_joined (msk , ssk );
895+ spin_unlock_bh (& msk -> fallback_lock );
896+
890897 /* attach to msk socket only after we are sure we will deal with it
891898 * at close time
892899 */
@@ -895,7 +902,6 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk)
895902
896903 mptcp_subflow_ctx (ssk )-> subflow_id = msk -> subflow_id ++ ;
897904 mptcp_sockopt_sync_locked (msk , ssk );
898- mptcp_subflow_joined (msk , ssk );
899905 mptcp_stop_tout_timer (sk );
900906 __mptcp_propagate_sndbuf (sk , ssk );
901907 return true;
@@ -1231,10 +1237,14 @@ static void mptcp_update_infinite_map(struct mptcp_sock *msk,
12311237 mpext -> infinite_map = 1 ;
12321238 mpext -> data_len = 0 ;
12331239
1240+ if (!mptcp_try_fallback (ssk )) {
1241+ mptcp_subflow_reset (ssk );
1242+ return ;
1243+ }
1244+
12341245 MPTCP_INC_STATS (sock_net (ssk ), MPTCP_MIB_INFINITEMAPTX );
12351246 mptcp_subflow_ctx (ssk )-> send_infinite_map = 0 ;
12361247 pr_fallback (msk );
1237- mptcp_do_fallback (ssk );
12381248}
12391249
12401250#define MPTCP_MAX_GSO_SIZE (GSO_LEGACY_MAX_SIZE - (MAX_TCP_HEADER + 1))
@@ -2606,9 +2616,9 @@ static void mptcp_check_fastclose(struct mptcp_sock *msk)
26062616
26072617static void __mptcp_retrans (struct sock * sk )
26082618{
2619+ struct mptcp_sendmsg_info info = { .data_lock_held = true, };
26092620 struct mptcp_sock * msk = mptcp_sk (sk );
26102621 struct mptcp_subflow_context * subflow ;
2611- struct mptcp_sendmsg_info info = {};
26122622 struct mptcp_data_frag * dfrag ;
26132623 struct sock * ssk ;
26142624 int ret , err ;
@@ -2653,6 +2663,18 @@ static void __mptcp_retrans(struct sock *sk)
26532663 info .sent = 0 ;
26542664 info .limit = READ_ONCE (msk -> csum_enabled ) ? dfrag -> data_len :
26552665 dfrag -> already_sent ;
2666+
2667+ /*
2668+ * make the whole retrans decision, xmit, disallow
2669+ * fallback atomic
2670+ */
2671+ spin_lock_bh (& msk -> fallback_lock );
2672+ if (__mptcp_check_fallback (msk )) {
2673+ spin_unlock_bh (& msk -> fallback_lock );
2674+ release_sock (ssk );
2675+ return ;
2676+ }
2677+
26562678 while (info .sent < info .limit ) {
26572679 ret = mptcp_sendmsg_frag (sk , ssk , dfrag , & info );
26582680 if (ret <= 0 )
@@ -2668,6 +2690,7 @@ static void __mptcp_retrans(struct sock *sk)
26682690 info .size_goal );
26692691 WRITE_ONCE (msk -> allow_infinite_fallback , false);
26702692 }
2693+ spin_unlock_bh (& msk -> fallback_lock );
26712694
26722695 release_sock (ssk );
26732696 }
@@ -2801,6 +2824,7 @@ static void __mptcp_init_sock(struct sock *sk)
28012824 msk -> subflow_id = 1 ;
28022825
28032826 mptcp_pm_data_init (msk );
2827+ spin_lock_init (& msk -> fallback_lock );
28042828
28052829 /* re-use the csk retrans timer for MPTCP-level retrans */
28062830 timer_setup (& msk -> sk .icsk_retransmit_timer , mptcp_retransmit_timer , 0 );
@@ -3599,7 +3623,13 @@ bool mptcp_finish_join(struct sock *ssk)
35993623
36003624 /* active subflow, already present inside the conn_list */
36013625 if (!list_empty (& subflow -> node )) {
3626+ spin_lock_bh (& msk -> fallback_lock );
3627+ if (__mptcp_check_fallback (msk )) {
3628+ spin_unlock_bh (& msk -> fallback_lock );
3629+ return false;
3630+ }
36023631 mptcp_subflow_joined (msk , ssk );
3632+ spin_unlock_bh (& msk -> fallback_lock );
36033633 mptcp_propagate_sndbuf (parent , ssk );
36043634 return true;
36053635 }
@@ -3712,7 +3742,7 @@ static void mptcp_subflow_early_fallback(struct mptcp_sock *msk,
37123742 struct mptcp_subflow_context * subflow )
37133743{
37143744 subflow -> request_mptcp = 0 ;
3715- __mptcp_do_fallback ( msk );
3745+ WARN_ON_ONCE (! __mptcp_try_fallback ( msk ) );
37163746}
37173747
37183748static int mptcp_connect (struct sock * sk , struct sockaddr * uaddr , int addr_len )
0 commit comments