aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_input.c
diff options
context:
space:
mode:
authorYuchung Cheng <ycheng@google.com>2017-11-08 16:01:26 -0500
committerDavid S. Miller <davem@davemloft.net>2017-11-11 04:53:16 -0500
commit713bafea92920103cd3d361657406cf04d0e22dd (patch)
tree505a887887bb48dc443388b0078ad176ff6edb5b /net/ipv4/tcp_input.c
parente4ec1384132ead18e972f1180e958aa0b69abd11 (diff)
tcp: retire FACK loss detection
FACK loss detection has been disabled by default and the successor RACK subsumed FACK and can handle reordering better. This patch removes FACK to simplify TCP loss recovery. Signed-off-by: Yuchung Cheng <ycheng@google.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Neal Cardwell <ncardwell@google.com> Reviewed-by: Soheil Hassas Yeganeh <soheil@google.com> Reviewed-by: Priyaranjan Jha <priyarjha@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.c53
1 files changed, 7 insertions, 46 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 9ceaa1fdc3ab..487e181cff86 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -842,18 +842,6 @@ __u32 tcp_init_cwnd(const struct tcp_sock *tp, const struct dst_entry *dst)
842 return min_t(__u32, cwnd, tp->snd_cwnd_clamp); 842 return min_t(__u32, cwnd, tp->snd_cwnd_clamp);
843} 843}
844 844
845/*
846 * Packet counting of FACK is based on in-order assumptions, therefore TCP
847 * disables it when reordering is detected
848 */
849void tcp_disable_fack(struct tcp_sock *tp)
850{
851 /* RFC3517 uses different metric in lost marker => reset on change */
852 if (tcp_is_fack(tp))
853 tp->lost_skb_hint = NULL;
854 tp->rx_opt.sack_ok &= ~TCP_FACK_ENABLED;
855}
856
857/* Take a notice that peer is sending D-SACKs */ 845/* Take a notice that peer is sending D-SACKs */
858static void tcp_dsack_seen(struct tcp_sock *tp) 846static void tcp_dsack_seen(struct tcp_sock *tp)
859{ 847{
@@ -881,7 +869,6 @@ static void tcp_update_reordering(struct sock *sk, const int metric,
881 tp->sacked_out, 869 tp->sacked_out,
882 tp->undo_marker ? tp->undo_retrans : 0); 870 tp->undo_marker ? tp->undo_retrans : 0);
883#endif 871#endif
884 tcp_disable_fack(tp);
885 } 872 }
886 873
887 tp->rack.reord = 1; 874 tp->rack.reord = 1;
@@ -891,8 +878,6 @@ static void tcp_update_reordering(struct sock *sk, const int metric,
891 mib_idx = LINUX_MIB_TCPTSREORDER; 878 mib_idx = LINUX_MIB_TCPTSREORDER;
892 else if (tcp_is_reno(tp)) 879 else if (tcp_is_reno(tp))
893 mib_idx = LINUX_MIB_TCPRENOREORDER; 880 mib_idx = LINUX_MIB_TCPRENOREORDER;
894 else if (tcp_is_fack(tp))
895 mib_idx = LINUX_MIB_TCPFACKREORDER;
896 else 881 else
897 mib_idx = LINUX_MIB_TCPSACKREORDER; 882 mib_idx = LINUX_MIB_TCPSACKREORDER;
898 883
@@ -970,7 +955,6 @@ void tcp_skb_mark_lost_uncond_verify(struct tcp_sock *tp, struct sk_buff *skb)
970 * 3. Loss detection event of two flavors: 955 * 3. Loss detection event of two flavors:
971 * A. Scoreboard estimator decided the packet is lost. 956 * A. Scoreboard estimator decided the packet is lost.
972 * A'. Reno "three dupacks" marks head of queue lost. 957 * A'. Reno "three dupacks" marks head of queue lost.
973 * A''. Its FACK modification, head until snd.fack is lost.
974 * B. SACK arrives sacking SND.NXT at the moment, when the 958 * B. SACK arrives sacking SND.NXT at the moment, when the
975 * segment was retransmitted. 959 * segment was retransmitted.
976 * 4. D-SACK added new rule: D-SACK changes any tag to S. 960 * 4. D-SACK added new rule: D-SACK changes any tag to S.
@@ -1248,7 +1232,7 @@ static u8 tcp_sacktag_one(struct sock *sk,
1248 fack_count += pcount; 1232 fack_count += pcount;
1249 1233
1250 /* Lost marker hint past SACKed? Tweak RFC3517 cnt */ 1234 /* Lost marker hint past SACKed? Tweak RFC3517 cnt */
1251 if (!tcp_is_fack(tp) && tp->lost_skb_hint && 1235 if (tp->lost_skb_hint &&
1252 before(start_seq, TCP_SKB_CB(tp->lost_skb_hint)->seq)) 1236 before(start_seq, TCP_SKB_CB(tp->lost_skb_hint)->seq))
1253 tp->lost_cnt_hint += pcount; 1237 tp->lost_cnt_hint += pcount;
1254 1238
@@ -2051,10 +2035,6 @@ static inline int tcp_fackets_out(const struct tcp_sock *tp)
2051 * counter when SACK is enabled (without SACK, sacked_out is used for 2035 * counter when SACK is enabled (without SACK, sacked_out is used for
2052 * that purpose). 2036 * that purpose).
2053 * 2037 *
2054 * Instead, with FACK TCP uses fackets_out that includes both SACKed
2055 * segments up to the highest received SACK block so far and holes in
2056 * between them.
2057 *
2058 * With reordering, holes may still be in flight, so RFC3517 recovery 2038 * With reordering, holes may still be in flight, so RFC3517 recovery
2059 * uses pure sacked_out (total number of SACKed segments) even though 2039 * uses pure sacked_out (total number of SACKed segments) even though
2060 * it violates the RFC that uses duplicate ACKs, often these are equal 2040 * it violates the RFC that uses duplicate ACKs, often these are equal
@@ -2064,10 +2044,10 @@ static inline int tcp_fackets_out(const struct tcp_sock *tp)
2064 */ 2044 */
2065static inline int tcp_dupack_heuristics(const struct tcp_sock *tp) 2045static inline int tcp_dupack_heuristics(const struct tcp_sock *tp)
2066{ 2046{
2067 return tcp_is_fack(tp) ? tp->fackets_out : tp->sacked_out + 1; 2047 return tp->sacked_out + 1;
2068} 2048}
2069 2049
2070/* Linux NewReno/SACK/FACK/ECN state machine. 2050/* Linux NewReno/SACK/ECN state machine.
2071 * -------------------------------------- 2051 * --------------------------------------
2072 * 2052 *
2073 * "Open" Normal state, no dubious events, fast path. 2053 * "Open" Normal state, no dubious events, fast path.
@@ -2132,16 +2112,6 @@ static inline int tcp_dupack_heuristics(const struct tcp_sock *tp)
2132 * dynamically measured and adjusted. This is implemented in 2112 * dynamically measured and adjusted. This is implemented in
2133 * tcp_rack_mark_lost. 2113 * tcp_rack_mark_lost.
2134 * 2114 *
2135 * FACK (Disabled by default. Subsumbed by RACK):
2136 * It is the simplest heuristics. As soon as we decided
2137 * that something is lost, we decide that _all_ not SACKed
2138 * packets until the most forward SACK are lost. I.e.
2139 * lost_out = fackets_out - sacked_out and left_out = fackets_out.
2140 * It is absolutely correct estimate, if network does not reorder
2141 * packets. And it loses any connection to reality when reordering
2142 * takes place. We use FACK by default until reordering
2143 * is suspected on the path to this destination.
2144 *
2145 * If the receiver does not support SACK: 2115 * If the receiver does not support SACK:
2146 * 2116 *
2147 * NewReno (RFC6582): in Recovery we assume that one segment 2117 * NewReno (RFC6582): in Recovery we assume that one segment
@@ -2190,7 +2160,7 @@ static bool tcp_time_to_recover(struct sock *sk, int flag)
2190} 2160}
2191 2161
2192/* Detect loss in event "A" above by marking head of queue up as lost. 2162/* Detect loss in event "A" above by marking head of queue up as lost.
2193 * For FACK or non-SACK(Reno) senders, the first "packets" number of segments 2163 * For non-SACK(Reno) senders, the first "packets" number of segments
2194 * are considered lost. For RFC3517 SACK, a segment is considered lost if it 2164 * are considered lost. For RFC3517 SACK, a segment is considered lost if it
2195 * has at least tp->reordering SACKed seqments above it; "packets" refers to 2165 * has at least tp->reordering SACKed seqments above it; "packets" refers to
2196 * the maximum SACKed segments to pass before reaching this limit. 2166 * the maximum SACKed segments to pass before reaching this limit.
@@ -2226,12 +2196,12 @@ static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head)
2226 break; 2196 break;
2227 2197
2228 oldcnt = cnt; 2198 oldcnt = cnt;
2229 if (tcp_is_fack(tp) || tcp_is_reno(tp) || 2199 if (tcp_is_reno(tp) ||
2230 (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED)) 2200 (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED))
2231 cnt += tcp_skb_pcount(skb); 2201 cnt += tcp_skb_pcount(skb);
2232 2202
2233 if (cnt > packets) { 2203 if (cnt > packets) {
2234 if ((tcp_is_sack(tp) && !tcp_is_fack(tp)) || 2204 if (tcp_is_sack(tp) ||
2235 (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED) || 2205 (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED) ||
2236 (oldcnt >= packets)) 2206 (oldcnt >= packets))
2237 break; 2207 break;
@@ -2262,11 +2232,6 @@ static void tcp_update_scoreboard(struct sock *sk, int fast_rexmit)
2262 2232
2263 if (tcp_is_reno(tp)) { 2233 if (tcp_is_reno(tp)) {
2264 tcp_mark_head_lost(sk, 1, 1); 2234 tcp_mark_head_lost(sk, 1, 1);
2265 } else if (tcp_is_fack(tp)) {
2266 int lost = tp->fackets_out - tp->reordering;
2267 if (lost <= 0)
2268 lost = 1;
2269 tcp_mark_head_lost(sk, lost, 0);
2270 } else { 2235 } else {
2271 int sacked_upto = tp->sacked_out - tp->reordering; 2236 int sacked_upto = tp->sacked_out - tp->reordering;
2272 if (sacked_upto >= 0) 2237 if (sacked_upto >= 0)
@@ -3199,8 +3164,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets,
3199 if (reord < prior_fackets && reord <= tp->fackets_out) 3164 if (reord < prior_fackets && reord <= tp->fackets_out)
3200 tcp_update_reordering(sk, tp->fackets_out - reord, 0); 3165 tcp_update_reordering(sk, tp->fackets_out - reord, 0);
3201 3166
3202 delta = tcp_is_fack(tp) ? pkts_acked : 3167 delta = prior_sacked - tp->sacked_out;
3203 prior_sacked - tp->sacked_out;
3204 tp->lost_cnt_hint -= min(tp->lost_cnt_hint, delta); 3168 tp->lost_cnt_hint -= min(tp->lost_cnt_hint, delta);
3205 } 3169 }
3206 3170
@@ -5708,9 +5672,6 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
5708 tp->tcp_header_len = sizeof(struct tcphdr); 5672 tp->tcp_header_len = sizeof(struct tcphdr);
5709 } 5673 }
5710 5674
5711 if (tcp_is_sack(tp) && sock_net(sk)->ipv4.sysctl_tcp_fack)
5712 tcp_enable_fack(tp);
5713
5714 tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); 5675 tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
5715 tcp_initialize_rcv_mss(sk); 5676 tcp_initialize_rcv_mss(sk);
5716 5677