[PATCH net-next v5 2/2] mptcp: annotate lockless access to sk->sk_err
From: Quanye Yang via B4 Relay
Date: Fri Sep 25 2026 - 08:49:07 EST
From: Quanye Yang <quanyeyang@xxxxxxxxx>
sock_error() can clear sk_err with xchg() without the socket lock.
On the no-data msk recv and splice paths, call sock_error() once and
only stop when it returns a non-zero error. Annotate the remaining
msk send and subflow error-report peeks with READ_ONCE().
Signed-off-by: Quanye Yang <quanyeyang@xxxxxxxxx>
---
net/mptcp/protocol.c | 14 ++++++--------
net/mptcp/subflow.c | 4 ++--
2 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index e1f08f71cdb1..e37a8642a4b0 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -969,7 +969,7 @@ static bool move_skbs_to_msk(struct mptcp_sock *msk, struct sock *ssk)
moved = __mptcp_move_skbs_from_subflow(msk, ssk, true);
__mptcp_ofo_queue(msk);
- if (unlikely(ssk->sk_err))
+ if (unlikely(READ_ONCE(ssk->sk_err)))
__mptcp_subflow_error_report(sk, ssk);
/* If the moves have caught up with the DATA_FIN sequence number
@@ -2028,7 +2028,7 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
}
ret = -EPIPE;
- if (unlikely(sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)))
+ if (unlikely(READ_ONCE(sk->sk_err) || (sk->sk_shutdown & SEND_SHUTDOWN)))
goto do_error;
pfrag = sk_page_frag(sk);
@@ -2429,10 +2429,9 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
!timeo)
break;
} else {
- if (sk->sk_err) {
- copied = sock_error(sk);
+ copied = sock_error(sk);
+ if (copied)
break;
- }
if (sk->sk_shutdown & RCV_SHUTDOWN)
break;
@@ -4655,10 +4654,9 @@ static ssize_t mptcp_splice_read(struct socket *sock, loff_t *ppos,
break;
if (sock_flag(sk, SOCK_DONE))
break;
- if (sk->sk_err) {
- ret = sock_error(sk);
+ ret = sock_error(sk);
+ if (ret)
break;
- }
if (sk->sk_shutdown & RCV_SHUTDOWN)
break;
if (sk->sk_state == TCP_CLOSE) {
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index af81ad5e699d..ec9668fe8d5b 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -1541,7 +1541,7 @@ static void subflow_data_ready(struct sock *sk)
if (mptcp_data_avail(msk) < parent->sk_rcvlowat &&
(tcp_sk(sk)->rcv_nxt - tcp_sk(sk)->rcv_wup) > inet_csk(sk)->icsk_ack.rcv_mss)
inet_csk(sk)->icsk_ack.pending |= ICSK_ACK_NOW;
- } else if (unlikely(sk->sk_err)) {
+ } else if (unlikely(READ_ONCE(sk->sk_err))) {
subflow_error_report(sk);
}
}
@@ -1889,7 +1889,7 @@ static void subflow_state_change(struct sock *sk)
*/
if (mptcp_subflow_data_available(sk))
mptcp_data_ready(parent, sk);
- else if (unlikely(sk->sk_err))
+ else if (unlikely(READ_ONCE(sk->sk_err)))
subflow_error_report(sk);
subflow_sched_work_if_closed(mptcp_sk(parent), sk);
--
2.55.0