From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-ot1-f51.google.com (mail-ot1-f51.google.com [209.85.210.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 800823B635C for ; Fri, 9 Oct 2026 05:01:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.51 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791522097; cv=none; b=SvEQANDlh7tCmMMrNqh0YWR6V3UVskfBe2HNNkYvi/pWZfOGm2G/s20jl3ow/Q7OVR3kWQVY0QwyCeDjN+TqkZHh1k9+FDMpeF6oR9/pwIi+3WM58hG0JmG8Ua6c/4I40SCsvmZwEKFUjVeezIMERUhTxlcmk4RjHUu1OiLpzFo= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791522097; c=relaxed/simple; bh=jWwNvQhVRJMaI/NuEyzm8YPpikM+OQknELJgCA/Uvq0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mRTocAZdOqXGVXD9etN/ooltaezEXl1+E17zTZrGYowmZ1P+Dk+03dlUHNNbyEcKkuzHxH7R7+hpHxY8ijPL2WA2fohbnChxf3Z/ZFEuaIlPhq70dP6fgw9/4iai/6y7WAnqGAZ8aGB+TA0ek/FO1lupvY+kttIfgZzri2YEdMU= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=openai.com; spf=pass smtp.mailfrom=openai.com; dkim=pass (1024-bit key) header.d=openai.com header.i=@openai.com header.b=abjvs95R; arc=none smtp.client-ip=209.85.210.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=openai.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=openai.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=openai.com header.i=@openai.com header.b="abjvs95R" Received: by mail-ot1-f51.google.com with SMTP id 46e09a7af769-82503732024so1670987a34.3 for ; Thu, 08 Oct 2026 22:01:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openai.com; s=google; t=1791522094; x=1792126894; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=1U3fvYWJH0YcBKOkycFzaZNpcYiFFVMrPSZ0BUt9UTo=; b=abjvs95R8Dh34nO6E2E/FmMYMWpN7wPE2BZ2QqUptePgwWJPRL5D8YYxaekpurU3gh UZQQhRq9rLK9gq++Ttu4O71nrMAOtIjSArUTZ9uRQ6F4nR0sOF6dBFYYhWI0fLUDrYKz 9Dbe/1j5GdXjUQ5lGws0cxZ76cDY8HksctlpA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1791522094; x=1792126894; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=1U3fvYWJH0YcBKOkycFzaZNpcYiFFVMrPSZ0BUt9UTo=; b=WYmYtWTCx0TJdsY7I6UEnVlisMfsg5PaSqf7HPZvx2l9h99p8z5ZAaVlXoLSiooiPm Yr40LN1nxsvnOADuzzpPJgNh/r56XZ5YhBnKt4amsil4CghHuR+tFXZER418luMOmw6f /Ch9Ix6Bj86xG/ZLRNGWRm2OePl8cjVIHwJZzHnH79++ktKzrNUJrN9jA4lBdUpErQWt 3zT65NnM1b12nlzOOpXstjZvF17QAWwP16GhrClTxzaV2NQaHXLXba2hkF7PkzB34IM3 9b64Fl3gQjUkWtCnO7ITtkGxM/aXgbjsH2l3+dSlW2VIVIU2MvC7qSh4t+0qlbWeXIr1 dSRg== X-Forwarded-Encrypted: i=1; AKwUvBzrXafJQWOlxangW48x0I/PviaKlWrRmKP4xpD9IKzv4xtE7zSxWbQHwrdgXOnD2stJq4UVQtyYZdggX6k=@vger.kernel.org X-Gm-Message-State: AFuF++lCK+xRdUYsdQiynbDUOv3wr8pvJLw5uV8ecCzkeMiOzA0s5y+K bGpY3BgqizcvqARe2xNE4d4IugRQ5iC/Nt9DB2ZEDmsQHBJAs37ru7E/UA97U8XzomU= X-Gm-Gg: AYBFou08ymUPgtTux6/xB+7kprp34qGHX9Cd+sYCnbtxRNabUrSOO44RC6oTYYnQthV lWfsNqxAZeUhgll1ax5q//jFSQuY4AwU52kh/hhn2CS0K9By4EvIXum4qZjV/P0UdVGuH2J4vEX pExKLd4KbJLjfhb1mPOOf79s1Od1UOEmJxyZHAjMXQTtIc9bPb3C4gc5clpiL4g4EGwDfWDkk3T e6y1aEVHZ+U1H1yVAbwhSk1+IvMbx9XoTHWPX69CQp76q8YIjTComdOPCFzX93Ndo7Q7qUSME6d OPp7SqfOKdd9GOm9+G7PMM+2E2bjH8nQWU8oXj48mntNPHjxItoTA6zDmqXE/Kb4brMdkunE1cf 13zG/B/fb0lA0U0kHDrLdO2GYI3KrfkGsQrbcd9rhnjY538+b3Mo5D+QzWb51bmmXHxeGhfBNOf ESgYGs4cwB47qfBpsYowfB7WJutqP7ZHz+WQT356J3VYLr7Gf2vVanLYHGZcHNEW8bim6dBKt4j eGNJrSKvuwdJ72lIdQsWl/szS0ibtxysizQyIZwtn4ktw+hfpYUrh3KWnOEVBb8MlyDLjLSFZ2J iEE= X-Received: by 2002:a05:6808:221f:b0:496:34a:d7e3 with SMTP id 5614622812f47-50c4ed40abcmr639887b6e.17.1791522094369; Thu, 08 Oct 2026 22:01:34 -0700 (PDT) Received: from com-68297.corp.openai.org ([199.47.143.0]) by smtp.gmail.com with ESMTPSA id 5614622812f47-50c1c1246cbsm944574b6e.18.2026.10.08.22.01.31 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Thu, 08 Oct 2026 22:01:33 -0700 (PDT) From: nramaswamy@openai.com To: netdev@vger.kernel.org Cc: Neil Ramaswamy , Eric Dumazet , Neal Cardwell , Neal Cardwell , Kuniyuki Iwashima , Yuchung Cheng , Jiayuan Chen , "David S. Miller" , Jakub Kicinski , Paolo Abeni , Simon Horman , Shuah Khan , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH net v3 1/3] tcp: restore RACK list membership when undoing loss Date: Thu, 8 Oct 2026 22:00:32 -0700 Message-ID: X-Mailer: git-send-email 2.55.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Neil Ramaswamy Partial undo can clear the TCPCB_LOST flag on segments already removed from RACK's list, which prevents subsequent RACK loss detection, leading to segments only being retransmitted after the RTO. This patch uses the implementation provided by Neal Cardwell to linearly insert lost segments that have not been retransmitted back into the RACK list. The core observation is that segments that are lost but not ever retransmitted are already sorted by their transmission timestamp, which allows us to insert them into RACK's list linearly, without needing to pre-sort them. Segments with TCPCB_EVER_RETRANS are left for RTO recovery. Their transmission order can differ from their sequence order, so reinserting them would require addiitonal work (e.g. sorting) before reinsertion into the RACK list. We assume that this case is rare, and allow those segments to be transmitted by the RTO. My investigation started from seeing repeated TCP stalls in prod and the mitigation that seemed to prevent these stalls was limiting SO_SNDBUF to 96 KiB. It also seems like others have seen similar symptoms before [1]. [1] https://lore.kernel.org/netdev/35A4DDAA-7E8D-43CB-A1F5-D1E46A4ED42E@gmail.com/ Fixes: 043b87d7599e ("tcp: more efficient RACK loss detection") Suggested-by: Neal Cardwell Suggested-by: Yuchung Cheng Link: https://lore.kernel.org/netdev/20261006141300.1722466-1-ncardwell.sw@gmail.com/ Signed-off-by: Neil Ramaswamy Assisted-by: LLM sparse --- net/ipv4/tcp_input.c | 50 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 92bc60716f33..d0a1e8899c4b 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -2840,15 +2840,63 @@ static void DBGUNDO(struct sock *sk, const char *msg) #endif } +/* Is skb @a after skb @b in tp->tsorted_sent_queue (send) order? */ +static bool tcp_tsorted_after(const struct list_head *a, + const struct list_head *b) +{ + const struct sk_buff *skb_a = list_entry(a, struct sk_buff, + tcp_tsorted_anchor); + const struct sk_buff *skb_b = list_entry(b, struct sk_buff, + tcp_tsorted_anchor); + + return tcp_skb_sent_after(tcp_skb_timestamp_us(skb_a), + tcp_skb_timestamp_us(skb_b), + TCP_SKB_CB(skb_a)->end_seq, + TCP_SKB_CB(skb_b)->end_seq); +} + +/* Link skb back into tp->tsorted_sent_queue in send order, at or after + * pos, and advance pos to it. Leave skb alone if it was sent before + * pos. During undo, all relink calls together traverse the RACK list + * at most once, as pos only moves forward. + */ +static void tcp_tsorted_relink_skb(struct tcp_sock *tp, struct sk_buff *skb, + struct list_head **pos_ptr) +{ + struct list_head *head = &tp->tsorted_sent_queue; + struct list_head *node = &skb->tcp_tsorted_anchor; + struct list_head *pos = *pos_ptr; + + if (pos != head && !tcp_tsorted_after(node, pos)) + return; + while (pos->next != head && !tcp_tsorted_after(pos->next, node)) + pos = pos->next; + if (pos != node) /* not already linked in place */ + list_move(node, pos); + *pos_ptr = node; +} + static void tcp_undo_cwnd_reduction(struct sock *sk, bool unmark_loss) { struct tcp_sock *tp = tcp_sk(sk); if (unmark_loss) { + struct list_head *pos = &tp->tsorted_sent_queue; struct sk_buff *skb; skb_rbtree_walk(skb, &sk->tcp_rtx_queue) { - TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST; + u8 sacked = TCP_SKB_CB(skb)->sacked; + + TCP_SKB_CB(skb)->sacked = sacked & ~TCPCB_LOST; + /* RACK unlinked the skbs it marked lost. Skbs never + * retransmitted keep their original send times, which + * increase with sequence, so in one forward pass we + * relink them all. For the rare case of undo after + * lost retransmissions, we will fall back to RTO. + */ + if ((sacked & (TCPCB_LOST | TCPCB_EVER_RETRANS)) == + TCPCB_LOST) + tcp_tsorted_relink_skb(tp, skb, &pos); } tp->lost_out = 0; tcp_clear_all_retrans_hints(tp); -- 2.55.0