summaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_output.c
diff options
context:
space:
mode:
authorIlpo Järvinen <ilpo.jarvinen@helsinki.fi>2007-09-20 11:37:19 -0700
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 16:52:12 -0700
commitb76892051cf1c04d95872838e70146f65e3b9d75 (patch)
tree475050b8e41eb317144465b1e2b9255fbad188b4 /net/ipv4/tcp_output.c
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/ipv4/tcp_output.c')
-rw-r--r--net/ipv4/tcp_output.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index f46d24b8410..cbb83acd830 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
BUG_ON(len > skb->len);
- tcp_clear_all_retrans_hints(tp);
+ tcp_clear_retrans_hints_partial(tp);
nsize = skb_headlen(skb) - len;
if (nsize < 0)
nsize = 0;
@@ -1718,9 +1718,6 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb, int m
BUG_ON(tcp_skb_pcount(skb) != 1 ||
tcp_skb_pcount(next_skb) != 1);
- /* changing transmit queue under us so clear hints */
- tcp_clear_all_retrans_hints(tp);
-
/* Ok. We will be able to collapse the packet. */
tcp_unlink_write_queue(next_skb, sk);
@@ -1759,6 +1756,13 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb, int m
tcp_adjust_fackets_out(tp, skb, tcp_skb_pcount(next_skb));
tp->packets_out -= tcp_skb_pcount(next_skb);
+
+ /* changed transmit queue under us so clear hints */
+ tcp_clear_retrans_hints_partial(tp);
+ /* manually tune sacktag skb hint */
+ if (tp->fastpath_skb_hint == next_skb)
+ tp->fastpath_skb_hint = skb;
+
sk_stream_free_skb(sk, next_skb);
}
}