summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Abeni <pabeni@redhat.com>2025-11-25 17:59:11 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-12-07 06:18:52 +0900
commitce318ec9864bc3dbaa37d71ec4813f0358f0d44a (patch)
tree6d27d231e2b68f8e98705e1ef98d3821eb622ba6
parent71796c91ee8e33faf4434a9e210b5063c28ea907 (diff)
downloadlinux-ce318ec9864bc3dbaa37d71ec4813f0358f0d44a.tar.gz
linux-ce318ec9864bc3dbaa37d71ec4813f0358f0d44a.tar.bz2
linux-ce318ec9864bc3dbaa37d71ec4813f0358f0d44a.zip
mptcp: clear scheduled subflows on retransmit
commit 27fd02860164bfa78cec2640dfad630d832e302c upstream. 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: ee2708aedad0 ("mptcp: use get_retrans wrapper") Cc: stable@vger.kernel.org Reported-by: Filip Pokryvka <fpokryvk@redhat.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20251125-net-mptcp-clear-sched-rtx-v1-1-1cea4ad2165f@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--net/mptcp/protocol.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 73b3a44b183f..90e0a9e8e014 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -2691,7 +2691,7 @@ static void __mptcp_retrans(struct sock *sk)
}
if (!mptcp_send_head(sk))
- return;
+ goto clear_scheduled;
goto reset_timer;
}
@@ -2722,7 +2722,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) {
@@ -2754,6 +2754,15 @@ reset_timer:
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