[RFC mptcp-next v11 05/15] mptcp: avoid sleeping in read_sock path under softirq

Geliang Tang posted 15 patches 2 days, 22 hours ago
[RFC mptcp-next v11 05/15] mptcp: avoid sleeping in read_sock path under softirq
Posted by Geliang Tang 2 days, 22 hours ago
From: Geliang Tang <tanggeliang@kylinos.cn>

When mptcp_read_sock() is called from softirq context via TLS
read_sock, lock_sock_fast() in mptcp_rcv_space_adjust() and
mptcp_cleanup_rbuf() may trigger might_sleep() warnings or
illegal sleeps, as softirq context cannot block.

Replace lock_sock_fast() with spin_trylock_bh() to make locking
non-blocking and context-safe. Skip operations if the lock cannot
be acquired.

Co-developed-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Gang Yan <yangang@kylinos.cn>
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/protocol.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 5585f43cf879..e9e40dfab5ea 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -561,12 +561,11 @@ static void mptcp_send_ack(struct mptcp_sock *msk)
 
 static void mptcp_subflow_cleanup_rbuf(struct sock *ssk, int copied)
 {
-	bool slow;
-
-	slow = lock_sock_fast(ssk);
-	if (tcp_can_send_ack(ssk))
+	if (!spin_trylock_bh(&ssk->sk_lock.slock))
+		return;
+	if (!sock_owned_by_user(ssk) && tcp_can_send_ack(ssk))
 		tcp_cleanup_rbuf(ssk, copied);
-	unlock_sock_fast(ssk, slow);
+	spin_unlock_bh(&ssk->sk_lock.slock);
 }
 
 static bool mptcp_subflow_could_cleanup(const struct sock *ssk, bool rx_empty)
@@ -2194,14 +2193,15 @@ static void mptcp_rcv_space_adjust(struct mptcp_sock *msk, int copied)
 		 */
 		mptcp_for_each_subflow(msk, subflow) {
 			struct sock *ssk;
-			bool slow;
 
 			ssk = mptcp_subflow_tcp_sock(subflow);
-			slow = lock_sock_fast(ssk);
+			if (!spin_trylock_bh(&ssk->sk_lock.slock))
+				continue;
 			/* subflows can be added before tcp_init_transfer() */
-			if (tcp_sk(ssk)->rcvq_space.space)
+			if (!sock_owned_by_user(ssk) &&
+			    tcp_sk(ssk)->rcvq_space.space)
 				tcp_rcvbuf_grow(ssk, copied);
-			unlock_sock_fast(ssk, slow);
+			spin_unlock_bh(&ssk->sk_lock.slock);
 		}
 	}
 
-- 
2.53.0