aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_input.c
diff options
context:
space:
mode:
authorYuchung Cheng <ycheng@google.com>2017-01-13 01:11:32 -0500
committerDavid S. Miller <davem@davemloft.net>2017-01-13 22:37:16 -0500
commitdeed7be78f512d003c6290da0a781479b31b3d74 (patch)
treeac478434d723eb690fa62943f262c251d92a538c /net/ipv4/tcp_input.c
parente636f8b0104d6622aaaed6aa5ef17dfbf165bc51 (diff)
tcp: record most recent RTT in RACK loss detection
Record the most recent RTT in RACK. It is often identical to the "ca_rtt_us" values in tcp_clean_rtx_queue. But when the packet has been retransmitted, RACK choses to believe the ACK is for the (latest) retransmitted packet if the RTT is over minimum RTT. This requires passing the arrival time of the most recent ACK to RACK routines. The timestamp is now recorded in the "ack_time" in tcp_sacktag_state during the ACK processing. This patch does not change the RACK algorithm itself. It only adds the RTT variable to prepare the next main patch. Signed-off-by: Yuchung Cheng <ycheng@google.com> Signed-off-by: Neal Cardwell <ncardwell@google.com> Acked-by: Eric Dumazet <edumazet@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.c36
1 files changed, 22 insertions, 14 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index bb24b93e64bc..8ccd171999bf 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1135,6 +1135,7 @@ struct tcp_sacktag_state {
1135 */ 1135 */
1136 struct skb_mstamp first_sackt; 1136 struct skb_mstamp first_sackt;
1137 struct skb_mstamp last_sackt; 1137 struct skb_mstamp last_sackt;
1138 struct skb_mstamp ack_time; /* Timestamp when the S/ACK was received */
1138 struct rate_sample *rate; 1139 struct rate_sample *rate;
1139 int flag; 1140 int flag;
1140}; 1141};
@@ -1217,7 +1218,7 @@ static u8 tcp_sacktag_one(struct sock *sk,
1217 return sacked; 1218 return sacked;
1218 1219
1219 if (!(sacked & TCPCB_SACKED_ACKED)) { 1220 if (!(sacked & TCPCB_SACKED_ACKED)) {
1220 tcp_rack_advance(tp, xmit_time, sacked); 1221 tcp_rack_advance(tp, sacked, xmit_time, &state->ack_time);
1221 1222
1222 if (sacked & TCPCB_SACKED_RETRANS) { 1223 if (sacked & TCPCB_SACKED_RETRANS) {
1223 /* If the segment is not tagged as lost, 1224 /* If the segment is not tagged as lost,
@@ -2813,7 +2814,8 @@ static bool tcp_try_undo_partial(struct sock *sk, const int acked)
2813 * tcp_xmit_retransmit_queue(). 2814 * tcp_xmit_retransmit_queue().
2814 */ 2815 */
2815static void tcp_fastretrans_alert(struct sock *sk, const int acked, 2816static void tcp_fastretrans_alert(struct sock *sk, const int acked,
2816 bool is_dupack, int *ack_flag, int *rexmit) 2817 bool is_dupack, int *ack_flag, int *rexmit,
2818 const struct skb_mstamp *ack_time)
2817{ 2819{
2818 struct inet_connection_sock *icsk = inet_csk(sk); 2820 struct inet_connection_sock *icsk = inet_csk(sk);
2819 struct tcp_sock *tp = tcp_sk(sk); 2821 struct tcp_sock *tp = tcp_sk(sk);
@@ -2868,7 +2870,7 @@ static void tcp_fastretrans_alert(struct sock *sk, const int acked,
2868 if (sysctl_tcp_recovery & TCP_RACK_LOST_RETRANS) { 2870 if (sysctl_tcp_recovery & TCP_RACK_LOST_RETRANS) {
2869 u32 prior_retrans = tp->retrans_out; 2871 u32 prior_retrans = tp->retrans_out;
2870 2872
2871 tcp_rack_mark_lost(sk); 2873 tcp_rack_mark_lost(sk, ack_time);
2872 if (prior_retrans > tp->retrans_out) { 2874 if (prior_retrans > tp->retrans_out) {
2873 flag |= FLAG_LOST_RETRANS; 2875 flag |= FLAG_LOST_RETRANS;
2874 *ack_flag |= FLAG_LOST_RETRANS; 2876 *ack_flag |= FLAG_LOST_RETRANS;
@@ -3105,11 +3107,11 @@ static void tcp_ack_tstamp(struct sock *sk, struct sk_buff *skb,
3105 */ 3107 */
3106static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets, 3108static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets,
3107 u32 prior_snd_una, int *acked, 3109 u32 prior_snd_una, int *acked,
3108 struct tcp_sacktag_state *sack, 3110 struct tcp_sacktag_state *sack)
3109 struct skb_mstamp *now)
3110{ 3111{
3111 const struct inet_connection_sock *icsk = inet_csk(sk); 3112 const struct inet_connection_sock *icsk = inet_csk(sk);
3112 struct skb_mstamp first_ackt, last_ackt; 3113 struct skb_mstamp first_ackt, last_ackt;
3114 struct skb_mstamp *now = &sack->ack_time;
3113 struct tcp_sock *tp = tcp_sk(sk); 3115 struct tcp_sock *tp = tcp_sk(sk);
3114 u32 prior_sacked = tp->sacked_out; 3116 u32 prior_sacked = tp->sacked_out;
3115 u32 reord = tp->packets_out; 3117 u32 reord = tp->packets_out;
@@ -3169,7 +3171,9 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets,
3169 } else if (tcp_is_sack(tp)) { 3171 } else if (tcp_is_sack(tp)) {
3170 tp->delivered += acked_pcount; 3172 tp->delivered += acked_pcount;
3171 if (!tcp_skb_spurious_retrans(tp, skb)) 3173 if (!tcp_skb_spurious_retrans(tp, skb))
3172 tcp_rack_advance(tp, &skb->skb_mstamp, sacked); 3174 tcp_rack_advance(tp, sacked,
3175 &skb->skb_mstamp,
3176 &sack->ack_time);
3173 } 3177 }
3174 if (sacked & TCPCB_LOST) 3178 if (sacked & TCPCB_LOST)
3175 tp->lost_out -= acked_pcount; 3179 tp->lost_out -= acked_pcount;
@@ -3599,7 +3603,6 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
3599 u32 lost = tp->lost; 3603 u32 lost = tp->lost;
3600 int acked = 0; /* Number of packets newly acked */ 3604 int acked = 0; /* Number of packets newly acked */
3601 int rexmit = REXMIT_NONE; /* Flag to (re)transmit to recover losses */ 3605 int rexmit = REXMIT_NONE; /* Flag to (re)transmit to recover losses */
3602 struct skb_mstamp now;
3603 3606
3604 sack_state.first_sackt.v64 = 0; 3607 sack_state.first_sackt.v64 = 0;
3605 sack_state.rate = &rs; 3608 sack_state.rate = &rs;
@@ -3625,7 +3628,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
3625 if (after(ack, tp->snd_nxt)) 3628 if (after(ack, tp->snd_nxt))
3626 goto invalid_ack; 3629 goto invalid_ack;
3627 3630
3628 skb_mstamp_get(&now); 3631 skb_mstamp_get(&sack_state.ack_time);
3629 3632
3630 if (icsk->icsk_pending == ICSK_TIME_EARLY_RETRANS || 3633 if (icsk->icsk_pending == ICSK_TIME_EARLY_RETRANS ||
3631 icsk->icsk_pending == ICSK_TIME_LOSS_PROBE) 3634 icsk->icsk_pending == ICSK_TIME_LOSS_PROBE)
@@ -3693,11 +3696,12 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
3693 3696
3694 /* See if we can take anything off of the retransmit queue. */ 3697 /* See if we can take anything off of the retransmit queue. */
3695 flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una, &acked, 3698 flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una, &acked,
3696 &sack_state, &now); 3699 &sack_state);
3697 3700
3698 if (tcp_ack_is_dubious(sk, flag)) { 3701 if (tcp_ack_is_dubious(sk, flag)) {
3699 is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP)); 3702 is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP));
3700 tcp_fastretrans_alert(sk, acked, is_dupack, &flag, &rexmit); 3703 tcp_fastretrans_alert(sk, acked, is_dupack, &flag, &rexmit,
3704 &sack_state.ack_time);
3701 } 3705 }
3702 if (tp->tlp_high_seq) 3706 if (tp->tlp_high_seq)
3703 tcp_process_tlp_ack(sk, ack, flag); 3707 tcp_process_tlp_ack(sk, ack, flag);
@@ -3712,15 +3716,17 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
3712 tcp_schedule_loss_probe(sk); 3716 tcp_schedule_loss_probe(sk);
3713 delivered = tp->delivered - delivered; /* freshly ACKed or SACKed */ 3717 delivered = tp->delivered - delivered; /* freshly ACKed or SACKed */
3714 lost = tp->lost - lost; /* freshly marked lost */ 3718 lost = tp->lost - lost; /* freshly marked lost */
3715 tcp_rate_gen(sk, delivered, lost, &now, &rs); 3719 tcp_rate_gen(sk, delivered, lost, &sack_state.ack_time,
3716 tcp_cong_control(sk, ack, delivered, flag, &rs); 3720 sack_state.rate);
3721 tcp_cong_control(sk, ack, delivered, flag, sack_state.rate);
3717 tcp_xmit_recovery(sk, rexmit); 3722 tcp_xmit_recovery(sk, rexmit);
3718 return 1; 3723 return 1;
3719 3724
3720no_queue: 3725no_queue:
3721 /* If data was DSACKed, see if we can undo a cwnd reduction. */ 3726 /* If data was DSACKed, see if we can undo a cwnd reduction. */
3722 if (flag & FLAG_DSACKING_ACK) 3727 if (flag & FLAG_DSACKING_ACK)
3723 tcp_fastretrans_alert(sk, acked, is_dupack, &flag, &rexmit); 3728 tcp_fastretrans_alert(sk, acked, is_dupack, &flag, &rexmit,
3729 &sack_state.ack_time);
3724 /* If this ack opens up a zero window, clear backoff. It was 3730 /* If this ack opens up a zero window, clear backoff. It was
3725 * being used to time the probes, and is probably far higher than 3731 * being used to time the probes, and is probably far higher than
3726 * it needs to be for normal retransmission. 3732 * it needs to be for normal retransmission.
@@ -3741,9 +3747,11 @@ old_ack:
3741 * If data was DSACKed, see if we can undo a cwnd reduction. 3747 * If data was DSACKed, see if we can undo a cwnd reduction.
3742 */ 3748 */
3743 if (TCP_SKB_CB(skb)->sacked) { 3749 if (TCP_SKB_CB(skb)->sacked) {
3750 skb_mstamp_get(&sack_state.ack_time);
3744 flag |= tcp_sacktag_write_queue(sk, skb, prior_snd_una, 3751 flag |= tcp_sacktag_write_queue(sk, skb, prior_snd_una,
3745 &sack_state); 3752 &sack_state);
3746 tcp_fastretrans_alert(sk, acked, is_dupack, &flag, &rexmit); 3753 tcp_fastretrans_alert(sk, acked, is_dupack, &flag, &rexmit,
3754 &sack_state.ack_time);
3747 tcp_xmit_recovery(sk, rexmit); 3755 tcp_xmit_recovery(sk, rexmit);
3748 } 3756 }
3749 3757