Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b76892051cf1c04d95872838e70146f65e3b9d75
Commit:     b76892051cf1c04d95872838e70146f65e3b9d75
Parent:     c96fd3d461fa495400df24be3b3b66f0e0b152f9
Author:     Ilpo Järvinen <[EMAIL PROTECTED]>
AuthorDate: Thu Sep 20 11:37:19 2007 -0700
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Wed Oct 10 16:52:12 2007 -0700

    [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 <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
---
 include/net/tcp.h     |    6 +++++-
 net/ipv4/tcp_input.c  |   14 ++++++++------
 net/ipv4/tcp_output.c |   12 ++++++++----
 3 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/include/net/tcp.h b/include/net/tcp.h
index d78ad9b..456983d 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1067,11 +1067,15 @@ static inline void tcp_mib_init(void)
 }
 
 /* from STCP */
-static inline void tcp_clear_all_retrans_hints(struct tcp_sock *tp) {
+static inline void tcp_clear_retrans_hints_partial(struct tcp_sock *tp) {
        tp->lost_skb_hint = NULL;
        tp->scoreboard_skb_hint = NULL;
        tp->retransmit_skb_hint = NULL;
        tp->forward_skb_hint = NULL;
+}
+
+static inline void tcp_clear_all_retrans_hints(struct tcp_sock *tp) {
+       tcp_clear_retrans_hints_partial(tp);
        tp->fastpath_skb_hint = NULL;
 }
 
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 65b9f27..4c10d9c 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)
        tp->high_seq = tp->frto_highmark;
        TCP_ECN_queue_cwr(tp);
 
-       tcp_clear_all_retrans_hints(tp);
+       tcp_clear_retrans_hints_partial(tp);
 }
 
 void tcp_clear_retrans(struct tcp_sock *tp)
@@ -1711,10 +1711,14 @@ void tcp_enter_loss(struct sock *sk, int how)
        tp->bytes_acked = 0;
        tcp_clear_retrans(tp);
 
-       /* Push undo marker, if it was plain RTO and nothing
-        * was retransmitted. */
-       if (!how)
+       if (!how) {
+               /* Push undo marker, if it was plain RTO and nothing
+                * was retransmitted. */
                tp->undo_marker = tp->snd_una;
+               tcp_clear_retrans_hints_partial(tp);
+       } else {
+               tcp_clear_all_retrans_hints(tp);
+       }
 
        tcp_for_write_queue(skb, sk) {
                if (skb == tcp_send_head(sk))
@@ -1741,8 +1745,6 @@ void tcp_enter_loss(struct sock *sk, int how)
        TCP_ECN_queue_cwr(tp);
        /* Abort FRTO algorithm if one is in progress */
        tp->frto_counter = 0;
-
-       tcp_clear_all_retrans_hints(tp);
 }
 
 static int tcp_check_sack_reneging(struct sock *sk)
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index f46d24b..cbb83ac 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);
        }
 }
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to