@@ -558,10 +558,9 @@ static bool mptcp_check_data_fin(struct sock *sk)
558558
559559static void mptcp_dss_corruption (struct mptcp_sock * msk , struct sock * ssk )
560560{
561- if (READ_ONCE ( msk -> allow_infinite_fallback )) {
561+ if (mptcp_try_fallback ( ssk )) {
562562 MPTCP_INC_STATS (sock_net (ssk ),
563563 MPTCP_MIB_DSSCORRUPTIONFALLBACK );
564- mptcp_do_fallback (ssk );
565564 } else {
566565 MPTCP_INC_STATS (sock_net (ssk ), MPTCP_MIB_DSSCORRUPTIONRESET );
567566 mptcp_subflow_reset (ssk );
@@ -801,6 +800,14 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk)
801800 if (sk -> sk_state != TCP_ESTABLISHED )
802801 return false;
803802
803+ spin_lock_bh (& msk -> fallback_lock );
804+ if (__mptcp_check_fallback (msk )) {
805+ spin_unlock_bh (& msk -> fallback_lock );
806+ return false;
807+ }
808+ mptcp_subflow_joined (msk , ssk );
809+ spin_unlock_bh (& msk -> fallback_lock );
810+
804811 /* attach to msk socket only after we are sure we will deal with it
805812 * at close time
806813 */
@@ -809,7 +816,6 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk)
809816
810817 mptcp_subflow_ctx (ssk )-> subflow_id = msk -> subflow_id ++ ;
811818 mptcp_sockopt_sync_locked (msk , ssk );
812- mptcp_subflow_joined (msk , ssk );
813819 mptcp_stop_tout_timer (sk );
814820 __mptcp_propagate_sndbuf (sk , ssk );
815821 return true;
@@ -1134,10 +1140,14 @@ static void mptcp_update_infinite_map(struct mptcp_sock *msk,
11341140 mpext -> infinite_map = 1 ;
11351141 mpext -> data_len = 0 ;
11361142
1143+ if (!mptcp_try_fallback (ssk )) {
1144+ mptcp_subflow_reset (ssk );
1145+ return ;
1146+ }
1147+
11371148 MPTCP_INC_STATS (sock_net (ssk ), MPTCP_MIB_INFINITEMAPTX );
11381149 mptcp_subflow_ctx (ssk )-> send_infinite_map = 0 ;
11391150 pr_fallback (msk );
1140- mptcp_do_fallback (ssk );
11411151}
11421152
11431153#define MPTCP_MAX_GSO_SIZE (GSO_LEGACY_MAX_SIZE - (MAX_TCP_HEADER + 1))
@@ -2541,9 +2551,9 @@ static void mptcp_check_fastclose(struct mptcp_sock *msk)
25412551
25422552static void __mptcp_retrans (struct sock * sk )
25432553{
2554+ struct mptcp_sendmsg_info info = { .data_lock_held = true, };
25442555 struct mptcp_sock * msk = mptcp_sk (sk );
25452556 struct mptcp_subflow_context * subflow ;
2546- struct mptcp_sendmsg_info info = {};
25472557 struct mptcp_data_frag * dfrag ;
25482558 struct sock * ssk ;
25492559 int ret , err ;
@@ -2588,6 +2598,18 @@ static void __mptcp_retrans(struct sock *sk)
25882598 info .sent = 0 ;
25892599 info .limit = READ_ONCE (msk -> csum_enabled ) ? dfrag -> data_len :
25902600 dfrag -> already_sent ;
2601+
2602+ /*
2603+ * make the whole retrans decision, xmit, disallow
2604+ * fallback atomic
2605+ */
2606+ spin_lock_bh (& msk -> fallback_lock );
2607+ if (__mptcp_check_fallback (msk )) {
2608+ spin_unlock_bh (& msk -> fallback_lock );
2609+ release_sock (ssk );
2610+ return ;
2611+ }
2612+
25912613 while (info .sent < info .limit ) {
25922614 ret = mptcp_sendmsg_frag (sk , ssk , dfrag , & info );
25932615 if (ret <= 0 )
@@ -2603,6 +2625,7 @@ static void __mptcp_retrans(struct sock *sk)
26032625 info .size_goal );
26042626 WRITE_ONCE (msk -> allow_infinite_fallback , false);
26052627 }
2628+ spin_unlock_bh (& msk -> fallback_lock );
26062629
26072630 release_sock (ssk );
26082631 }
@@ -2736,6 +2759,7 @@ static void __mptcp_init_sock(struct sock *sk)
27362759 msk -> last_ack_recv = tcp_jiffies32 ;
27372760
27382761 mptcp_pm_data_init (msk );
2762+ spin_lock_init (& msk -> fallback_lock );
27392763
27402764 /* re-use the csk retrans timer for MPTCP-level retrans */
27412765 timer_setup (& msk -> sk .icsk_retransmit_timer , mptcp_retransmit_timer , 0 );
@@ -3522,7 +3546,13 @@ bool mptcp_finish_join(struct sock *ssk)
35223546
35233547 /* active subflow, already present inside the conn_list */
35243548 if (!list_empty (& subflow -> node )) {
3549+ spin_lock_bh (& msk -> fallback_lock );
3550+ if (__mptcp_check_fallback (msk )) {
3551+ spin_unlock_bh (& msk -> fallback_lock );
3552+ return false;
3553+ }
35253554 mptcp_subflow_joined (msk , ssk );
3555+ spin_unlock_bh (& msk -> fallback_lock );
35263556 mptcp_propagate_sndbuf (parent , ssk );
35273557 return true;
35283558 }
0 commit comments