Skip to content

Commit a0e59c4

Browse files
YANGANGintel-lab-lkp
authored andcommitted
mptcp: Add data race when accessing the fully_established of subflow
We introduce the same handling for potential data races with the 'fully_established' flag in subflow as previously done for msk->fully_established. Additionally, we make a crucial change: convert the subflow's 'fully_established' from 'bit_field' to 'bool' type. This is necessary because methods for avoiding data races don't work well with 'bit_field'. Specifically, the 'READ_ONCE' needs to know the size of the variable being accessed, which is not supported in 'bit_field'. Also, 'test_bit' expect the address of 'bit_field'. This change was prompted by compilation errors we encountered, as detailed below. ''' READ_ONCE: 477 | (sizeof(t) == sizeof(char) || \ | ^ sizeof(t) == sizeof(short)|| \ ././include/linux/compiler_types.h:490:23: note: in definition of macro ‘__compiletime_assert’ 490 | if (!(condition))\ | ^~~~~~~~~ ././include/linux/compiler_types.h:510:9: note: in expansion of macro ‘_compiletime_assert’ 510 | _compiletime_assert(condition, msg, \ __compiletime_assert_, __COUNTER__) | ^~~~~~~~~~~~~~~~~~~ ./include/asm-generic/rwonce.h:36:9: note: in expansion of macro ‘compiletime_assert’ 36 | compiletime_assert(__native_word(t) || \ sizeof(t) == sizeof(long long), \ | ^~~~~~~~~~~~~~~~~~ ./include/asm-generic/rwonce.h:36:28: note: in expansion of macro ‘__native_word’ 36 | compiletime_assert(__native_word(t) || \ | ^~~~~~~~~~~~~ sizeof(t) == sizeof(long long), \ ./include/asm-generic/rwonce.h:49:9: note: in expansion of macro ‘compiletime_assert_rwonce_type’ 49 | compiletime_assert_rwonce_type(x); \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ net/mptcp/protocol.h:781:39: note: in expansion of macro ‘READ_ONCE’ 781 | if (subflow->request_join && \ | !READ_ONCE(subflow->fully_established)) | ^~~~~~~~~ test_bit: error: cannot take address of bit-field 'fully_established' 50 | if (test_bit(1, &sf->fully_established)) | ''' Closes: multipath-tcp/mptcp_net-next#516 Signed-off-by: YANGANG <[email protected]>
1 parent 1d732d3 commit a0e59c4

File tree

5 files changed

+10
-10
lines changed

5 files changed

+10
-10
lines changed

net/mptcp/diag.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ static int subflow_get_info(struct sock *sk, struct sk_buff *skb)
4747
flags |= MPTCP_SUBFLOW_FLAG_BKUP_REM;
4848
if (sf->request_bkup)
4949
flags |= MPTCP_SUBFLOW_FLAG_BKUP_LOC;
50-
if (sf->fully_established)
50+
if (READ_ONCE(sf->fully_established))
5151
flags |= MPTCP_SUBFLOW_FLAG_FULLY_ESTABLISHED;
5252
if (sf->conn_finished)
5353
flags |= MPTCP_SUBFLOW_FLAG_CONNECTED;

