Skip to content

Commit

Permalink
[TCP]: Avoid clearing sacktag hint in trivial situations
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Ilpo Järvinen authored and David S. Miller committed Oct 10, 2007
1 parent c96fd3d commit b768920
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 11 deletions.
6 changes: 5 additions & 1 deletion include/net/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
14 changes: 8 additions & 6 deletions net/ipv4/tcp_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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))
Expand All @@ -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)
Expand Down
12 changes: 8 additions & 4 deletions net/ipv4/tcp_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);
}
}
Expand Down

0 comments on commit b768920

Please sign in to comment.