aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_input.c
diff options
context:
space:
mode:
authorIlpo Järvinen <ilpo.jarvinen@helsinki.fi>2007-10-09 04:28:45 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:52:09 -0400
commit13fcf850cc20373db4dd8a5c9f349583ab3817c4 (patch)
treea3ef44d94215babe1362c267f84e04ecffeb3dbb /net/ipv4/tcp_input.c
parent5af4ec236f7c98f3671fb26731457a172d85e0e6 (diff)
[TCP]: Move accounting from tso_acked to clean_rtx_queue
The accounting code is pretty much the same, so it's a shame we do it in two places. I'm not too sure if added fully_acked check in MTU probing is really what we want perhaps the added end_seq could be used in the after() comparison. Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r--net/ipv4/tcp_input.c81
1 files changed, 35 insertions, 46 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 31e7e339b567..4238ed98acb9 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2525,14 +2525,12 @@ static void tcp_rearm_rto(struct sock *sk)
2525 } 2525 }
2526} 2526}
2527 2527
2528static int tcp_tso_acked(struct sock *sk, struct sk_buff *skb, 2528static u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb)
2529 __u32 now, __s32 *seq_rtt)
2530{ 2529{
2531 struct tcp_sock *tp = tcp_sk(sk); 2530 struct tcp_sock *tp = tcp_sk(sk);
2532 struct tcp_skb_cb *scb = TCP_SKB_CB(skb); 2531 struct tcp_skb_cb *scb = TCP_SKB_CB(skb);
2533 __u32 seq = tp->snd_una; 2532 __u32 seq = tp->snd_una;
2534 __u32 packets_acked; 2533 __u32 packets_acked;
2535 int acked = 0;
2536 2534
2537 /* If we get here, the whole TSO packet has not been 2535 /* If we get here, the whole TSO packet has not been
2538 * acked. 2536 * acked.
@@ -2545,39 +2543,11 @@ static int tcp_tso_acked(struct sock *sk, struct sk_buff *skb,
2545 packets_acked -= tcp_skb_pcount(skb); 2543 packets_acked -= tcp_skb_pcount(skb);
2546 2544
2547 if (packets_acked) { 2545 if (packets_acked) {
2548 __u8 sacked = scb->sacked;
2549
2550 acked |= FLAG_DATA_ACKED;
2551 if (sacked) {
2552 if (sacked & TCPCB_RETRANS) {
2553 if (sacked & TCPCB_SACKED_RETRANS)
2554 tp->retrans_out -= packets_acked;
2555 acked |= FLAG_RETRANS_DATA_ACKED;
2556 *seq_rtt = -1;
2557 } else if (*seq_rtt < 0)
2558 *seq_rtt = now - scb->when;
2559 if (sacked & TCPCB_SACKED_ACKED)
2560 tp->sacked_out -= packets_acked;
2561 if (sacked & TCPCB_LOST)
2562 tp->lost_out -= packets_acked;
2563 if (sacked & TCPCB_URG) {
2564 if (tp->urg_mode &&
2565 !before(seq, tp->snd_up))
2566 tp->urg_mode = 0;
2567 }
2568 } else if (*seq_rtt < 0)
2569 *seq_rtt = now - scb->when;
2570
2571 /* hint's skb might be NULL but we don't need to care */
2572 tp->fastpath_cnt_hint -= min_t(u32, packets_acked,
2573 tp->fastpath_cnt_hint);
2574 tp->packets_out -= packets_acked;
2575
2576 BUG_ON(tcp_skb_pcount(skb) == 0); 2546 BUG_ON(tcp_skb_pcount(skb) == 0);
2577 BUG_ON(!before(scb->seq, scb->end_seq)); 2547 BUG_ON(!before(scb->seq, scb->end_seq));
2578 } 2548 }
2579 2549
2580 return acked; 2550 return packets_acked;
2581} 2551}
2582 2552
2583/* Remove acknowledged frames from the retransmission queue. */ 2553/* Remove acknowledged frames from the retransmission queue. */
@@ -2587,6 +2557,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
2587 const struct inet_connection_sock *icsk = inet_csk(sk); 2557 const struct inet_connection_sock *icsk = inet_csk(sk);
2588 struct sk_buff *skb; 2558 struct sk_buff *skb;
2589 __u32 now = tcp_time_stamp; 2559 __u32 now = tcp_time_stamp;
2560 int fully_acked = 1;
2590 int acked = 0; 2561 int acked = 0;
2591 int prior_packets = tp->packets_out; 2562 int prior_packets = tp->packets_out;
2592 __s32 seq_rtt = -1; 2563 __s32 seq_rtt = -1;
@@ -2595,6 +2566,8 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
2595 while ((skb = tcp_write_queue_head(sk)) && 2566 while ((skb = tcp_write_queue_head(sk)) &&
2596 skb != tcp_send_head(sk)) { 2567 skb != tcp_send_head(sk)) {
2597 struct tcp_skb_cb *scb = TCP_SKB_CB(skb); 2568 struct tcp_skb_cb *scb = TCP_SKB_CB(skb);
2569 u32 end_seq;
2570 u32 packets_acked;
2598 __u8 sacked = scb->sacked; 2571 __u8 sacked = scb->sacked;
2599 2572
2600 /* If our packet is before the ack sequence we can 2573 /* If our packet is before the ack sequence we can
@@ -2602,11 +2575,19 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
2602 * the other end. 2575 * the other end.
2603 */ 2576 */
2604 if (after(scb->end_seq, tp->snd_una)) { 2577 if (after(scb->end_seq, tp->snd_una)) {
2605 if (tcp_skb_pcount(skb) > 1 && 2578 if (tcp_skb_pcount(skb) == 1 ||
2606 after(tp->snd_una, scb->seq)) 2579 !after(tp->snd_una, scb->seq))
2607 acked |= tcp_tso_acked(sk, skb, 2580 break;
2608 now, &seq_rtt); 2581
2609 break; 2582 packets_acked = tcp_tso_acked(sk, skb);
2583 if (!packets_acked)
2584 break;
2585
2586 fully_acked = 0;
2587 end_seq = tp->snd_una;
2588 } else {
2589 packets_acked = tcp_skb_pcount(skb);
2590 end_seq = scb->end_seq;
2610 } 2591 }
2611 2592
2612 /* Initial outgoing SYN's get put onto the write_queue 2593 /* Initial outgoing SYN's get put onto the write_queue
@@ -2624,7 +2605,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
2624 } 2605 }
2625 2606
2626 /* MTU probing checks */ 2607 /* MTU probing checks */
2627 if (icsk->icsk_mtup.probe_size) { 2608 if (fully_acked && icsk->icsk_mtup.probe_size) {
2628 if (!after(tp->mtu_probe.probe_seq_end, TCP_SKB_CB(skb)->end_seq)) { 2609 if (!after(tp->mtu_probe.probe_seq_end, TCP_SKB_CB(skb)->end_seq)) {
2629 tcp_mtup_probe_success(sk, skb); 2610 tcp_mtup_probe_success(sk, skb);
2630 } 2611 }
@@ -2633,27 +2614,32 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
2633 if (sacked) { 2614 if (sacked) {
2634 if (sacked & TCPCB_RETRANS) { 2615 if (sacked & TCPCB_RETRANS) {
2635 if (sacked & TCPCB_SACKED_RETRANS) 2616 if (sacked & TCPCB_SACKED_RETRANS)
2636 tp->retrans_out -= tcp_skb_pcount(skb); 2617 tp->retrans_out -= packets_acked;
2637 acked |= FLAG_RETRANS_DATA_ACKED; 2618 acked |= FLAG_RETRANS_DATA_ACKED;
2638 seq_rtt = -1; 2619 seq_rtt = -1;
2639 } else if (seq_rtt < 0) { 2620 } else if (seq_rtt < 0) {
2640 seq_rtt = now - scb->when; 2621 seq_rtt = now - scb->when;
2641 last_ackt = skb->tstamp; 2622 if (fully_acked)
2623 last_ackt = skb->tstamp;
2642 } 2624 }
2643 if (sacked & TCPCB_SACKED_ACKED) 2625 if (sacked & TCPCB_SACKED_ACKED)
2644 tp->sacked_out -= tcp_skb_pcount(skb); 2626 tp->sacked_out -= packets_acked;
2645 if (sacked & TCPCB_LOST) 2627 if (sacked & TCPCB_LOST)
2646 tp->lost_out -= tcp_skb_pcount(skb); 2628 tp->lost_out -= packets_acked;
2647 if (sacked & TCPCB_URG) { 2629 if (sacked & TCPCB_URG) {
2648 if (tp->urg_mode && 2630 if (tp->urg_mode && !before(end_seq, tp->snd_up))
2649 !before(scb->end_seq, tp->snd_up))
2650 tp->urg_mode = 0; 2631 tp->urg_mode = 0;
2651 } 2632 }
2652 } else if (seq_rtt < 0) { 2633 } else if (seq_rtt < 0) {
2653 seq_rtt = now - scb->when; 2634 seq_rtt = now - scb->when;
2654 last_ackt = skb->tstamp; 2635 if (fully_acked)
2636 last_ackt = skb->tstamp;
2655 } 2637 }
2656 tp->packets_out -= tcp_skb_pcount(skb); 2638 tp->packets_out -= packets_acked;
2639
2640 if (!fully_acked)
2641 break;
2642
2657 tcp_unlink_write_queue(skb, sk); 2643 tcp_unlink_write_queue(skb, sk);
2658 sk_stream_free_skb(sk, skb); 2644 sk_stream_free_skb(sk, skb);
2659 tcp_clear_all_retrans_hints(tp); 2645 tcp_clear_all_retrans_hints(tp);
@@ -2668,6 +2654,9 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
2668 tcp_rearm_rto(sk); 2654 tcp_rearm_rto(sk);
2669 2655
2670 tp->fackets_out -= min(pkts_acked, tp->fackets_out); 2656 tp->fackets_out -= min(pkts_acked, tp->fackets_out);
2657 /* hint's skb might be NULL but we don't need to care */
2658 tp->fastpath_cnt_hint -= min_t(u32, pkts_acked,
2659 tp->fastpath_cnt_hint);
2671 if (tcp_is_reno(tp)) 2660 if (tcp_is_reno(tp))
2672 tcp_remove_reno_sacks(sk, pkts_acked); 2661 tcp_remove_reno_sacks(sk, pkts_acked);
2673 2662