Commit 27fd0286 authored by Paolo Abeni's avatar Paolo Abeni Committed by Jakub Kicinski
Browse files

mptcp: clear scheduled subflows on retransmit



When __mptcp_retrans() kicks-in, it schedules one or more subflows for
retransmission, but such subflows could be actually left alone if there
is no more data to retransmit and/or in case of concurrent fallback.

Scheduled subflows could be processed much later in time, i.e. when new
data will be transmitted, leading to bad subflow selection.

Explicitly clear all scheduled subflows before leaving the
retransmission function.

Fixes: ee2708ae ("mptcp: use get_retrans wrapper")
Cc: stable@vger.kernel.org
Reported-by: default avatarFilip Pokryvka <fpokryvk@redhat.com>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
Reviewed-by: default avatarMatthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: default avatarMatthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20251125-net-mptcp-clear-sched-rtx-v1-1-1cea4ad2165f@kernel.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent da62abaa
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -2665,7 +2665,7 @@ static void __mptcp_retrans(struct sock *sk)
		}

		if (!mptcp_send_head(sk))
			return;
			goto clear_scheduled;

		goto reset_timer;
	}
@@ -2696,7 +2696,7 @@ static void __mptcp_retrans(struct sock *sk)
			if (__mptcp_check_fallback(msk)) {
				spin_unlock_bh(&msk->fallback_lock);
				release_sock(ssk);
				return;
				goto clear_scheduled;
			}

			while (info.sent < info.limit) {
@@ -2728,6 +2728,15 @@ static void __mptcp_retrans(struct sock *sk)

	if (!mptcp_rtx_timer_pending(sk))
		mptcp_reset_rtx_timer(sk);

clear_scheduled:
	/* If no rtx data was available or in case of fallback, there
	 * could be left-over scheduled subflows; clear them all
	 * or later xmit could use bad ones
	 */
	mptcp_for_each_subflow(msk, subflow)
		if (READ_ONCE(subflow->scheduled))
			mptcp_subflow_set_scheduled(subflow, false);
}

/* schedule the timeout timer for the relevant event: either close timeout