@@ -561,10 +561,9 @@ static bool mptcp_check_data_fin(struct sock *sk)
561
561
562
562
static void mptcp_dss_corruption (struct mptcp_sock * msk , struct sock * ssk )
563
563
{
564
- if (READ_ONCE ( msk -> allow_infinite_fallback )) {
564
+ if (mptcp_try_fallback ( ssk )) {
565
565
MPTCP_INC_STATS (sock_net (ssk ),
566
566
MPTCP_MIB_DSSCORRUPTIONFALLBACK );
567
- mptcp_do_fallback (ssk );
568
567
} else {
569
568
MPTCP_INC_STATS (sock_net (ssk ), MPTCP_MIB_DSSCORRUPTIONRESET );
570
569
mptcp_subflow_reset (ssk );
@@ -804,6 +803,14 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk)
804
803
if (sk -> sk_state != TCP_ESTABLISHED )
805
804
return false;
806
805
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
+
807
814
/* attach to msk socket only after we are sure we will deal with it
808
815
* at close time
809
816
*/
@@ -812,7 +819,6 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk)
812
819
813
820
mptcp_subflow_ctx (ssk )-> subflow_id = msk -> subflow_id ++ ;
814
821
mptcp_sockopt_sync_locked (msk , ssk );
815
- mptcp_subflow_joined (msk , ssk );
816
822
mptcp_stop_tout_timer (sk );
817
823
__mptcp_propagate_sndbuf (sk , ssk );
818
824
return true;
@@ -1137,10 +1143,14 @@ static void mptcp_update_infinite_map(struct mptcp_sock *msk,
1137
1143
mpext -> infinite_map = 1 ;
1138
1144
mpext -> data_len = 0 ;
1139
1145
1146
+ if (!mptcp_try_fallback (ssk )) {
1147
+ mptcp_subflow_reset (ssk );
1148
+ return ;
1149
+ }
1150
+
1140
1151
MPTCP_INC_STATS (sock_net (ssk ), MPTCP_MIB_INFINITEMAPTX );
1141
1152
mptcp_subflow_ctx (ssk )-> send_infinite_map = 0 ;
1142
1153
pr_fallback (msk );
1143
- mptcp_do_fallback (ssk );
1144
1154
}
1145
1155
1146
1156
#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)
2544
2554
2545
2555
static void __mptcp_retrans (struct sock * sk )
2546
2556
{
2557
+ struct mptcp_sendmsg_info info = { .data_lock_held = true, };
2547
2558
struct mptcp_sock * msk = mptcp_sk (sk );
2548
2559
struct mptcp_subflow_context * subflow ;
2549
- struct mptcp_sendmsg_info info = {};
2550
2560
struct mptcp_data_frag * dfrag ;
2551
2561
struct sock * ssk ;
2552
2562
int ret , err ;
@@ -2591,6 +2601,18 @@ static void __mptcp_retrans(struct sock *sk)
2591
2601
info .sent = 0 ;
2592
2602
info .limit = READ_ONCE (msk -> csum_enabled ) ? dfrag -> data_len :
2593
2603
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
+
2594
2616
while (info .sent < info .limit ) {
2595
2617
ret = mptcp_sendmsg_frag (sk , ssk , dfrag , & info );
2596
2618
if (ret <= 0 )
@@ -2606,6 +2628,7 @@ static void __mptcp_retrans(struct sock *sk)
2606
2628
info .size_goal );
2607
2629
WRITE_ONCE (msk -> allow_infinite_fallback , false);
2608
2630
}
2631
+ spin_unlock_bh (& msk -> fallback_lock );
2609
2632
2610
2633
release_sock (ssk );
2611
2634
}
@@ -2739,6 +2762,7 @@ static void __mptcp_init_sock(struct sock *sk)
2739
2762
msk -> last_ack_recv = tcp_jiffies32 ;
2740
2763
2741
2764
mptcp_pm_data_init (msk );
2765
+ spin_lock_init (& msk -> fallback_lock );
2742
2766
2743
2767
/* re-use the csk retrans timer for MPTCP-level retrans */
2744
2768
timer_setup (& msk -> sk .icsk_retransmit_timer , mptcp_retransmit_timer , 0 );
@@ -3525,7 +3549,13 @@ bool mptcp_finish_join(struct sock *ssk)
3525
3549
3526
3550
/* active subflow, already present inside the conn_list */
3527
3551
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
+ }
3528
3557
mptcp_subflow_joined (msk , ssk );
3558
+ spin_unlock_bh (& msk -> fallback_lock );
3529
3559
mptcp_propagate_sndbuf (parent , ssk );
3530
3560
return true;
3531
3561
}
0 commit comments