diff mbox series

[v2,1/4] mptcp: add wmem_queued accounting

Message ID 20191112141038.19213-2-fw@strlen.de
State Superseded, archived
Headers show
Series [v2,1/4] mptcp: add wmem_queued accounting | expand

Commit Message

Florian Westphal Nov. 12, 2019, 2:10 p.m. UTC
Peer could ack data at TCP level but refrain from sending mptcp-level ACKs.
This could result in a growing the mptcp socket backlog indefinitely.

We should thus block mptcp_sendmsg until the peer has acked some of the
sent data.

In order to be able to do so, increment the mptcp socket wmem_queued
counter on memory allocation and decrement it when releasing the memory
on mptcp-level ack reception.

Because TCP performns sndbuf auto-tuning up to tcp_wmem_max[2], make
this the mptcp sk_sndbuf limit.

In the future we could add experiment with autotuning as TCP does in
tcp_sndbuf_expand().

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

Patch

diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 7bea6b62f66e..65f10bb372aa 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -139,8 +139,11 @@  static inline bool mptcp_frag_can_collapse_to(const struct mptcp_sock *msk,
 
 static void dfrag_clear(struct sock *sk, struct mptcp_data_frag *dfrag)
 {
+	int len = dfrag->data_len + dfrag->overhead;
+
 	list_del(&dfrag->list);
-	sk_mem_uncharge(sk, dfrag->data_len + dfrag->overhead);
+	sk_mem_uncharge(sk, len);
+	sk_wmem_queued_add(sk, -len);
 	put_page(dfrag->page);
 }
 
@@ -304,6 +307,9 @@  static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
 		if (!dfrag_collapsed) {
 			get_page(dfrag->page);
 			list_add_tail(&dfrag->list, &msk->rtx_queue);
+			sk_wmem_queued_add(sk, frag_truesize);
+		} else {
+			sk_wmem_queued_add(sk, ret);
 		}
 
 		/* charge data on mptcp rtx queue to the master socket
@@ -711,6 +717,7 @@  static int mptcp_init_sock(struct sock *sk)
 		return ret;
 
 	sk_sockets_allocated_inc(sk);
+	sk->sk_sndbuf = sock_net(sk)->ipv4.sysctl_tcp_wmem[2];
 
 	return 0;
 }