aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorIlpo Järvinen <ilpo.jarvinen@helsinki.fi>2007-09-20 14:37:19 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:52:12 -0400
commitb76892051cf1c04d95872838e70146f65e3b9d75 (patch)
tree475050b8e41eb317144465b1e2b9255fbad188b4 /net
parentc96fd3d461fa495400df24be3b3b66f0e0b152f9 (diff)
[TCP]: Avoid clearing sacktag hint in trivial situations
There's no reason to clear the sacktag skb hint when small part of the rexmit queue changes. Account changes (if any) instead when fragmenting/collapsing. RTO/FRTO do not touch SACKED_ACKED bits so no need to discard SACK tag hint at all. Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/tcp_input.c14
-rw-r--r--net/ipv4/tcp_output.c12
2 files changed, 16 insertions, 10 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 65b9f274a774..4c10d9cad20f 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1671,7 +1671,7 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag)
1671 tp->high_seq = tp->frto_highmark; 1671 tp->high_seq = tp->frto_highmark;
1672 TCP_ECN_queue_cwr(tp); 1672 TCP_ECN_queue_cwr(tp);
1673 1673
1674 tcp_clear_all_retrans_hints(tp); 1674 tcp_clear_retrans_hints_partial(tp);
1675} 1675}
1676 1676
1677void tcp_clear_retrans(struct tcp_sock *tp) 1677void tcp_clear_retrans(struct tcp_sock *tp)
@@ -1711,10 +1711,14 @@ void tcp_enter_loss(struct sock *sk, int how)
1711 tp->bytes_acked = 0; 1711 tp->bytes_acked = 0;
1712 tcp_clear_retrans(tp); 1712 tcp_clear_retrans(tp);
1713 1713
1714 /* Push undo marker, if it was plain RTO and nothing 1714 if (!how) {
1715 * was retransmitted. */ 1715 /* Push undo marker, if it was plain RTO and nothing
1716 if (!how) 1716 * was retransmitted. */
1717 tp->undo_marker = tp->snd_una; 1717 tp->undo_marker = tp->snd_una;
1718 tcp_clear_retrans_hints_partial(tp);
1719 } else {
1720 tcp_clear_all_retrans_hints(tp);
1721 }
1718 1722
1719 tcp_for_write_queue(skb, sk) { 1723 tcp_for_write_queue(skb, sk) {
1720 if (skb == tcp_send_head(sk)) 1724 if (skb == tcp_send_head(sk))
@@ -1741,8 +1745,6 @@ void tcp_enter_loss(struct sock *sk, int how)
1741 TCP_ECN_queue_cwr(tp); 1745 TCP_ECN_queue_cwr(tp);
1742 /* Abort FRTO algorithm if one is in progress */ 1746 /* Abort FRTO algorithm if one is in progress */
1743 tp->frto_counter = 0; 1747 tp->frto_counter = 0;
1744
1745 tcp_clear_all_retrans_hints(tp);
1746} 1748}
1747 1749
1748static int tcp_check_sack_reneging(struct sock *sk) 1750static int tcp_check_sack_reneging(struct sock *sk)
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index f46d24b8410f..cbb83acd830a 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -687,7 +687,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss
687 687
688 BUG_ON(len > skb->len); 688 BUG_ON(len > skb->len);
689 689
690 tcp_clear_all_retrans_hints(tp); 690 tcp_clear_retrans_hints_partial(tp);
691 nsize = skb_headlen(skb) - len; 691 nsize = skb_headlen(skb) - len;
692 if (nsize < 0) 692 if (nsize < 0)
693 nsize = 0; 693 nsize = 0;
@@ -1718,9 +1718,6 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb, int m
1718 BUG_ON(tcp_skb_pcount(skb) != 1 || 1718 BUG_ON(tcp_skb_pcount(skb) != 1 ||
1719 tcp_skb_pcount(next_skb) != 1); 1719 tcp_skb_pcount(next_skb) != 1);
1720 1720
1721 /* changing transmit queue under us so clear hints */
1722 tcp_clear_all_retrans_hints(tp);
1723
1724 /* Ok. We will be able to collapse the packet. */ 1721 /* Ok. We will be able to collapse the packet. */
1725 tcp_unlink_write_queue(next_skb, sk); 1722 tcp_unlink_write_queue(next_skb, sk);
1726 1723
@@ -1759,6 +1756,13 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb, int m
1759 1756
1760 tcp_adjust_fackets_out(tp, skb, tcp_skb_pcount(next_skb)); 1757 tcp_adjust_fackets_out(tp, skb, tcp_skb_pcount(next_skb));
1761 tp->packets_out -= tcp_skb_pcount(next_skb); 1758 tp->packets_out -= tcp_skb_pcount(next_skb);
1759
1760 /* changed transmit queue under us so clear hints */
1761 tcp_clear_retrans_hints_partial(tp);
1762 /* manually tune sacktag skb hint */
1763 if (tp->fastpath_skb_hint == next_skb)
1764 tp->fastpath_skb_hint = skb;
1765
1762 sk_stream_free_skb(sk, next_skb); 1766 sk_stream_free_skb(sk, next_skb);
1763 } 1767 }
1764} 1768}