@@ -561,10 +561,9 @@ static bool mptcp_check_data_fin(struct sock *sk)
561561
562562static void mptcp_dss_corruption (struct mptcp_sock * msk , struct sock * ssk )
563563{
564- if (READ_ONCE ( msk -> allow_infinite_fallback )) {
564+ if (mptcp_try_fallback ( ssk )) {
565565 MPTCP_INC_STATS (sock_net (ssk ),
566566 MPTCP_MIB_DSSCORRUPTIONFALLBACK );
567- mptcp_do_fallback (ssk );
568567 } else {
569568 MPTCP_INC_STATS (sock_net (ssk ), MPTCP_MIB_DSSCORRUPTIONRESET );
570569 mptcp_subflow_reset (ssk );
@@ -804,6 +803,14 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk)
804803 if (sk -> sk_state != TCP_ESTABLISHED )
805804 return false;
806805
806+ spin_lock_bh (& msk -> fallback_lock );
807+ if (__mptcp_check_fallback (msk )) {
808+ spin_unlock_bh (& msk -> fallback_lock );
809+ return false;
810+ }
811+ mptcp_subflow_joined (msk , ssk );
812+ spin_unlock_bh (& msk -> fallback_lock );
813+
807814 /* attach to msk socket only after we are sure we will deal with it
808815 * at close time
809816 */
@@ -812,7 +819,6 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk)
812819
813820 mptcp_subflow_ctx (ssk )-> subflow_id = msk -> subflow_id ++ ;
814821 mptcp_sockopt_sync_locked (msk , ssk );
815- mptcp_subflow_joined (msk , ssk );
816822 mptcp_stop_tout_timer (sk );
817823 __mptcp_propagate_sndbuf (sk , ssk );
818824 return true;
@@ -1137,10 +1143,14 @@ static void mptcp_update_infinite_map(struct mptcp_sock *msk,
11371143 mpext -> infinite_map = 1 ;
11381144 mpext -> data_len = 0 ;
11391145
1146+ if (!mptcp_try_fallback (ssk )) {
1147+ mptcp_subflow_reset (ssk );
1148+ return ;
1149+ }
1150+
11401151 MPTCP_INC_STATS (sock_net (ssk ), MPTCP_MIB_INFINITEMAPTX );
11411152 mptcp_subflow_ctx (ssk )-> send_infinite_map = 0 ;
11421153 pr_fallback (msk );
1143- mptcp_do_fallback (ssk );
11441154}
11451155
11461156#define MPTCP_MAX_GSO_SIZE (GSO_LEGACY_MAX_SIZE - (MAX_TCP_HEADER + 1))
@@ -2544,9 +2554,9 @@ static void mptcp_check_fastclose(struct mptcp_sock *msk)
25442554
25452555static void __mptcp_retrans (struct sock * sk )
25462556{
2557+ struct mptcp_sendmsg_info info = { .data_lock_held = true, };
25472558 struct mptcp_sock * msk = mptcp_sk (sk );
25482559 struct mptcp_subflow_context * subflow ;
2549- struct mptcp_sendmsg_info info = {};
25502560 struct mptcp_data_frag * dfrag ;
25512561 struct sock * ssk ;
25522562 int ret , err ;
@@ -2591,6 +2601,18 @@ static void __mptcp_retrans(struct sock *sk)
25912601 info .sent = 0 ;
25922602 info .limit = READ_ONCE (msk -> csum_enabled ) ? dfrag -> data_len :
25932603 dfrag -> already_sent ;
2604+
2605+ /*
2606+ * make the whole retrans decision, xmit, disallow
2607+ * fallback atomic
2608+ */
2609+ spin_lock_bh (& msk -> fallback_lock );
2610+ if (__mptcp_check_fallback (msk )) {
2611+ spin_unlock_bh (& msk -> fallback_lock );
2612+ release_sock (ssk );
2613+ return ;
2614+ }
2615+
25942616 while (info .sent < info .limit ) {
25952617 ret = mptcp_sendmsg_frag (sk , ssk , dfrag , & info );
25962618 if (ret <= 0 )
@@ -2606,6 +2628,7 @@ static void __mptcp_retrans(struct sock *sk)
26062628 info .size_goal );
26072629 WRITE_ONCE (msk -> allow_infinite_fallback , false);
26082630 }
2631+ spin_unlock_bh (& msk -> fallback_lock );
26092632
26102633 release_sock (ssk );
26112634 }
@@ -2739,6 +2762,7 @@ static void __mptcp_init_sock(struct sock *sk)
27392762 msk -> last_ack_recv = tcp_jiffies32 ;
27402763
27412764 mptcp_pm_data_init (msk );
2765+ spin_lock_init (& msk -> fallback_lock );
27422766
27432767 /* re-use the csk retrans timer for MPTCP-level retrans */
27442768 timer_setup (& msk -> sk .icsk_retransmit_timer , mptcp_retransmit_timer , 0 );
@@ -3525,7 +3549,13 @@ bool mptcp_finish_join(struct sock *ssk)
35253549
35263550 /* active subflow, already present inside the conn_list */
35273551 if (!list_empty (& subflow -> node )) {
3552+ spin_lock_bh (& msk -> fallback_lock );
3553+ if (__mptcp_check_fallback (msk )) {
3554+ spin_unlock_bh (& msk -> fallback_lock );
3555+ return false;
3556+ }
35283557 mptcp_subflow_joined (msk , ssk );
3558+ spin_unlock_bh (& msk -> fallback_lock );
35293559 mptcp_propagate_sndbuf (parent , ssk );
35303560 return true;
35313561 }
0 commit comments