diff options
author | Ilpo Järvinen <ilpo.jarvinen@helsinki.fi> | 2007-10-09 04:24:15 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:52:08 -0400 |
commit | 91fed7a15c9222af29a653ecb0ee72cff178fdd8 (patch) | |
tree | 53c72bd6c1bf3216e46565761bc34ea066f5b995 /net/ipv4/tcp_output.c | |
parent | 0dde7b5404a3d52dcd9ce66d46197f6c3ca97dda (diff) |
[TCP]: Make fackets_out accurate
Substraction for fackets_out is unconditional when snd_una
advances, thus there's no need to do it inside the loop. Just
make sure correct bounds are honored.
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_output.c')
-rw-r--r-- | net/ipv4/tcp_output.c | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 9df5b2a4da6..cbe8bf6dab5 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -652,6 +652,26 @@ static void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb, unsigned | |||
652 | } | 652 | } |
653 | } | 653 | } |
654 | 654 | ||
655 | /* When a modification to fackets out becomes necessary, we need to check | ||
656 | * skb is counted to fackets_out or not. Another important thing is to | ||
657 | * tweak SACK fastpath hint too as it would overwrite all changes unless | ||
658 | * hint is also changed. | ||
659 | */ | ||
660 | static void tcp_adjust_fackets_out(struct tcp_sock *tp, struct sk_buff *skb, | ||
661 | int decr) | ||
662 | { | ||
663 | if (!tp->sacked_out) | ||
664 | return; | ||
665 | |||
666 | if (!before(tp->highest_sack, TCP_SKB_CB(skb)->seq)) | ||
667 | tp->fackets_out -= decr; | ||
668 | |||
669 | /* cnt_hint is "off-by-one" compared with fackets_out (see sacktag) */ | ||
670 | if (tp->fastpath_skb_hint != NULL && | ||
671 | after(TCP_SKB_CB(tp->fastpath_skb_hint)->seq, TCP_SKB_CB(skb)->seq)) | ||
672 | tp->fastpath_cnt_hint -= decr; | ||
673 | } | ||
674 | |||
655 | /* Function to create two new TCP segments. Shrinks the given segment | 675 | /* Function to create two new TCP segments. Shrinks the given segment |
656 | * to the specified size and appends a new segment with the rest of the | 676 | * to the specified size and appends a new segment with the rest of the |
657 | * packet to the list. This won't be called frequently, I hope. | 677 | * packet to the list. This won't be called frequently, I hope. |
@@ -746,21 +766,12 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss | |||
746 | if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) | 766 | if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) |
747 | tp->lost_out -= diff; | 767 | tp->lost_out -= diff; |
748 | 768 | ||
749 | if (diff > 0) { | 769 | /* Adjust Reno SACK estimate. */ |
750 | /* Adjust Reno SACK estimate. */ | 770 | if (tcp_is_reno(tp) && diff > 0) { |
751 | if (tcp_is_reno(tp)) { | 771 | tcp_dec_pcount_approx_int(&tp->sacked_out, diff); |
752 | tcp_dec_pcount_approx_int(&tp->sacked_out, diff); | 772 | tcp_verify_left_out(tp); |
753 | tcp_verify_left_out(tp); | ||
754 | } | ||
755 | |||
756 | tcp_dec_pcount_approx_int(&tp->fackets_out, diff); | ||
757 | /* SACK fastpath might overwrite it unless dealt with */ | ||
758 | if (tp->fastpath_skb_hint != NULL && | ||
759 | after(TCP_SKB_CB(tp->fastpath_skb_hint)->seq, | ||
760 | TCP_SKB_CB(skb)->seq)) { | ||
761 | tcp_dec_pcount_approx_int(&tp->fastpath_cnt_hint, diff); | ||
762 | } | ||
763 | } | 773 | } |
774 | tcp_adjust_fackets_out(tp, skb, diff); | ||
764 | } | 775 | } |
765 | 776 | ||
766 | /* Link BUFF into the send queue. */ | 777 | /* Link BUFF into the send queue. */ |
@@ -1746,10 +1757,7 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb, int m | |||
1746 | if (tcp_is_reno(tp) && tp->sacked_out) | 1757 | if (tcp_is_reno(tp) && tp->sacked_out) |
1747 | tcp_dec_pcount_approx(&tp->sacked_out, next_skb); | 1758 | tcp_dec_pcount_approx(&tp->sacked_out, next_skb); |
1748 | 1759 | ||
1749 | /* Not quite right: it can be > snd.fack, but | 1760 | tcp_adjust_fackets_out(tp, skb, tcp_skb_pcount(next_skb)); |
1750 | * it is better to underestimate fackets. | ||
1751 | */ | ||
1752 | tcp_dec_pcount_approx(&tp->fackets_out, next_skb); | ||
1753 | tp->packets_out -= tcp_skb_pcount(next_skb); | 1761 | tp->packets_out -= tcp_skb_pcount(next_skb); |
1754 | sk_stream_free_skb(sk, next_skb); | 1762 | sk_stream_free_skb(sk, next_skb); |
1755 | } | 1763 | } |