net/mptcp/options.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ static bool mptcp_established_options_mp(struct sock *sk, struct sk_buff *skb,
461461
return false;
462462

463463
/* MPC/MPJ needed only on 3rd ack packet, DATA_FIN and TCP shutdown take precedence */
464-
if (subflow->fully_established || snd_data_fin_enable ||
464+
if (READ_ONCE(subflow->fully_established) || snd_data_fin_enable ||
465465
subflow->snd_isn != TCP_SKB_CB(skb)->seq ||
466466
sk->sk_state != TCP_ESTABLISHED)
467467
return false;
@@ -930,7 +930,7 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk,
930930
/* here we can process OoO, in-window pkts, only in-sequence 4th ack
931931
* will make the subflow fully established
932932
*/
933-
if (likely(subflow->fully_established)) {
933+
if (likely(READ_ONCE(subflow->fully_established))) {
934934
/* on passive sockets, check for 3rd ack retransmission
935935
* note that msk is always set by subflow_syn_recv_sock()
936936
* for mp_join subflows

net/mptcp/protocol.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3493,7 +3493,7 @@ static void schedule_3rdack_retransmission(struct sock *ssk)
34933493
struct tcp_sock *tp = tcp_sk(ssk);
34943494
unsigned long timeout;
34953495

3496-
if (mptcp_subflow_ctx(ssk)->fully_established)
3496+
if (READ_ONCE(mptcp_subflow_ctx(ssk)->fully_established))
34973497
return;
34983498

34993499
/* reschedule with a timeout above RTT, as we must look only for drop */

net/mptcp/protocol.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,6 @@ struct mptcp_subflow_context {
513513
request_bkup : 1,
514514
mp_capable : 1, /* remote is MPTCP capable */
515515
mp_join : 1, /* remote is JOINing */
516-
fully_established : 1, /* path validated */
517516
pm_notified : 1, /* PM hook called for established status */
518517
conn_finished : 1,
519518
map_valid : 1,
@@ -531,9 +530,10 @@ struct mptcp_subflow_context {
531530
valid_csum_seen : 1, /* at least one csum validated */
532531
is_mptfo : 1, /* subflow is doing TFO */
533532
close_event_done : 1, /* has done the post-closed part */
534-
__unused : 9;
533+
__unused : 10;
535534
bool data_avail;
536535
bool scheduled;
536+
bool fully_established; /* path validated */
537537
u32 remote_nonce;
538538
u64 thmac;
539539
u32 local_nonce;
@@ -778,7 +778,7 @@ static inline bool __tcp_can_send(const struct sock *ssk)
778778
static inline bool __mptcp_subflow_active(struct mptcp_subflow_context *subflow)
779779
{
780780
/* can't send if JOIN hasn't completed yet (i.e. is usable for mptcp) */
781-
if (subflow->request_join && !subflow->fully_established)
781+
if (subflow->request_join && !READ_ONCE(subflow->fully_established))
782782
return false;
783783

784784
return __tcp_can_send(mptcp_subflow_tcp_sock(subflow));

net/mptcp/subflow.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -785,7 +785,7 @@ void __mptcp_subflow_fully_established(struct mptcp_sock *msk,
785785
const struct mptcp_options_received *mp_opt)
786786
{
787787
subflow_set_remote_key(msk, subflow, mp_opt);
788-
subflow->fully_established = 1;
788+
WRITE_ONCE(subflow->fully_established, true);
789789
WRITE_ONCE(msk->fully_established, true);
790790

791791
if (subflow->is_mptfo)
@@ -1276,7 +1276,7 @@ static bool subflow_can_fallback(struct mptcp_subflow_context *subflow)
12761276
else if (READ_ONCE(msk->csum_enabled))
12771277
return !subflow->valid_csum_seen;
12781278
else
1279-
return !subflow->fully_established;
1279+
return !READ_ONCE(subflow->fully_established);
12801280
}
12811281

12821282
static void mptcp_subflow_fail(struct mptcp_sock *msk, struct sock *ssk)
@@ -2045,7 +2045,7 @@ static void subflow_ulp_clone(const struct request_sock *req,
20452045
} else if (subflow_req->mp_join) {
20462046
new_ctx->ssn_offset = subflow_req->ssn_offset;
20472047
new_ctx->mp_join = 1;
2048-
new_ctx->fully_established = 1;
2048+
WRITE_ONCE(new_ctx->fully_established, true);
20492049
new_ctx->remote_key_valid = 1;
20502050
new_ctx->backup = subflow_req->backup;
20512051
new_ctx->request_bkup = subflow_req->request_bkup;

0 commit comments

Comments
 (0)