aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_output.c
diff options
context:
space:
mode:
authorIlpo Järvinen <ilpo.jarvinen@helsinki.fi>2007-10-09 04:24:15 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:52:08 -0400
commit91fed7a15c9222af29a653ecb0ee72cff178fdd8 (patch)
tree53c72bd6c1bf3216e46565761bc34ea066f5b995 /net/ipv4/tcp_output.c
parent0dde7b5404a3d52dcd9ce66d46197f6c3ca97dda (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.c44
1 files changed, 26 insertions, 18 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 9df5b2a4da6e..cbe8bf6dab5f 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 */
660static 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 }