| From 227f0acb6f8c5f180664b341f8272fbaf8c45acf Mon Sep 17 00:00:00 2001 |
| From: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> |
| Date: Wed, 15 Sep 2010 10:27:52 -0700 |
| Subject: [PATCH] tcp: Prevent overzealous packetization by SWS logic. |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| commit 01f83d69844d307be2aa6fea88b0e8fe5cbdb2f4 upstream. |
| |
| If peer uses tiny MSS (say, 75 bytes) and similarly tiny advertised |
| window, the SWS logic will packetize to half the MSS unnecessarily. |
| |
| This causes problems with some embedded devices. |
| |
| However for large MSS devices we do want to half-MSS packetize |
| otherwise we never get enough packets into the pipe for things |
| like fast retransmit and recovery to work. |
| |
| Be careful also to handle the case where MSS > window, otherwise |
| we'll never send until the probe timer. |
| |
| Reported-by: ツ Leandro Melo de Sales <leandroal@gmail.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| --- |
| include/net/tcp.h | 18 ++++++++++++++++-- |
| 1 files changed, 16 insertions(+), 2 deletions(-) |
| |
| diff --git a/include/net/tcp.h b/include/net/tcp.h |
| index cae8c39..91cdffd 100644 |
| --- a/include/net/tcp.h |
| +++ b/include/net/tcp.h |
| @@ -518,8 +518,22 @@ extern unsigned int tcp_current_mss(struct sock *sk); |
| /* Bound MSS / TSO packet size with the half of the window */ |
| static inline int tcp_bound_to_half_wnd(struct tcp_sock *tp, int pktsize) |
| { |
| - if (tp->max_window && pktsize > (tp->max_window >> 1)) |
| - return max(tp->max_window >> 1, 68U - tp->tcp_header_len); |
| + int cutoff; |
| + |
| + /* When peer uses tiny windows, there is no use in packetizing |
| + * to sub-MSS pieces for the sake of SWS or making sure there |
| + * are enough packets in the pipe for fast recovery. |
| + * |
| + * On the other hand, for extremely large MSS devices, handling |
| + * smaller than MSS windows in this way does make sense. |
| + */ |
| + if (tp->max_window >= 512) |
| + cutoff = (tp->max_window >> 1); |
| + else |
| + cutoff = tp->max_window; |
| + |
| + if (cutoff && pktsize > cutoff) |
| + return max_t(int, cutoff, 68U - tp->tcp_header_len); |
| else |
| return pktsize; |
| } |
| -- |
| 1.7.0.4 |
| |