Patchwork tcp: splice as many packets as possible at once

login
register
mail settings
Submitter willy tarreau
Date Jan. 8, 2009, 8:16 p.m.
Message ID <20090108201646.GA23687@1wt.eu>
Download mbox | patch
Permalink /patch/17405/
State Superseded
Delegated to: David Miller
Headers show

Comments

willy tarreau - Jan. 8, 2009, 8:16 p.m.
Hi David,

would you please accept this patch (acked by Jens) ?

Also, would you mind adding this one as well as
4f7d54f59bc470f0aaa932f747a95232d7ebf8b1 to your stable queue, because
without them, splicing between sockets is unusable or worthless, and
having both in the long-term 2.6.27 will certainly promote splice()
usage among applications.

Thanks!
Willy


From fafe76713523c8e9767805cfdc7b73323d7bf180 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Thu, 8 Jan 2009 17:10:13 +0100
Subject: [PATCH] tcp: splice as many packets as possible at once

Currently, in non-blocking mode, tcp_splice_read() returns after
splicing one segment regardless of the len argument. This results
in low performance and very high overhead due to syscall rate when
splicing from interfaces which do not support LRO.

The fix simply consists in not breaking out of the loop after the
first read. That way, we can read up to the size requested by the
caller and still return when there is no data left.

Performance has significantly improved with this fix, with the
number of calls to splice() divided by about 20, and CPU usage
dropped from 100% to 75%.

Signed-off-by: Willy Tarreau <w@1wt.eu>
Acked-by: Jens Axboe <jens.axboe@oracle.com>
---
 net/ipv4/tcp.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

Patch

diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 35bcddf..80261b4 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -615,7 +615,7 @@  ssize_t tcp_splice_read(struct socket *sock, loff_t *ppos,
 		lock_sock(sk);
 
 		if (sk->sk_err || sk->sk_state == TCP_CLOSE ||
-		    (sk->sk_shutdown & RCV_SHUTDOWN) || !timeo ||
+		    (sk->sk_shutdown & RCV_SHUTDOWN) ||
 		    signal_pending(current))
 			break;
 	}