diff options
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r-- | net/ipv4/tcp_input.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index bd18c252dee4..a06603912137 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -1711,18 +1711,23 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag) | |||
1711 | tcp_clear_retrans_hints_partial(tp); | 1711 | tcp_clear_retrans_hints_partial(tp); |
1712 | } | 1712 | } |
1713 | 1713 | ||
1714 | void tcp_clear_retrans(struct tcp_sock *tp) | 1714 | static void tcp_clear_retrans_partial(struct tcp_sock *tp) |
1715 | { | 1715 | { |
1716 | tp->retrans_out = 0; | 1716 | tp->retrans_out = 0; |
1717 | |||
1718 | tp->fackets_out = 0; | ||
1719 | tp->sacked_out = 0; | ||
1720 | tp->lost_out = 0; | 1717 | tp->lost_out = 0; |
1721 | 1718 | ||
1722 | tp->undo_marker = 0; | 1719 | tp->undo_marker = 0; |
1723 | tp->undo_retrans = 0; | 1720 | tp->undo_retrans = 0; |
1724 | } | 1721 | } |
1725 | 1722 | ||
1723 | void tcp_clear_retrans(struct tcp_sock *tp) | ||
1724 | { | ||
1725 | tcp_clear_retrans_partial(tp); | ||
1726 | |||
1727 | tp->fackets_out = 0; | ||
1728 | tp->sacked_out = 0; | ||
1729 | } | ||
1730 | |||
1726 | /* Enter Loss state. If "how" is not zero, forget all SACK information | 1731 | /* Enter Loss state. If "how" is not zero, forget all SACK information |
1727 | * and reset tags completely, otherwise preserve SACKs. If receiver | 1732 | * and reset tags completely, otherwise preserve SACKs. If receiver |
1728 | * dropped its ofo queue, we will know this due to reneging detection. | 1733 | * dropped its ofo queue, we will know this due to reneging detection. |
@@ -1732,7 +1737,6 @@ void tcp_enter_loss(struct sock *sk, int how) | |||
1732 | const struct inet_connection_sock *icsk = inet_csk(sk); | 1737 | const struct inet_connection_sock *icsk = inet_csk(sk); |
1733 | struct tcp_sock *tp = tcp_sk(sk); | 1738 | struct tcp_sock *tp = tcp_sk(sk); |
1734 | struct sk_buff *skb; | 1739 | struct sk_buff *skb; |
1735 | int cnt = 0; | ||
1736 | 1740 | ||
1737 | /* Reduce ssthresh if it has not yet been made inside this window. */ | 1741 | /* Reduce ssthresh if it has not yet been made inside this window. */ |
1738 | if (icsk->icsk_ca_state <= TCP_CA_Disorder || tp->snd_una == tp->high_seq || | 1742 | if (icsk->icsk_ca_state <= TCP_CA_Disorder || tp->snd_una == tp->high_seq || |
@@ -1746,7 +1750,10 @@ void tcp_enter_loss(struct sock *sk, int how) | |||
1746 | tp->snd_cwnd_stamp = tcp_time_stamp; | 1750 | tp->snd_cwnd_stamp = tcp_time_stamp; |
1747 | 1751 | ||
1748 | tp->bytes_acked = 0; | 1752 | tp->bytes_acked = 0; |
1749 | tcp_clear_retrans(tp); | 1753 | tcp_clear_retrans_partial(tp); |
1754 | |||
1755 | if (tcp_is_reno(tp)) | ||
1756 | tcp_reset_reno_sack(tp); | ||
1750 | 1757 | ||
1751 | if (!how) { | 1758 | if (!how) { |
1752 | /* Push undo marker, if it was plain RTO and nothing | 1759 | /* Push undo marker, if it was plain RTO and nothing |
@@ -1754,13 +1761,15 @@ void tcp_enter_loss(struct sock *sk, int how) | |||
1754 | tp->undo_marker = tp->snd_una; | 1761 | tp->undo_marker = tp->snd_una; |
1755 | tcp_clear_retrans_hints_partial(tp); | 1762 | tcp_clear_retrans_hints_partial(tp); |
1756 | } else { | 1763 | } else { |
1764 | tp->sacked_out = 0; | ||
1765 | tp->fackets_out = 0; | ||
1757 | tcp_clear_all_retrans_hints(tp); | 1766 | tcp_clear_all_retrans_hints(tp); |
1758 | } | 1767 | } |
1759 | 1768 | ||
1760 | tcp_for_write_queue(skb, sk) { | 1769 | tcp_for_write_queue(skb, sk) { |
1761 | if (skb == tcp_send_head(sk)) | 1770 | if (skb == tcp_send_head(sk)) |
1762 | break; | 1771 | break; |
1763 | cnt += tcp_skb_pcount(skb); | 1772 | |
1764 | if (TCP_SKB_CB(skb)->sacked&TCPCB_RETRANS) | 1773 | if (TCP_SKB_CB(skb)->sacked&TCPCB_RETRANS) |
1765 | tp->undo_marker = 0; | 1774 | tp->undo_marker = 0; |
1766 | TCP_SKB_CB(skb)->sacked &= (~TCPCB_TAGBITS)|TCPCB_SACKED_ACKED; | 1775 | TCP_SKB_CB(skb)->sacked &= (~TCPCB_TAGBITS)|TCPCB_SACKED_ACKED; |
@@ -1768,9 +1777,6 @@ void tcp_enter_loss(struct sock *sk, int how) | |||
1768 | TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_ACKED; | 1777 | TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_ACKED; |
1769 | TCP_SKB_CB(skb)->sacked |= TCPCB_LOST; | 1778 | TCP_SKB_CB(skb)->sacked |= TCPCB_LOST; |
1770 | tp->lost_out += tcp_skb_pcount(skb); | 1779 | tp->lost_out += tcp_skb_pcount(skb); |
1771 | } else { | ||
1772 | tp->sacked_out += tcp_skb_pcount(skb); | ||
1773 | tp->fackets_out = cnt; | ||
1774 | } | 1780 | } |
1775 | } | 1781 | } |
1776 | tcp_verify_left_out(tp); | 1782 | tcp_verify_left_out(tp); |