summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorfenner <fenner@FreeBSD.org>1998-07-06 19:27:14 +0000
committerfenner <fenner@FreeBSD.org>1998-07-06 19:27:14 +0000
commitbcc119fe0b9c7e44eff8a980368af8f6598043f7 (patch)
tree6dba027df297d9a8bdeac3dac4652171f70a887f /sys
parente1c554bc5fe3a7f11b72cb36f0958fc3c1f45d18 (diff)
downloadFreeBSD-src-bcc119fe0b9c7e44eff8a980368af8f6598043f7.zip
FreeBSD-src-bcc119fe0b9c7e44eff8a980368af8f6598043f7.tar.gz
Introduce (fairly hacky) workaround for odd TCP behavior with application
writes of size (100,208]+N*MCLBYTES. The bug: sosend() hands each mbuf off to the protocol output routine as soon as it has copied it, in the hopes of increasing parallelism (see http://www.kohala.com/~rstevens/vanj.88jul20.txt ). This works well for TCP as long as the first mbuf handed off is at least the MSS. However, when doing small writes (between MHLEN and MINCLSIZE), the transaction is split into 2 small MBUF's and each is individually handed off to TCP. TCP assumes that the first small mbuf is the whole transaction, so sends a small packet. When the second small mbuf arrives, Nagle prevents TCP from sending it so it must wait for a (potentially delayed) ACK. This sends throughput down the toilet. The workaround: Set the "atomic" flag when we're doing small writes. The "atomic" flag has two meanings: 1. Copy all of the data into a chain of mbufs before handing off to the protocol. 2. Leave room for a datagram header in said mbuf chain. TCP wants the first but doesn't want the second. However, the second simply results in some memory wastage (but is why the workaround is a hack and not a fix). The real fix: The real fix for this problem is to introduce something like a "requested transfer size" variable in the socket->protocol interface. sosend() would then accumulate an mbuf chain until it exceeded the "requested transfer size". TCP could set it to the TCP MSS (note that the current interface causes strange TCP behaviors when the MSS > MCLBYTES; nobody notices because MCLBYTES > ethernet's MTU).
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/uipc_socket.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 2ca79fc..56c0593 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94
- * $Id: uipc_socket.c,v 1.39 1998/03/28 10:33:08 bde Exp $
+ * $Id: uipc_socket.c,v 1.40 1998/05/15 20:11:30 wollman Exp $
*/
#include <sys/param.h>
@@ -491,6 +491,7 @@ restart:
mlen = MCLBYTES;
len = min(min(mlen, resid), space);
} else {
+ atomic = 1;
nopages:
len = min(min(mlen, resid), space);
/*
OpenPOWER on IntegriCloud