diff options
author | Paolo Abeni <pabeni@redhat.com> | 2020-09-14 10:01:10 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-09-14 22:28:02 +0200 |
commit | da51aef5fe5b9ef389055f693472d4fb5a3f58f9 (patch) | |
tree | 5b507c2926494c896091cda790e44168bec20dd6 /net/mptcp | |
parent | mptcp: trigger msk processing even for OoO data (diff) | |
download | linux-da51aef5fe5b9ef389055f693472d4fb5a3f58f9.tar.xz linux-da51aef5fe5b9ef389055f693472d4fb5a3f58f9.zip |
mptcp: basic sndbuf autotuning
Let the msk sendbuf track the size of the larger subflow's
send window, so that we ensure mptcp_sendmsg() does not
exceed MPTCP-level send window.
The update is performed just before try to send any data.
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/mptcp')
-rw-r--r-- | net/mptcp/protocol.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 95573c6f7762..4f12a8ce0ddd 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -856,7 +856,8 @@ static void mptcp_nospace(struct mptcp_sock *msk) } } -static struct sock *mptcp_subflow_get_send(struct mptcp_sock *msk) +static struct sock *mptcp_subflow_get_send(struct mptcp_sock *msk, + u32 *sndbuf) { struct mptcp_subflow_context *subflow; struct sock *sk = (struct sock *)msk; @@ -865,6 +866,7 @@ static struct sock *mptcp_subflow_get_send(struct mptcp_sock *msk) sock_owned_by_me(sk); + *sndbuf = 0; if (!mptcp_ext_cache_refill(msk)) return NULL; @@ -877,6 +879,7 @@ static struct sock *mptcp_subflow_get_send(struct mptcp_sock *msk) return NULL; } + *sndbuf = max(tcp_sk(ssk)->snd_wnd, *sndbuf); if (subflow->backup) { if (!backup) backup = ssk; @@ -903,6 +906,7 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) struct page_frag *pfrag; size_t copied = 0; struct sock *ssk; + u32 sndbuf; bool tx_ok; long timeo; @@ -929,7 +933,7 @@ restart: } __mptcp_flush_join_list(msk); - ssk = mptcp_subflow_get_send(msk); + ssk = mptcp_subflow_get_send(msk, &sndbuf); while (!sk_stream_memory_free(sk) || !ssk || !mptcp_page_frag_refill(ssk, pfrag)) { @@ -953,13 +957,18 @@ restart: mptcp_clean_una(sk); - ssk = mptcp_subflow_get_send(msk); + ssk = mptcp_subflow_get_send(msk, &sndbuf); if (list_empty(&msk->conn_list)) { ret = -ENOTCONN; goto out; } } + /* do auto tuning */ + if (!(sk->sk_userlocks & SOCK_SNDBUF_LOCK) && + sndbuf > READ_ONCE(sk->sk_sndbuf)) + WRITE_ONCE(sk->sk_sndbuf, sndbuf); + pr_debug("conn_list->subflow=%p", ssk); lock_sock(ssk); @@ -1547,7 +1556,7 @@ static int mptcp_init_sock(struct sock *sk) sk_sockets_allocated_inc(sk); sk->sk_rcvbuf = sock_net(sk)->ipv4.sysctl_tcp_rmem[1]; - sk->sk_sndbuf = sock_net(sk)->ipv4.sysctl_tcp_wmem[2]; + sk->sk_sndbuf = sock_net(sk)->ipv4.sysctl_tcp_wmem[1]; return 0; } |