diff options
-rw-r--r-- | net/ipv4/tcp_input.c | 81 |
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 | ||
2528 | static int tcp_tso_acked(struct sock *sk, struct sk_buff *skb, | 2528 | static 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 | ||