mirror of https://gitee.com/openkylin/linux.git
Merge branch 'tcp-loss-probe'
Yuchung Cheng says: ==================== minor tail loss probe improvements This patch series enhance the tail loss probe (TLP) on some error conditions. When TLP fails to send a probe, it will no longer extend the RTO. When it fails to send a new packet because of receiver window limit, it'll try to retransmit the last packet. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
5bbbcc0073
|
@ -2149,7 +2149,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
|
||||||
tcp_cwnd_validate(sk, is_cwnd_limited);
|
tcp_cwnd_validate(sk, is_cwnd_limited);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return (push_one == 2) || (!tp->packets_out && tcp_send_head(sk));
|
return !tp->packets_out && tcp_send_head(sk);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tcp_schedule_loss_probe(struct sock *sk)
|
bool tcp_schedule_loss_probe(struct sock *sk)
|
||||||
|
@ -2226,7 +2226,7 @@ static bool skb_still_in_host_queue(const struct sock *sk,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* When probe timeout (PTO) fires, send a new segment if one exists, else
|
/* When probe timeout (PTO) fires, try send a new segment if possible, else
|
||||||
* retransmit the last segment.
|
* retransmit the last segment.
|
||||||
*/
|
*/
|
||||||
void tcp_send_loss_probe(struct sock *sk)
|
void tcp_send_loss_probe(struct sock *sk)
|
||||||
|
@ -2235,11 +2235,19 @@ void tcp_send_loss_probe(struct sock *sk)
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
int pcount;
|
int pcount;
|
||||||
int mss = tcp_current_mss(sk);
|
int mss = tcp_current_mss(sk);
|
||||||
int err = -1;
|
|
||||||
|
|
||||||
if (tcp_send_head(sk)) {
|
skb = tcp_send_head(sk);
|
||||||
err = tcp_write_xmit(sk, mss, TCP_NAGLE_OFF, 2, GFP_ATOMIC);
|
if (skb) {
|
||||||
goto rearm_timer;
|
if (tcp_snd_wnd_test(tp, skb, mss)) {
|
||||||
|
pcount = tp->packets_out;
|
||||||
|
tcp_write_xmit(sk, mss, TCP_NAGLE_OFF, 2, GFP_ATOMIC);
|
||||||
|
if (tp->packets_out > pcount)
|
||||||
|
goto probe_sent;
|
||||||
|
goto rearm_timer;
|
||||||
|
}
|
||||||
|
skb = tcp_write_queue_prev(sk, skb);
|
||||||
|
} else {
|
||||||
|
skb = tcp_write_queue_tail(sk);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* At most one outstanding TLP retransmission. */
|
/* At most one outstanding TLP retransmission. */
|
||||||
|
@ -2247,7 +2255,6 @@ void tcp_send_loss_probe(struct sock *sk)
|
||||||
goto rearm_timer;
|
goto rearm_timer;
|
||||||
|
|
||||||
/* Retransmit last segment. */
|
/* Retransmit last segment. */
|
||||||
skb = tcp_write_queue_tail(sk);
|
|
||||||
if (WARN_ON(!skb))
|
if (WARN_ON(!skb))
|
||||||
goto rearm_timer;
|
goto rearm_timer;
|
||||||
|
|
||||||
|
@ -2262,26 +2269,24 @@ void tcp_send_loss_probe(struct sock *sk)
|
||||||
if (unlikely(tcp_fragment(sk, skb, (pcount - 1) * mss, mss,
|
if (unlikely(tcp_fragment(sk, skb, (pcount - 1) * mss, mss,
|
||||||
GFP_ATOMIC)))
|
GFP_ATOMIC)))
|
||||||
goto rearm_timer;
|
goto rearm_timer;
|
||||||
skb = tcp_write_queue_tail(sk);
|
skb = tcp_write_queue_next(sk, skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WARN_ON(!skb || !tcp_skb_pcount(skb)))
|
if (WARN_ON(!skb || !tcp_skb_pcount(skb)))
|
||||||
goto rearm_timer;
|
goto rearm_timer;
|
||||||
|
|
||||||
err = __tcp_retransmit_skb(sk, skb);
|
if (__tcp_retransmit_skb(sk, skb))
|
||||||
|
goto rearm_timer;
|
||||||
|
|
||||||
/* Record snd_nxt for loss detection. */
|
/* Record snd_nxt for loss detection. */
|
||||||
if (likely(!err))
|
tp->tlp_high_seq = tp->snd_nxt;
|
||||||
tp->tlp_high_seq = tp->snd_nxt;
|
|
||||||
|
|
||||||
|
probe_sent:
|
||||||
|
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPLOSSPROBES);
|
||||||
|
/* Reset s.t. tcp_rearm_rto will restart timer from now */
|
||||||
|
inet_csk(sk)->icsk_pending = 0;
|
||||||
rearm_timer:
|
rearm_timer:
|
||||||
inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
|
tcp_rearm_rto(sk);
|
||||||
inet_csk(sk)->icsk_rto,
|
|
||||||
TCP_RTO_MAX);
|
|
||||||
|
|
||||||
if (likely(!err))
|
|
||||||
NET_INC_STATS_BH(sock_net(sk),
|
|
||||||
LINUX_MIB_TCPLOSSPROBES);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Push out any pending frames which were held back due to
|
/* Push out any pending frames which were held back due to
|
||||||
|
|
Loading…
Reference in New Issue