aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorIlpo Järvinen <ilpo.jarvinen@helsinki.fi>2009-02-27 23:44:33 -0500
committerDavid S. Miller <davem@davemloft.net>2009-03-02 06:00:12 -0500
commit7363a5b233734dba339f2874ff6ed6c489d3d865 (patch)
treee982156d409f29c82bcc7ec5e4e6160a11bc3685 /net
parentd0af4160d19ff2849386140881e729f9ba86f2aa (diff)
tcp: separate timeout marking loop to it's own function
Some comment about its current state added. So far I have seen very few cases where the thing is actually useful, usually just marginally (though admittedly I don't usually see top of window losses where it seems possible that there could be some gain), instead, more often the cases suffer from L-marking spike which is certainly not desirable (I'll bury improving it to my todo list, but on a low prio position). Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/tcp_input.c63
1 files changed, 39 insertions, 24 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 125b4517f368..03f5ede87224 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2461,6 +2461,44 @@ static int tcp_time_to_recover(struct sock *sk)
2461 return 0; 2461 return 0;
2462} 2462}
2463 2463
2464/* New heuristics: it is possible only after we switched to restart timer
2465 * each time when something is ACKed. Hence, we can detect timed out packets
2466 * during fast retransmit without falling to slow start.
2467 *
2468 * Usefulness of this as is very questionable, since we should know which of
2469 * the segments is the next to timeout which is relatively expensive to find
2470 * in general case unless we add some data structure just for that. The
2471 * current approach certainly won't find the right one too often and when it
2472 * finally does find _something_ it usually marks large part of the window
2473 * right away (because a retransmission with a larger timestamp blocks the
2474 * loop from advancing). -ij
2475 */
2476static void tcp_timeout_skbs(struct sock *sk)
2477{
2478 struct tcp_sock *tp = tcp_sk(sk);
2479 struct sk_buff *skb;
2480
2481 if (!tcp_is_fack(tp) || !tcp_head_timedout(sk))
2482 return;
2483
2484 skb = tp->scoreboard_skb_hint;
2485 if (tp->scoreboard_skb_hint == NULL)
2486 skb = tcp_write_queue_head(sk);
2487
2488 tcp_for_write_queue_from(skb, sk) {
2489 if (skb == tcp_send_head(sk))
2490 break;
2491 if (!tcp_skb_timedout(sk, skb))
2492 break;
2493
2494 tcp_skb_mark_lost(tp, skb);
2495 }
2496
2497 tp->scoreboard_skb_hint = skb;
2498
2499 tcp_verify_left_out(tp);
2500}
2501
2464/* Mark head of queue up as lost. With RFC3517 SACK, the packets is 2502/* Mark head of queue up as lost. With RFC3517 SACK, the packets is
2465 * is against sacked "cnt", otherwise it's against facked "cnt" 2503 * is against sacked "cnt", otherwise it's against facked "cnt"
2466 */ 2504 */
@@ -2533,30 +2571,7 @@ static void tcp_update_scoreboard(struct sock *sk, int fast_rexmit)
2533 tcp_mark_head_lost(sk, sacked_upto); 2571 tcp_mark_head_lost(sk, sacked_upto);
2534 } 2572 }
2535 2573
2536 /* New heuristics: it is possible only after we switched 2574 tcp_timeout_skbs(sk);
2537 * to restart timer each time when something is ACKed.
2538 * Hence, we can detect timed out packets during fast
2539 * retransmit without falling to slow start.
2540 */
2541 if (tcp_is_fack(tp) && tcp_head_timedout(sk)) {
2542 struct sk_buff *skb;
2543
2544 skb = tp->scoreboard_skb_hint ? tp->scoreboard_skb_hint
2545 : tcp_write_queue_head(sk);
2546
2547 tcp_for_write_queue_from(skb, sk) {
2548 if (skb == tcp_send_head(sk))
2549 break;
2550 if (!tcp_skb_timedout(sk, skb))
2551 break;
2552
2553 tcp_skb_mark_lost(tp, skb);
2554 }
2555
2556 tp->scoreboard_skb_hint = skb;
2557
2558 tcp_verify_left_out(tp);
2559 }
2560} 2575}
2561 2576
2562/* CWND moderation, preventing bursts due to too big ACKs 2577/* CWND moderation, preventing bursts due to too big ACKs