All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Anil Kaushik" <anilkaushikwireless@gmail.com>, mptcp@lists.linux.dev
Subject: Re: [PATCH mptcp-next v7 4/6] mptcp: pm: in-kernel: retry subflows closed after an error
Date: Tue, 20 Oct 2026 08:37:38 +0000	[thread overview]
Message-ID: <sashiko-outbox-178583@kernel.org> (raw)
In-Reply-To: <20261020031711.1896660-5-anilkaushikwireless@gmail.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] mptcp: __mptcp_close() disconnects retry subflows before closing them
--

commit e4e5fe628ce5b62d531a83ca2d2c9088740581ed
Author: Anil Kaushik <anilkaushikwireless@gmail.com>

mptcp: pm: in-kernel: retry subflows closed after an error

This commit teaches the in-kernel path manager to re-create established
subflows that were initiated locally and closed after a path error such
as a retransmission or keepalive timeout. It also closes any re-created
subflows that are still connecting when the MPTCP socket is closed.

> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> index 60cbd91be6320..5cee1ed788caa 100644
> --- a/net/mptcp/protocol.c
> +++ b/net/mptcp/protocol.c

[ ... ]

> @@ -3494,6 +3499,26 @@ static void mptcp_check_listen_stop(struct sock *sk)
>  	release_sock(ssk);
>  }
>  
> +/* Re-created subflows still connecting are useless once the msk is closed,
> + * and their SYN retransmissions could keep them around for a long time.
> + */
> +static void mptcp_close_retry_subflows(struct sock *sk)
> +{
> +	struct mptcp_subflow_context *subflow, *tmp;
> +	struct mptcp_sock *msk = mptcp_sk(sk);
> +
> +	mptcp_for_each_subflow_safe(msk, subflow, tmp) {
> +		struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
> +
> +		if (!subflow->retry || inet_sk_state_load(ssk) != TCP_SYN_SENT)
> +			continue;
> +
> +		/* it never carried data: nothing to push or re-inject */
> +		mptcp_pm_subflow_check_next(msk, subflow);
> +		__mptcp_close_ssk(sk, ssk, subflow, 0);
> +	}
> +}
> +
>  bool __mptcp_close(struct sock *sk, long timeout)
>  {
>  	struct mptcp_subflow_context *subflow;
> @@ -3520,6 +3545,8 @@ bool __mptcp_close(struct sock *sk, long timeout)
>  		__mptcp_wr_shutdown(sk);
>  	}
>  
> +	mptcp_close_retry_subflows(sk);
> +
>  	sk_stream_wait_close(sk, timeout);
>  
>  cleanup:

[Severity: Medium]
Should mptcp_close_retry_subflows() be called before mptcp_do_fastclose()
and __mptcp_wr_shutdown(), or also handle retry subflows that have already
been disconnected?

When closing an established or TCP_CLOSE_WAIT MPTCP socket that has no
unsent data queued in mptcp_send_head(sk), __mptcp_wr_shutdown() calls
mptcp_check_send_data_fin(), which iterates over msk->conn_list and calls
mptcp_subflow_shutdown(sk, tcp_sk, SEND_SHUTDOWN) on every subflow:

net/mptcp/protocol.c:mptcp_subflow_shutdown() {
	...
	switch (ssk->sk_state) {
	case TCP_LISTEN:
		break;
	case TCP_SYN_SENT:
		WARN_ON_ONCE(tcp_disconnect(ssk, O_NONBLOCK));
		break;
	...
}

For a retry subflow in TCP_SYN_SENT, tcp_disconnect() sets ssk->sk_state to
TCP_CLOSE without invoking sk_state_change, unlinking the subflow from
msk->conn_list, or decrementing msk->pm.extra_subflows.

When mptcp_close_retry_subflows() runs right after __mptcp_wr_shutdown() (or
during close() after an earlier shutdown(fd, SHUT_WR)), it checks for
TCP_SYN_SENT:

	if (!subflow->retry || inet_sk_state_load(ssk) != TCP_SYN_SENT)
		continue;

Because ssk->sk_state is already TCP_CLOSE, mptcp_close_retry_subflows()
skips the retry subflow. This leaves msk->pm.extra_subflows incremented and
leaves the disconnected retry subflow on msk->conn_list, which can also
prevent sk->sk_state from transitioning to TCP_CLOSE before
sk_stream_wait_close(sk, timeout) when all other subflows are already
closed.

Similarly, on the fastclose path, calling mptcp_do_fastclose() before
mptcp_close_retry_subflows() calls tcp_send_active_reset() on the
TCP_SYN_SENT retry subflow before mptcp_close_retry_subflows() can close it.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261020031711.1896660-1-anilkaushikwireless@gmail.com?part=4

  reply	other threads:[~2026-10-20  8:37 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-20  3:17 [PATCH mptcp-next v7 0/6] mptcp: pm: in-kernel: retry subflows closed after an error Anil Kaushik
2026-10-20  3:17 ` [PATCH mptcp-next v7 1/6] selftests: mptcp: connect: retry write() on EAGAIN Anil Kaushik
2026-10-20  3:17 ` [PATCH mptcp-next v7 2/6] netlink: specs: mptcp: add the subflow-retries attribute Anil Kaushik
2026-10-20  3:17 ` [PATCH mptcp-next v7 3/6] mptcp: pm: in-kernel: add the subflow-retries limit Anil Kaushik
2026-10-20  3:17 ` [PATCH mptcp-next v7 4/6] mptcp: pm: in-kernel: retry subflows closed after an error Anil Kaushik
2026-10-20  8:37   ` sashiko-bot [this message]
2026-10-20  3:17 ` [PATCH mptcp-next v7 5/6] selftests: mptcp: pm_nl_ctl: support the subflow-retries limit Anil Kaushik
2026-10-20  3:17 ` [PATCH mptcp-next v7 6/6] selftests: mptcp: join: validate subflow retry after link failure Anil Kaushik

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=sashiko-outbox-178583@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=anilkaushikwireless@gmail.com \
    --cc=mptcp@lists.linux.dev \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.