Commit f31f54db authored by David S. Miller's avatar David S. Miller

Merge branch 'FACK-loss-recovery-remove'

Yuchung Cheng says:

====================
remove FACK loss recovery

This patch set removes the forward-acknowledgment (FACK)
packet-based loss and reordering detection. This simplifies TCP
loss recovery since the SACK scoreboard no longer needs to track
the number of pending packets under highest SACKed sequence. FACK
is subsumed by the time-based RACK loss detection which is more
robust under reordering and second order losses.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents e4ec1384 737ff314
...@@ -289,8 +289,7 @@ tcp_ecn_fallback - BOOLEAN ...@@ -289,8 +289,7 @@ tcp_ecn_fallback - BOOLEAN
Default: 1 (fallback enabled) Default: 1 (fallback enabled)
tcp_fack - BOOLEAN tcp_fack - BOOLEAN
Enable FACK congestion avoidance and fast retransmission. This is a legacy option, it has no effect anymore.
The value is not used, if tcp_sack is not enabled.
tcp_fin_timeout - INTEGER tcp_fin_timeout - INTEGER
The length of time an orphaned (no longer referenced by any The length of time an orphaned (no longer referenced by any
......
...@@ -85,7 +85,6 @@ struct tcp_sack_block { ...@@ -85,7 +85,6 @@ struct tcp_sack_block {
/*These are used to set the sack_ok field in struct tcp_options_received */ /*These are used to set the sack_ok field in struct tcp_options_received */
#define TCP_SACK_SEEN (1 << 0) /*1 = peer is SACK capable, */ #define TCP_SACK_SEEN (1 << 0) /*1 = peer is SACK capable, */
#define TCP_FACK_ENABLED (1 << 1) /*1 = FACK is enabled locally*/
#define TCP_DSACK_SEEN (1 << 2) /*1 = DSACK was received from peer*/ #define TCP_DSACK_SEEN (1 << 2) /*1 = DSACK was received from peer*/
struct tcp_options_received { struct tcp_options_received {
...@@ -294,7 +293,6 @@ struct tcp_sock { ...@@ -294,7 +293,6 @@ struct tcp_sock {
u32 pushed_seq; /* Last pushed seq, required to talk to windows */ u32 pushed_seq; /* Last pushed seq, required to talk to windows */
u32 lost_out; /* Lost packets */ u32 lost_out; /* Lost packets */
u32 sacked_out; /* SACK'd packets */ u32 sacked_out; /* SACK'd packets */
u32 fackets_out; /* FACK'd packets */
struct hrtimer pacing_timer; struct hrtimer pacing_timer;
......
...@@ -384,7 +384,6 @@ void tcp_update_metrics(struct sock *sk); ...@@ -384,7 +384,6 @@ void tcp_update_metrics(struct sock *sk);
void tcp_init_metrics(struct sock *sk); void tcp_init_metrics(struct sock *sk);
void tcp_metrics_init(void); void tcp_metrics_init(void);
bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst); bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst);
void tcp_disable_fack(struct tcp_sock *tp);
void tcp_close(struct sock *sk, long timeout); void tcp_close(struct sock *sk, long timeout);
void tcp_init_sock(struct sock *sk); void tcp_init_sock(struct sock *sk);
void tcp_init_transfer(struct sock *sk, int bpf_op); void tcp_init_transfer(struct sock *sk, int bpf_op);
...@@ -776,7 +775,7 @@ struct tcp_skb_cb { ...@@ -776,7 +775,7 @@ struct tcp_skb_cb {
}; };
__u8 tcp_flags; /* TCP header flags. (tcp[13]) */ __u8 tcp_flags; /* TCP header flags. (tcp[13]) */
__u8 sacked; /* State flags for SACK/FACK. */ __u8 sacked; /* State flags for SACK. */
#define TCPCB_SACKED_ACKED 0x01 /* SKB ACK'd by a SACK block */ #define TCPCB_SACKED_ACKED 0x01 /* SKB ACK'd by a SACK block */
#define TCPCB_SACKED_RETRANS 0x02 /* SKB retransmitted */ #define TCPCB_SACKED_RETRANS 0x02 /* SKB retransmitted */
#define TCPCB_LOST 0x04 /* SKB is lost */ #define TCPCB_LOST 0x04 /* SKB is lost */
...@@ -1066,7 +1065,6 @@ void tcp_rate_check_app_limited(struct sock *sk); ...@@ -1066,7 +1065,6 @@ void tcp_rate_check_app_limited(struct sock *sk);
* *
* tcp_is_sack - SACK enabled * tcp_is_sack - SACK enabled
* tcp_is_reno - No SACK * tcp_is_reno - No SACK
* tcp_is_fack - FACK enabled, implies SACK enabled
*/ */
static inline int tcp_is_sack(const struct tcp_sock *tp) static inline int tcp_is_sack(const struct tcp_sock *tp)
{ {
...@@ -1078,16 +1076,6 @@ static inline bool tcp_is_reno(const struct tcp_sock *tp) ...@@ -1078,16 +1076,6 @@ static inline bool tcp_is_reno(const struct tcp_sock *tp)
return !tcp_is_sack(tp); return !tcp_is_sack(tp);
} }
static inline bool tcp_is_fack(const struct tcp_sock *tp)
{
return tp->rx_opt.sack_ok & TCP_FACK_ENABLED;
}
static inline void tcp_enable_fack(struct tcp_sock *tp)
{
tp->rx_opt.sack_ok |= TCP_FACK_ENABLED;
}
static inline unsigned int tcp_left_out(const struct tcp_sock *tp) static inline unsigned int tcp_left_out(const struct tcp_sock *tp)
{ {
return tp->sacked_out + tp->lost_out; return tp->sacked_out + tp->lost_out;
......
...@@ -191,7 +191,6 @@ enum ...@@ -191,7 +191,6 @@ enum
LINUX_MIB_TCPRENORECOVERY, /* TCPRenoRecovery */ LINUX_MIB_TCPRENORECOVERY, /* TCPRenoRecovery */
LINUX_MIB_TCPSACKRECOVERY, /* TCPSackRecovery */ LINUX_MIB_TCPSACKRECOVERY, /* TCPSackRecovery */
LINUX_MIB_TCPSACKRENEGING, /* TCPSACKReneging */ LINUX_MIB_TCPSACKRENEGING, /* TCPSACKReneging */
LINUX_MIB_TCPFACKREORDER, /* TCPFACKReorder */
LINUX_MIB_TCPSACKREORDER, /* TCPSACKReorder */ LINUX_MIB_TCPSACKREORDER, /* TCPSACKReorder */
LINUX_MIB_TCPRENOREORDER, /* TCPRenoReorder */ LINUX_MIB_TCPRENOREORDER, /* TCPRenoReorder */
LINUX_MIB_TCPTSREORDER, /* TCPTSReorder */ LINUX_MIB_TCPTSREORDER, /* TCPTSReorder */
......
...@@ -212,7 +212,6 @@ static const struct snmp_mib snmp4_net_list[] = { ...@@ -212,7 +212,6 @@ static const struct snmp_mib snmp4_net_list[] = {
SNMP_MIB_ITEM("TCPRenoRecovery", LINUX_MIB_TCPRENORECOVERY), SNMP_MIB_ITEM("TCPRenoRecovery", LINUX_MIB_TCPRENORECOVERY),
SNMP_MIB_ITEM("TCPSackRecovery", LINUX_MIB_TCPSACKRECOVERY), SNMP_MIB_ITEM("TCPSackRecovery", LINUX_MIB_TCPSACKRECOVERY),
SNMP_MIB_ITEM("TCPSACKReneging", LINUX_MIB_TCPSACKRENEGING), SNMP_MIB_ITEM("TCPSACKReneging", LINUX_MIB_TCPSACKRENEGING),
SNMP_MIB_ITEM("TCPFACKReorder", LINUX_MIB_TCPFACKREORDER),
SNMP_MIB_ITEM("TCPSACKReorder", LINUX_MIB_TCPSACKREORDER), SNMP_MIB_ITEM("TCPSACKReorder", LINUX_MIB_TCPSACKREORDER),
SNMP_MIB_ITEM("TCPRenoReorder", LINUX_MIB_TCPRENOREORDER), SNMP_MIB_ITEM("TCPRenoReorder", LINUX_MIB_TCPRENOREORDER),
SNMP_MIB_ITEM("TCPTSReorder", LINUX_MIB_TCPTSREORDER), SNMP_MIB_ITEM("TCPTSReorder", LINUX_MIB_TCPTSREORDER),
......
...@@ -2509,8 +2509,6 @@ static int tcp_repair_options_est(struct sock *sk, ...@@ -2509,8 +2509,6 @@ static int tcp_repair_options_est(struct sock *sk,
return -EINVAL; return -EINVAL;
tp->rx_opt.sack_ok |= TCP_SACK_SEEN; tp->rx_opt.sack_ok |= TCP_SACK_SEEN;
if (sock_net(sk)->ipv4.sysctl_tcp_fack)
tcp_enable_fack(tp);
break; break;
case TCPOPT_TIMESTAMP: case TCPOPT_TIMESTAMP:
if (opt.opt_val != 0) if (opt.opt_val != 0)
...@@ -2979,7 +2977,6 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) ...@@ -2979,7 +2977,6 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info)
info->tcpi_lost = tp->lost_out; info->tcpi_lost = tp->lost_out;
info->tcpi_retrans = tp->retrans_out; info->tcpi_retrans = tp->retrans_out;
info->tcpi_fackets = tp->fackets_out;
now = tcp_jiffies32; now = tcp_jiffies32;
info->tcpi_last_data_sent = jiffies_to_msecs(now - tp->lsndtime); info->tcpi_last_data_sent = jiffies_to_msecs(now - tp->lsndtime);
......
This diff is collapsed.
...@@ -470,10 +470,8 @@ void tcp_init_metrics(struct sock *sk) ...@@ -470,10 +470,8 @@ void tcp_init_metrics(struct sock *sk)
tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
} }
val = tcp_metric_get(tm, TCP_METRIC_REORDERING); val = tcp_metric_get(tm, TCP_METRIC_REORDERING);
if (val && tp->reordering != val) { if (val && tp->reordering != val)
tcp_disable_fack(tp);
tp->reordering = val; tp->reordering = val;
}
crtt = tcp_metric_get(tm, TCP_METRIC_RTT); crtt = tcp_metric_get(tm, TCP_METRIC_RTT);
rcu_read_unlock(); rcu_read_unlock();
......
...@@ -475,7 +475,6 @@ struct sock *tcp_create_openreq_child(const struct sock *sk, ...@@ -475,7 +475,6 @@ struct sock *tcp_create_openreq_child(const struct sock *sk,
newtp->packets_out = 0; newtp->packets_out = 0;
newtp->retrans_out = 0; newtp->retrans_out = 0;
newtp->sacked_out = 0; newtp->sacked_out = 0;
newtp->fackets_out = 0;
newtp->snd_ssthresh = TCP_INFINITE_SSTHRESH; newtp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
newtp->tlp_high_seq = 0; newtp->tlp_high_seq = 0;
newtp->lsndtime = tcp_jiffies32; newtp->lsndtime = tcp_jiffies32;
...@@ -509,10 +508,7 @@ struct sock *tcp_create_openreq_child(const struct sock *sk, ...@@ -509,10 +508,7 @@ struct sock *tcp_create_openreq_child(const struct sock *sk,
keepalive_time_when(newtp)); keepalive_time_when(newtp));
newtp->rx_opt.tstamp_ok = ireq->tstamp_ok; newtp->rx_opt.tstamp_ok = ireq->tstamp_ok;
if ((newtp->rx_opt.sack_ok = ireq->sack_ok) != 0) { newtp->rx_opt.sack_ok = ireq->sack_ok;
if (sock_net(sk)->ipv4.sysctl_tcp_fack)
tcp_enable_fack(newtp);
}
newtp->window_clamp = req->rsk_window_clamp; newtp->window_clamp = req->rsk_window_clamp;
newtp->rcv_ssthresh = req->rsk_rcv_wnd; newtp->rcv_ssthresh = req->rsk_rcv_wnd;
newtp->rcv_wnd = req->rsk_rcv_wnd; newtp->rcv_wnd = req->rsk_rcv_wnd;
......
...@@ -1218,21 +1218,6 @@ static void tcp_set_skb_tso_segs(struct sk_buff *skb, unsigned int mss_now) ...@@ -1218,21 +1218,6 @@ static void tcp_set_skb_tso_segs(struct sk_buff *skb, unsigned int mss_now)
} }
} }
/* When a modification to fackets out becomes necessary, we need to check
* skb is counted to fackets_out or not.
*/
static void tcp_adjust_fackets_out(struct sock *sk, const struct sk_buff *skb,
int decr)
{
struct tcp_sock *tp = tcp_sk(sk);
if (!tp->sacked_out || tcp_is_reno(tp))
return;
if (after(tcp_highest_sack_seq(tp), TCP_SKB_CB(skb)->seq))
tp->fackets_out -= decr;
}
/* Pcount in the middle of the write queue got changed, we need to do various /* Pcount in the middle of the write queue got changed, we need to do various
* tweaks to fix counters * tweaks to fix counters
*/ */
...@@ -1253,11 +1238,9 @@ static void tcp_adjust_pcount(struct sock *sk, const struct sk_buff *skb, int de ...@@ -1253,11 +1238,9 @@ static void tcp_adjust_pcount(struct sock *sk, const struct sk_buff *skb, int de
if (tcp_is_reno(tp) && decr > 0) if (tcp_is_reno(tp) && decr > 0)
tp->sacked_out -= min_t(u32, tp->sacked_out, decr); tp->sacked_out -= min_t(u32, tp->sacked_out, decr);
tcp_adjust_fackets_out(sk, skb, decr);
if (tp->lost_skb_hint && if (tp->lost_skb_hint &&
before(TCP_SKB_CB(skb)->seq, TCP_SKB_CB(tp->lost_skb_hint)->seq) && before(TCP_SKB_CB(skb)->seq, TCP_SKB_CB(tp->lost_skb_hint)->seq) &&
(tcp_is_fack(tp) || (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED))) (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED))
tp->lost_cnt_hint -= decr; tp->lost_cnt_hint -= decr;
tcp_verify_left_out(tp); tcp_verify_left_out(tp);
...@@ -2961,9 +2944,6 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs) ...@@ -2961,9 +2944,6 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs)
* retransmitted data is acknowledged. It tries to continue * retransmitted data is acknowledged. It tries to continue
* resending the rest of the retransmit queue, until either * resending the rest of the retransmit queue, until either
* we've sent it all or the congestion window limit is reached. * we've sent it all or the congestion window limit is reached.
* If doing SACK, the first ACK which comes back for a timeout
* based retransmit packet might feed us FACK information again.
* If so, we use it to avoid unnecessarily retransmissions.
*/ */
void tcp_xmit_retransmit_queue(struct sock *sk) void tcp_xmit_retransmit_queue(struct sock *sk)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment