Commit b7689205 authored by Ilpo Järvinen's avatar Ilpo Järvinen Committed by David S. Miller

[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: default avatarIlpo Järvinen <ilpo.jarvinen@helsinki.fi>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c96fd3d4
...@@ -1067,11 +1067,15 @@ static inline void tcp_mib_init(void) ...@@ -1067,11 +1067,15 @@ static inline void tcp_mib_init(void)
} }
/* from STCP */ /* 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->lost_skb_hint = NULL;
tp->scoreboard_skb_hint = NULL; tp->scoreboard_skb_hint = NULL;
tp->retransmit_skb_hint = NULL; tp->retransmit_skb_hint = NULL;
tp->forward_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; tp->fastpath_skb_hint = NULL;
} }
......
...@@ -1671,7 +1671,7 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag) ...@@ -1671,7 +1671,7 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag)
tp->high_seq = tp->frto_highmark; tp->high_seq = tp->frto_highmark;
TCP_ECN_queue_cwr(tp); 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) void tcp_clear_retrans(struct tcp_sock *tp)
...@@ -1711,10 +1711,14 @@ void tcp_enter_loss(struct sock *sk, int how) ...@@ -1711,10 +1711,14 @@ void tcp_enter_loss(struct sock *sk, int how)
tp->bytes_acked = 0; tp->bytes_acked = 0;
tcp_clear_retrans(tp); tcp_clear_retrans(tp);
/* Push undo marker, if it was plain RTO and nothing if (!how) {
* was retransmitted. */ /* Push undo marker, if it was plain RTO and nothing
if (!how) * was retransmitted. */
tp->undo_marker = tp->snd_una; 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) { tcp_for_write_queue(skb, sk) {
if (skb == tcp_send_head(sk)) if (skb == tcp_send_head(sk))
...@@ -1741,8 +1745,6 @@ void tcp_enter_loss(struct sock *sk, int how) ...@@ -1741,8 +1745,6 @@ void tcp_enter_loss(struct sock *sk, int how)
TCP_ECN_queue_cwr(tp); TCP_ECN_queue_cwr(tp);
/* Abort FRTO algorithm if one is in progress */ /* Abort FRTO algorithm if one is in progress */
tp->frto_counter = 0; tp->frto_counter = 0;
tcp_clear_all_retrans_hints(tp);
} }
static int tcp_check_sack_reneging(struct sock *sk) static int tcp_check_sack_reneging(struct sock *sk)
......
...@@ -687,7 +687,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss ...@@ -687,7 +687,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss
BUG_ON(len > skb->len); BUG_ON(len > skb->len);
tcp_clear_all_retrans_hints(tp); tcp_clear_retrans_hints_partial(tp);
nsize = skb_headlen(skb) - len; nsize = skb_headlen(skb) - len;
if (nsize < 0) if (nsize < 0)
nsize = 0; nsize = 0;
...@@ -1718,9 +1718,6 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb, int m ...@@ -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 || BUG_ON(tcp_skb_pcount(skb) != 1 ||
tcp_skb_pcount(next_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. */ /* Ok. We will be able to collapse the packet. */
tcp_unlink_write_queue(next_skb, sk); 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 ...@@ -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)); tcp_adjust_fackets_out(tp, skb, tcp_skb_pcount(next_skb));
tp->packets_out -= 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); sk_stream_free_skb(sk, next_skb);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment