diff mbox series

[v3,3/6] mptcp: add rmem queue accounting

Message ID 20200218122110.23817-4-fw@strlen.de
State Superseded, archived
Delegated to: Paolo Abeni
Headers show
Series mptcp: update mptcp ack sequence from work queue | expand

Commit Message

Florian Westphal Feb. 18, 2020, 12:21 p.m. UTC
v2: adjust rcvbuf outside of loop.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 net/mptcp/protocol.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 85d7f73ca804..ac81283d5ec3 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -172,6 +172,10 @@  void mptcp_data_ready(struct sock *sk)
 	if (test_and_set_bit(MPTCP_WORK_DATA_READY, &msk->flags))
 		return;
 
+	/* don't schedule if mptcp sk is (still) over limit */
+	if (atomic_read(&sk->sk_rmem_alloc) > READ_ONCE(sk->sk_rcvbuf))
+		return;
+
 	sock_hold(sk);
 	if (!schedule_work(&msk->rtx_work))
 		sock_put(sk);
@@ -699,7 +703,7 @@  static void __mptcp_move_skb(struct mptcp_sock *msk, struct sock *ssk,
 	struct sock *sk = (struct sock *)msk;
 
 	__skb_unlink(skb, &ssk->sk_receive_queue);
-	skb_orphan(skb);
+	skb_set_owner_r(skb, sk);
 	__skb_queue_tail(&sk->sk_receive_queue, skb);
 
 	msk->ack_seq += copy_len;
@@ -717,6 +721,7 @@  static bool __mptcp_move_skbs(struct mptcp_sock *msk)
 		struct sock *ssk;
 		bool more_data_avail;
 		struct tcp_sock *tp;
+		int rcvbuf;
 
 		ssk = mptcp_subflow_recv_lookup(msk);
 		if (!ssk)
@@ -726,6 +731,10 @@  static bool __mptcp_move_skbs(struct mptcp_sock *msk)
 
 		lock_sock(ssk);
 
+		rcvbuf = max(ssk->sk_rcvbuf, sk->sk_rcvbuf);
+		if (rcvbuf > sk->sk_rcvbuf)
+			sk->sk_rcvbuf = rcvbuf;
+
 		tp = tcp_sk(ssk);
 		do {
 			u32 map_remaining, offset;
@@ -741,6 +750,11 @@  static bool __mptcp_move_skbs(struct mptcp_sock *msk)
 			if (!skb)
 				break;
 
+			if (!sk_rmem_schedule(sk, skb, skb->truesize)) {
+				done = true;
+				break;
+			}
+
 			offset = seq - TCP_SKB_CB(skb)->seq;
 			fin = TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN;
 			if (fin) {