diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-03 00:05:30 -0400 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-03 00:05:30 -0400 | 
| commit | ef8a97bbc92ec07e3a07a81cc011dc549f8c7a23 (patch) | |
| tree | 82a95f16d9236bc35a4cfd42ba8cab61981efda8 /net/ipv4/tcp_output.c | |
| parent | 4f032ac4122a77dbabf7a24b2739b2790448180f (diff) | |
| parent | 6c8ad3b07f7d9efdc41396db6da0aed906922701 (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (54 commits)
  glge: remove unused #include <version.h>
  dnet: remove unused #include <version.h>
  tcp: miscounts due to tcp_fragment pcount reset
  tcp: add helper for counter tweaking due mid-wq change
  hso: fix for the 'invalid frame length' messages
  hso: fix for crash when unplugging the device
  fsl_pq_mdio: Fix compile failure
  fsl_pq_mdio: Revive UCC MDIO support
  ucc_geth: Pass proper device to DMA routines, otherwise oops happens
  i.MX31: Fixing cs89x0 network building to i.MX31ADS
  tc35815: Fix build error if NAPI enabled
  hso: add Vendor/Product ID's for new devices
  ucc_geth: Remove unused header
  gianfar: Remove unused header
  kaweth: Fix locking to be SMP-safe
  net: allow multiple dev per napi with GRO
  r8169: reset IntrStatus after chip reset
  ixgbe: Fix potential memory leak/driver panic issue while setting up Tx & Rx ring parameters
  ixgbe: fix ethtool -A|a behavior
  ixgbe: Patch to fix driver panic while freeing up tx & rx resources
  ...
Diffstat (limited to 'net/ipv4/tcp_output.c')
| -rw-r--r-- | net/ipv4/tcp_output.c | 73 | 
1 files changed, 40 insertions, 33 deletions
| diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index c1f259d2d33..53300fa2359 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
| @@ -754,6 +754,36 @@ static void tcp_adjust_fackets_out(struct sock *sk, struct sk_buff *skb, | |||
| 754 | tp->fackets_out -= decr; | 754 | tp->fackets_out -= decr; | 
| 755 | } | 755 | } | 
| 756 | 756 | ||
| 757 | /* Pcount in the middle of the write queue got changed, we need to do various | ||
| 758 | * tweaks to fix counters | ||
| 759 | */ | ||
| 760 | static void tcp_adjust_pcount(struct sock *sk, struct sk_buff *skb, int decr) | ||
| 761 | { | ||
| 762 | struct tcp_sock *tp = tcp_sk(sk); | ||
| 763 | |||
| 764 | tp->packets_out -= decr; | ||
| 765 | |||
| 766 | if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED) | ||
| 767 | tp->sacked_out -= decr; | ||
| 768 | if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS) | ||
| 769 | tp->retrans_out -= decr; | ||
| 770 | if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) | ||
| 771 | tp->lost_out -= decr; | ||
| 772 | |||
| 773 | /* Reno case is special. Sigh... */ | ||
| 774 | if (tcp_is_reno(tp) && decr > 0) | ||
| 775 | tp->sacked_out -= min_t(u32, tp->sacked_out, decr); | ||
| 776 | |||
| 777 | tcp_adjust_fackets_out(sk, skb, decr); | ||
| 778 | |||
| 779 | if (tp->lost_skb_hint && | ||
| 780 | before(TCP_SKB_CB(skb)->seq, TCP_SKB_CB(tp->lost_skb_hint)->seq) && | ||
| 781 | (tcp_is_fack(tp) || TCP_SKB_CB(skb)->sacked)) | ||
| 782 | tp->lost_cnt_hint -= decr; | ||
| 783 | |||
| 784 | tcp_verify_left_out(tp); | ||
| 785 | } | ||
| 786 | |||
| 757 | /* Function to create two new TCP segments. Shrinks the given segment | 787 | /* Function to create two new TCP segments. Shrinks the given segment | 
| 758 | * to the specified size and appends a new segment with the rest of the | 788 | * to the specified size and appends a new segment with the rest of the | 
| 759 | * packet to the list. This won't be called frequently, I hope. | 789 | * packet to the list. This won't be called frequently, I hope. | 
| @@ -836,28 +866,8 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, | |||
| 836 | int diff = old_factor - tcp_skb_pcount(skb) - | 866 | int diff = old_factor - tcp_skb_pcount(skb) - | 
| 837 | tcp_skb_pcount(buff); | 867 | tcp_skb_pcount(buff); | 
| 838 | 868 | ||
| 839 | tp->packets_out -= diff; | 869 | if (diff) | 
| 840 | 870 | tcp_adjust_pcount(sk, skb, diff); | |
| 841 | if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED) | ||
| 842 | tp->sacked_out -= diff; | ||
| 843 | if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS) | ||
| 844 | tp->retrans_out -= diff; | ||
| 845 | |||
| 846 | if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) | ||
| 847 | tp->lost_out -= diff; | ||
| 848 | |||
| 849 | /* Adjust Reno SACK estimate. */ | ||
| 850 | if (tcp_is_reno(tp) && diff > 0) { | ||
| 851 | tcp_dec_pcount_approx_int(&tp->sacked_out, diff); | ||
| 852 | tcp_verify_left_out(tp); | ||
| 853 | } | ||
| 854 | tcp_adjust_fackets_out(sk, skb, diff); | ||
| 855 | |||
| 856 | if (tp->lost_skb_hint && | ||
| 857 | before(TCP_SKB_CB(skb)->seq, | ||
| 858 | TCP_SKB_CB(tp->lost_skb_hint)->seq) && | ||
| 859 | (tcp_is_fack(tp) || TCP_SKB_CB(skb)->sacked)) | ||
| 860 | tp->lost_cnt_hint -= diff; | ||
| 861 | } | 871 | } | 
| 862 | 872 | ||
| 863 | /* Link BUFF into the send queue. */ | 873 | /* Link BUFF into the send queue. */ | 
| @@ -1768,22 +1778,14 @@ static void tcp_collapse_retrans(struct sock *sk, struct sk_buff *skb) | |||
| 1768 | * packet counting does not break. | 1778 | * packet counting does not break. | 
| 1769 | */ | 1779 | */ | 
| 1770 | TCP_SKB_CB(skb)->sacked |= TCP_SKB_CB(next_skb)->sacked & TCPCB_EVER_RETRANS; | 1780 | TCP_SKB_CB(skb)->sacked |= TCP_SKB_CB(next_skb)->sacked & TCPCB_EVER_RETRANS; | 
| 1771 | if (TCP_SKB_CB(next_skb)->sacked & TCPCB_SACKED_RETRANS) | ||
| 1772 | tp->retrans_out -= tcp_skb_pcount(next_skb); | ||
| 1773 | if (TCP_SKB_CB(next_skb)->sacked & TCPCB_LOST) | ||
| 1774 | tp->lost_out -= tcp_skb_pcount(next_skb); | ||
| 1775 | /* Reno case is special. Sigh... */ | ||
| 1776 | if (tcp_is_reno(tp) && tp->sacked_out) | ||
| 1777 | tcp_dec_pcount_approx(&tp->sacked_out, next_skb); | ||
| 1778 | |||
| 1779 | tcp_adjust_fackets_out(sk, next_skb, tcp_skb_pcount(next_skb)); | ||
| 1780 | tp->packets_out -= tcp_skb_pcount(next_skb); | ||
| 1781 | 1781 | ||
| 1782 | /* changed transmit queue under us so clear hints */ | 1782 | /* changed transmit queue under us so clear hints */ | 
| 1783 | tcp_clear_retrans_hints_partial(tp); | 1783 | tcp_clear_retrans_hints_partial(tp); | 
| 1784 | if (next_skb == tp->retransmit_skb_hint) | 1784 | if (next_skb == tp->retransmit_skb_hint) | 
| 1785 | tp->retransmit_skb_hint = skb; | 1785 | tp->retransmit_skb_hint = skb; | 
| 1786 | 1786 | ||
| 1787 | tcp_adjust_pcount(sk, next_skb, tcp_skb_pcount(next_skb)); | ||
| 1788 | |||
| 1787 | sk_wmem_free_skb(sk, next_skb); | 1789 | sk_wmem_free_skb(sk, next_skb); | 
| 1788 | } | 1790 | } | 
| 1789 | 1791 | ||
| @@ -1891,7 +1893,12 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | |||
| 1891 | if (tcp_fragment(sk, skb, cur_mss, cur_mss)) | 1893 | if (tcp_fragment(sk, skb, cur_mss, cur_mss)) | 
| 1892 | return -ENOMEM; /* We'll try again later. */ | 1894 | return -ENOMEM; /* We'll try again later. */ | 
| 1893 | } else { | 1895 | } else { | 
| 1894 | tcp_init_tso_segs(sk, skb, cur_mss); | 1896 | int oldpcount = tcp_skb_pcount(skb); | 
| 1897 | |||
| 1898 | if (unlikely(oldpcount > 1)) { | ||
| 1899 | tcp_init_tso_segs(sk, skb, cur_mss); | ||
| 1900 | tcp_adjust_pcount(sk, skb, oldpcount - tcp_skb_pcount(skb)); | ||
| 1901 | } | ||
| 1895 | } | 1902 | } | 
| 1896 | 1903 | ||
| 1897 | tcp_retrans_try_collapse(sk, skb, cur_mss); | 1904 | tcp_retrans_try_collapse(sk, skb, cur_mss); | 
