From: Paolo Abeni pabeni@redhat.com
[ Upstream commit d4e85922e3e7ef2071f91f65e61629b60f3a9cf4 ]
If the peer closes all the existing subflows for a given mptcp socket and later the application closes it, the current implementation let it survive until the timewait timeout expires.
While the above is allowed by the protocol specification it consumes resources for almost no reason and additionally causes sporadic self-tests failures.
Let's move the mptcp socket to the TCP_CLOSE state when there are no alive subflows at close time, so that the allocated resources will be freed immediately.
Fixes: e16163b6e2b7 ("mptcp: refactor shutdown and close") Cc: stable@vger.kernel.org Signed-off-by: Paolo Abeni pabeni@redhat.com Reviewed-by: Matthieu Baerts matthieu.baerts@tessares.net Signed-off-by: Matthieu Baerts matthieu.baerts@tessares.net Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Matthieu Baerts matthieu.baerts@tessares.net --- Hi Greg, Sasha,
Here is one MPTCP patch backport that recently failed to apply to the 5.15 stable tree: it clears resources earlier if there is no more reasons to keep MPTCP sockets alive.
I had a simple conflict because in v5.15, the context is a bit different when iterating over the different subflows in __mptcp_close() but the idea is still the same: in this loop, a counter needs to be incremented. --- net/mptcp/protocol.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 47f359dac247..5d05d85242bc 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -2726,6 +2726,7 @@ static void mptcp_close(struct sock *sk, long timeout) { struct mptcp_subflow_context *subflow; bool do_cancel_work = false; + int subflows_alive = 0;
lock_sock(sk); sk->sk_shutdown = SHUTDOWN_MASK; @@ -2747,11 +2748,19 @@ static void mptcp_close(struct sock *sk, long timeout) struct sock *ssk = mptcp_subflow_tcp_sock(subflow); bool slow = lock_sock_fast_nested(ssk);
+ subflows_alive += ssk->sk_state != TCP_CLOSE; + sock_orphan(ssk); unlock_sock_fast(ssk, slow); } sock_orphan(sk);
+ /* all the subflows are closed, only timeout can change the msk + * state, let's not keep resources busy for no reasons + */ + if (subflows_alive == 0) + inet_sk_state_store(sk, TCP_CLOSE); + sock_hold(sk); pr_debug("msk=%p state=%d", sk, sk->sk_state); if (sk->sk_state == TCP_CLOSE) {
--- base-commit: e2c1a934fd8e4288e7a32f4088ceaccf469eb74c change-id: 20230214-upstream-stable-20230214-linux-5-15-94-rc1-mptcp-fixes-517feb25bd47
Best regards,
On Fri, Feb 17, 2023 at 02:37:33PM +0100, Matthieu Baerts wrote:
From: Paolo Abeni pabeni@redhat.com
[ Upstream commit d4e85922e3e7ef2071f91f65e61629b60f3a9cf4 ]
If the peer closes all the existing subflows for a given mptcp socket and later the application closes it, the current implementation let it survive until the timewait timeout expires.
While the above is allowed by the protocol specification it consumes resources for almost no reason and additionally causes sporadic self-tests failures.
Let's move the mptcp socket to the TCP_CLOSE state when there are no alive subflows at close time, so that the allocated resources will be freed immediately.
Fixes: e16163b6e2b7 ("mptcp: refactor shutdown and close") Cc: stable@vger.kernel.org Signed-off-by: Paolo Abeni pabeni@redhat.com Reviewed-by: Matthieu Baerts matthieu.baerts@tessares.net Signed-off-by: Matthieu Baerts matthieu.baerts@tessares.net Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Matthieu Baerts matthieu.baerts@tessares.net
Hi Greg, Sasha,
Here is one MPTCP patch backport that recently failed to apply to the 5.15 stable tree: it clears resources earlier if there is no more reasons to keep MPTCP sockets alive.
I had a simple conflict because in v5.15, the context is a bit different when iterating over the different subflows in __mptcp_close() but the idea is still the same: in this loop, a counter needs to be incremented.
Now queued up, thanks.
greg k-h
linux-stable-mirror@lists.linaro.org