From: Eric Dumazet <eric.dumazet@xxxxxxxxx> ------------------- This is a commit scheduled for the next v2.6.34 longterm release. http://git.kernel.org/?p=linux/kernel/git/paulg/longterm-queue-2.6.34.git If you see a problem with using this for longterm, please comment. ------------------- commit 2f53384424251c06038ae612e56231b96ab610ee upstream. vmsplice()/splice(pipe, socket) call do_tcp_sendpages() one page at a time, adding at most 4096 bytes to an skb. (assuming PAGE_SIZE=4096) The call to tcp_push() at the end of do_tcp_sendpages() forces an immediate xmit when pipe is not already filled, and tso_fragment() try to split these skb to MSS multiples. 4096 bytes are usually split in a skb with 2 MSS, and a remaining sub-mss skb (assuming MTU=1500) This makes slow start suboptimal because many small frames are sent to qdisc/driver layers instead of big ones (constrained by cwnd and packets in flight of course) In fact, applications using sendmsg() (adding an additional memory copy) instead of vmsplice()/splice()/sendfile() are a bit faster because of this anomaly, especially if serving small files in environments with large initial [c]wnd. Call tcp_push() only if MSG_MORE is not set in the flags parameter. This bit is automatically provided by splice() internals but for the last page, or on all pages if user specified SPLICE_F_MORE splice() flag. In some workloads, this can reduce number of sent logical packets by an order of magnitude, making zero-copy TCP actually faster than one-copy :) Reported-by: Tom Herbert <therbert@xxxxxxxxxx> Cc: Nandita Dukkipati <nanditad@xxxxxxxxxx> Cc: Neal Cardwell <ncardwell@xxxxxxxxxx> Cc: Tom Herbert <therbert@xxxxxxxxxx> Cc: Yuchung Cheng <ycheng@xxxxxxxxxx> Cc: H.K. Jerry Chu <hkchu@xxxxxxxxxx> Cc: Maciej Żenczykowski <maze@xxxxxxxxxx> Cc: Mahesh Bandewar <maheshb@xxxxxxxxxx> Cc: Ilpo Järvinen <ilpo.jarvinen@xxxxxxxxxxx> Signed-off-by: Eric Dumazet <eric.dumazet@gmail>com> Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx> Signed-off-by: Paul Gortmaker <paul.gortmaker@xxxxxxxxxxxxx> --- net/ipv4/tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 3a8cbf72b06e..cea0a9223c5d 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -849,7 +849,7 @@ wait_for_memory: } out: - if (copied) + if (copied && !(flags & MSG_MORE)) tcp_push(sk, flags, mss_now, tp->nonagle); return copied; -- 1.8.5.2 -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html