[PATCH mptcp-net v2 2/3] mptcp: use READ/WRITE_ONCE for allow_subflows

Chenguang Zhao <[email protected]> Wed, 15 Jul 2026 14:18:29 +0800
Newsgroups dev.linux.lists.mptcp
Message-ID <[email protected]>
From: Chenguang Zhao <[email protected]>

mptcp_is_fully_established() may read allow_subflows without holding
fallback_lock. Annotate all allow_subflows accesses with READ_ONCE and
WRITE_ONCE to avoid data-race warnings and make the concurrency model
explicit.

Signed-off-by: Chenguang Zhao <[email protected]>
---
 net/mptcp/pm.c       |  2 +-
 net/mptcp/protocol.c | 12 ++++++------
 net/mptcp/protocol.h |  2 +-
 net/mptcp/subflow.c  |  2 +-
 4 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index c1f5c3ced4ee..869876a06493 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -884,7 +884,7 @@ void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq)
 		spin_unlock_bh(&msk->fallback_lock);
 		return;
 	}
-	msk->allow_subflows = false;
+	WRITE_ONCE(msk->allow_subflows, false);
 	spin_unlock_bh(&msk->fallback_lock);
 
 	if (!subflow->fail_tout) {
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 5b9522caaf43..13a8d16c657a 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -93,7 +93,7 @@ bool __mptcp_try_fallback(struct mptcp_sock *msk, int fb_mib)
 		return false;
 	}
 
-	msk->allow_subflows = false;
+	WRITE_ONCE(msk->allow_subflows, false);
 	set_bit(MPTCP_FALLBACK_DONE, &msk->flags);
 	__MPTCP_INC_STATS(net, fb_mib);
 	spin_unlock_bh(&msk->fallback_lock);
@@ -958,7 +958,7 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk)
 		return false;
 
 	spin_lock_bh(&msk->fallback_lock);
-	if (!msk->allow_subflows) {
+	if (!READ_ONCE(msk->allow_subflows)) {
 		spin_unlock_bh(&msk->fallback_lock);
 		return false;
 	}
@@ -2844,7 +2844,7 @@ static void __mptcp_retrans(struct sock *sk)
 			 */
 			spin_lock_bh(&msk->fallback_lock);
 			if (__mptcp_check_fallback(msk) ||
-			    !msk->allow_subflows) {
+			    !READ_ONCE(msk->allow_subflows)) {
 				spin_unlock_bh(&msk->fallback_lock);
 				release_sock(ssk);
 				goto clear_scheduled;
@@ -3055,7 +3055,7 @@ static void __mptcp_init_sock(struct sock *sk)
 	inet_csk(sk)->icsk_sync_mss = mptcp_sync_mss;
 	WRITE_ONCE(msk->csum_enabled, mptcp_is_checksum_enabled(sock_net(sk)));
 	msk->allow_infinite_fallback = true;
-	msk->allow_subflows = true;
+	WRITE_ONCE(msk->allow_subflows, true);
 	msk->recovery = false;
 	msk->subflow_id = 1;
 	msk->last_data_sent = tcp_jiffies32;
@@ -3473,7 +3473,7 @@ static int mptcp_disconnect(struct sock *sk, int flags)
 	 * can't overlap with a fallback anymore
 	 */
 	spin_lock_bh(&msk->fallback_lock);
-	msk->allow_subflows = true;
+	WRITE_ONCE(msk->allow_subflows, true);
 	msk->allow_infinite_fallback = true;
 	WRITE_ONCE(msk->flags, 0);
 	spin_unlock_bh(&msk->fallback_lock);
@@ -3873,7 +3873,7 @@ bool mptcp_finish_join(struct sock *ssk)
 	 */
 	if (!list_empty(&subflow->node)) {
 		spin_lock_bh(&msk->fallback_lock);
-		if (!msk->allow_subflows) {
+		if (!READ_ONCE(msk->allow_subflows)) {
 			spin_unlock_bh(&msk->fallback_lock);
 			return false;
 		}
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 03f0b33694d7..833c76c41768 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -1291,7 +1291,7 @@ static inline bool mptcp_is_fully_established(struct sock *sk)
 	return inet_sk_state_load(sk) == TCP_ESTABLISHED &&
 	       READ_ONCE(msk->fully_established) &&
 	       !__mptcp_check_fallback(msk) &&
-	       msk->allow_subflows;
+	       READ_ONCE(msk->allow_subflows);
 }
 
 static inline bool __mptcp_has_initial_subflow(const struct mptcp_sock *msk)
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index 8e386899ceb9..b04d6edb9be3 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -1323,7 +1323,7 @@ static bool mptcp_subflow_fail(struct mptcp_sock *msk, struct sock *ssk)
 		spin_unlock_bh(&msk->fallback_lock);
 		return false;
 	}
-	msk->allow_subflows = false;
+	WRITE_ONCE(msk->allow_subflows, false);
 	spin_unlock_bh(&msk->fallback_lock);
 
 	/* graceful failure can happen only on the MPC subflow */
-- 
2.25.1