Skip to content

Commit 0682e69

Browse files
nealcardwelldavem330
authored andcommitted
tcp: count packets marked lost for a TCP connection
Count the number of packets that a TCP connection marks lost. Congestion control modules can use this loss rate information for more intelligent decisions about how fast to send. Specifically, this is used in TCP BBR policer detection. BBR uses a high packet loss rate as one signal in its policer detection and policer bandwidth estimation algorithm. The BBR policer detection algorithm cannot simply track retransmits, because a retransmit can be (and often is) an indicator of packets lost long, long ago. This is particularly true in a long CA_Loss period that repairs the initial massive losses when a policer kicks in. Signed-off-by: Van Jacobson <[email protected]> Signed-off-by: Neal Cardwell <[email protected]> Signed-off-by: Yuchung Cheng <[email protected]> Signed-off-by: Nandita Dukkipati <[email protected]> Signed-off-by: Eric Dumazet <[email protected]> Signed-off-by: Soheil Hassas Yeganeh <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent b2d3ea4 commit 0682e69

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

include/linux/tcp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ struct tcp_sock {
267267
* receiver in Recovery. */
268268
u32 prr_out; /* Total number of pkts sent during Recovery. */
269269
u32 delivered; /* Total data packets delivered incl. rexmits */
270+
u32 lost; /* Total data packets lost incl. rexmits */
270271

271272
u32 rcv_wnd; /* Current receiver window */
272273
u32 write_seq; /* Tail(+1) of data held in tcp send buffer */

net/ipv4/tcp_input.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -899,12 +899,29 @@ static void tcp_verify_retransmit_hint(struct tcp_sock *tp, struct sk_buff *skb)
899899
tp->retransmit_high = TCP_SKB_CB(skb)->end_seq;
900900
}
901901

902+
/* Sum the number of packets on the wire we have marked as lost.
903+
* There are two cases we care about here:
904+
* a) Packet hasn't been marked lost (nor retransmitted),
905+
* and this is the first loss.
906+
* b) Packet has been marked both lost and retransmitted,
907+
* and this means we think it was lost again.
908+
*/
909+
static void tcp_sum_lost(struct tcp_sock *tp, struct sk_buff *skb)
910+
{
911+
__u8 sacked = TCP_SKB_CB(skb)->sacked;
912+
913+
if (!(sacked & TCPCB_LOST) ||
914+
((sacked & TCPCB_LOST) && (sacked & TCPCB_SACKED_RETRANS)))
915+
tp->lost += tcp_skb_pcount(skb);
916+
}
917+
902918
static void tcp_skb_mark_lost(struct tcp_sock *tp, struct sk_buff *skb)
903919
{
904920
if (!(TCP_SKB_CB(skb)->sacked & (TCPCB_LOST|TCPCB_SACKED_ACKED))) {
905921
tcp_verify_retransmit_hint(tp, skb);
906922

907923
tp->lost_out += tcp_skb_pcount(skb);
924+
tcp_sum_lost(tp, skb);
908925
TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
909926
}
910927
}
@@ -913,6 +930,7 @@ void tcp_skb_mark_lost_uncond_verify(struct tcp_sock *tp, struct sk_buff *skb)
913930
{
914931
tcp_verify_retransmit_hint(tp, skb);
915932

933+
tcp_sum_lost(tp, skb);
916934
if (!(TCP_SKB_CB(skb)->sacked & (TCPCB_LOST|TCPCB_SACKED_ACKED))) {
917935
tp->lost_out += tcp_skb_pcount(skb);
918936
TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
@@ -1890,6 +1908,7 @@ void tcp_enter_loss(struct sock *sk)
18901908
struct sk_buff *skb;
18911909
bool new_recovery = icsk->icsk_ca_state < TCP_CA_Recovery;
18921910
bool is_reneg; /* is receiver reneging on SACKs? */
1911+
bool mark_lost;
18931912

18941913
/* Reduce ssthresh if it has not yet been made inside this window. */
18951914
if (icsk->icsk_ca_state <= TCP_CA_Disorder ||
@@ -1923,8 +1942,12 @@ void tcp_enter_loss(struct sock *sk)
19231942
if (skb == tcp_send_head(sk))
19241943
break;
19251944

1945+
mark_lost = (!(TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED) ||
1946+
is_reneg);
1947+
if (mark_lost)
1948+
tcp_sum_lost(tp, skb);
19261949
TCP_SKB_CB(skb)->sacked &= (~TCPCB_TAGBITS)|TCPCB_SACKED_ACKED;
1927-
if (!(TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_ACKED) || is_reneg) {
1950+
if (mark_lost) {
19281951
TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_ACKED;
19291952
TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
19301953
tp->lost_out += tcp_skb_pcount(skb);

0 commit comments

Comments
 (0)