[PATCH 7/9] [TCP]: Correct fastpath entrypoint below high_seq
From: Ilpo Järvinen <hidden>
Date: 2007-05-26 08:36:10
Subsystem:
networking [general], networking [tcp], the rest · Maintainers:
"David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Neal Cardwell, Linus Torvalds
From: =?ISO-8859-1?q?Ilpo_J=E4rvinen?= <redacted> In addition, implemented find_below using minus one. Some reorganization was necessary to make code efficient again. Signed-off-by: Ilpo Järvinen <redacted> --- net/ipv4/tcp_input.c | 31 +++++++++++++++++++++---------- 1 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index fbce87f..8c1e38a 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c@@ -1913,22 +1913,33 @@ struct sk_buff *tcp_update_scoreboard_fack(struct sock *sk, u32 entry_seq, struct sk_buff *skb; unsigned int holes_seen = 0; - skb = tcp_write_queue_find(sk, entry_seq); - /* If this ever becomes expensive, it can be delayed */ - timedout_continue = tcp_write_queue_next(sk, skb); if (entry_seq != tp->highest_sack) { - /* Not interested in "the last" SACKed one we got */ - /* RFC: find_below could help here too */ - skb = tcp_write_queue_prev(sk, skb); + /* Look for skb below min_seq(entry_seq, tp->high_seq) */ + if (!after(entry_seq, tp->high_seq)) { + skb = tcp_write_queue_find(sk, entry_seq - 1); + } else { + BUG_ON(tp->snd_una == tp->high_seq); + skb = tcp_write_queue_find(sk, tp->high_seq - 1); + } + + timedout_continue = NULL; if (IsFack(tp) && tcp_skb_timedout(sk, skb) && (tp->fackets_out < tp->packets_out)) { - timedout_continue = tcp_write_queue_find(sk, tp->highest_sack); - timedout_continue = tcp_write_queue_next(sk, timedout_continue); - } else - timedout_continue = NULL; + timedout_continue = tcp_write_queue_next(sk, skb); + if (!after(entry_seq, tp->high_seq)) { + /* Use latest SACK info in skipping past skbs */ + timedout_continue = tcp_write_queue_find(sk, tp->highest_sack); + timedout_continue = tcp_write_queue_next(sk, timedout_continue); + } + } + } else { unsigned int reord_count = IsFack(tp) ? 0 : 1; + skb = tcp_write_queue_find(sk, entry_seq); + /* If this ever becomes expensive, it can be delayed */ + timedout_continue = tcp_write_queue_next(sk, skb); + /* Phase I: Search until TCP can mark */ tcp_for_write_queue_backwards_from(skb, sk) { if ((tp->fackets_out <= tp->sacked_out + tp->lost_out +
--
1.5.0.6