aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_input.c
diff options
context:
space:
mode:
authorNeal Cardwell <ncardwell@google.com>2016-09-19 23:39:13 -0400
committerDavid S. Miller <davem@davemloft.net>2016-09-21 00:23:00 -0400
commit0682e6902a52aca7caf6ad42551b16ea0f87bc31 (patch)
tree659bae32eb96d42f6b39ef8f383fa20cd37a0b0e /net/ipv4/tcp_input.c
parentb2d3ea4a730f812b9c0f67a67b6762ce66ddb17c (diff)
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 <vanj@google.com> Signed-off-by: Neal Cardwell <ncardwell@google.com> Signed-off-by: Yuchung Cheng <ycheng@google.com> Signed-off-by: Nandita Dukkipati <nanditad@google.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Soheil Hassas Yeganeh <soheil@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r--net/ipv4/tcp_input.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 6886f386464f..9413288c2778 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -899,12 +899,29 @@ static void tcp_verify_retransmit_hint(struct tcp_sock *tp, struct sk_buff *skb)
899 tp->retransmit_high = TCP_SKB_CB(skb)->end_seq; 899 tp->retransmit_high = TCP_SKB_CB(skb)->end_seq;
900} 900}
901 901
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 */
909static 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
902static void tcp_skb_mark_lost(struct tcp_sock *tp, struct sk_buff *skb) 918static void tcp_skb_mark_lost(struct tcp_sock *tp, struct sk_buff *skb)
903{ 919{
904 if (!(TCP_SKB_CB(skb)->sacked & (TCPCB_LOST|TCPCB_SACKED_ACKED))) { 920 if (!(TCP_SKB_CB(skb)->sacked & (TCPCB_LOST|TCPCB_SACKED_ACKED))) {
905 tcp_verify_retransmit_hint(tp, skb); 921 tcp_verify_retransmit_hint(tp, skb);
906 922
907 tp->lost_out += tcp_skb_pcount(skb); 923 tp->lost_out += tcp_skb_pcount(skb);
924 tcp_sum_lost(tp, skb);
908 TCP_SKB_CB(skb)->sacked |= TCPCB_LOST; 925 TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
909 } 926 }
910} 927}
@@ -913,6 +930,7 @@ void tcp_skb_mark_lost_uncond_verify(struct tcp_sock *tp, struct sk_buff *skb)
913{ 930{
914 tcp_verify_retransmit_hint(tp, skb); 931 tcp_verify_retransmit_hint(tp, skb);
915 932
933 tcp_sum_lost(tp, skb);
916 if (!(TCP_SKB_CB(skb)->sacked & (TCPCB_LOST|TCPCB_SACKED_ACKED))) { 934 if (!(TCP_SKB_CB(skb)->sacked & (TCPCB_LOST|TCPCB_SACKED_ACKED))) {
917 tp->lost_out += tcp_skb_pcount(skb); 935 tp->lost_out += tcp_skb_pcount(skb);
918 TCP_SKB_CB(skb)->sacked |= TCPCB_LOST; 936 TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
@@ -1890,6 +1908,7 @@ void tcp_enter_loss(struct sock *sk)
1890 struct sk_buff *skb; 1908 struct sk_buff *skb;
1891 bool new_recovery = icsk->icsk_ca_state < TCP_CA_Recovery; 1909 bool new_recovery = icsk->icsk_ca_state < TCP_CA_Recovery;
1892 bool is_reneg; /* is receiver reneging on SACKs? */ 1910 bool is_reneg; /* is receiver reneging on SACKs? */
1911 bool mark_lost;
1893 1912
1894 /* Reduce ssthresh if it has not yet been made inside this window. */ 1913 /* Reduce ssthresh if it has not yet been made inside this window. */
1895 if (icsk->icsk_ca_state <= TCP_CA_Disorder || 1914 if (icsk->icsk_ca_state <= TCP_CA_Disorder ||
@@ -1923,8 +1942,12 @@ void tcp_enter_loss(struct sock *sk)
1923 if (skb == tcp_send_head(sk)) 1942 if (skb == tcp_send_head(sk))
1924 break; 1943 break;
1925 1944
1945 mark_lost = (!(TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED) ||
1946 is_reneg);
1947 if (mark_lost)
1948 tcp_sum_lost(tp, skb);
1926 TCP_SKB_CB(skb)->sacked &= (~TCPCB_TAGBITS)|TCPCB_SACKED_ACKED; 1949 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) {
1928 TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_ACKED; 1951 TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_ACKED;
1929 TCP_SKB_CB(skb)->sacked |= TCPCB_LOST; 1952 TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
1930 tp->lost_out += tcp_skb_pcount(skb); 1953 tp->lost_out += tcp_skb_pcount(skb);