From: Volker Lendecke <Volker.Lendecke@SerNet.DE>
To: linux-kernel@vger.kernel.org
Subject: maximum buffer size for splice(2) tcp->pipe?
Date: Thu, 8 Jan 2009 11:13:51 +0100 [thread overview]
Message-ID: <E1LKrp3-004Tub-IR@intern.SerNet.DE> (raw)
[-- Attachment #1.1: Type: text/plain, Size: 1633 bytes --]
Hi!
While implementing splice support in Samba for better
performance I found it blocking when trying to pull data off
tcp into a pipe when the recvq was full. Attached find a
test program that shows this behaviour, on another host I
started
netcat 192.168.19.10 4711 < /dev/zero
vlendec@lenny:~$ uname -a
Linux lenny 2.6.28-06857-g5cbd04a #7 Wed Jan 7 10:10:42 CET 2009 x86_64 = GNU/Linux
vlendec@lenny:~$ gcc -o splicetest /host/home/vlendec/splicetest.c -O3 -Wall
vlendec@lenny:~$ ./splicetest out 65536 &
[1] 697
vlendec@lenny:~$ strace -p 697
Process 697 attached - interrupt to quit
splice(0x3, 0, 0x5, 0, 0x56a0, 0x1) = 22176
splice(0x7, 0, 0x4, 0, 0x10000, 0x1^C <unfinished ...>
Process 697 detached
vlendec@lenny:~$ netstat -nt | grep 4711
tcp 69272 0 192.168.19.10:4711 192.168.19.1:33773 ESTABLISHED
vlendec@lenny:~$
Interestingly, whenever I start the strace, it gets another
chunk of data and then blocks in the next splice call.
If I start splicetest with a buffer size of 16384 instead of
65536, it does not block. I could not find a way to ask the
kernel for the tipping point below which it does not block.
What is a safe buffer size to use with splice?
BTW, this kernel is from Steve French's linux-cifs.git repo.
Thanks,
Volker Lendecke
Samba Team
P.S: I'm not subscribed to linux-kernel, so if possible
please CC me directly. If this is inappropriate behaviour,
please give me a quick hint :-)
--
SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
phone: +49-551-370000-0, fax: +49-551-370000-9
AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
[-- Attachment #1.2: splicetest.c --]
[-- Type: text/x-c++src, Size: 2004 bytes --]
#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, const char *argv[])
{
int pipefds[2];
int file_fd;
int sock;
int listen_fd;
struct sockaddr_in in_addr;
int res;
int to_read;
if (argc != 3) {
fprintf(stderr, "usage: %s <filename> to_read\n", argv[0]);
exit(1);
}
to_read = atoi(argv[2]);
if (pipe(pipefds) != 0) {
fprintf(stderr, "pipe returned %s\n", strerror(errno));
exit(1);
}
if ((file_fd = open(argv[1], O_CREAT|O_RDWR, 0644)) == -1) {
fprintf(stderr, "open returned %s\n", strerror(errno));
exit(1);
}
listen_fd = socket(PF_INET, SOCK_STREAM, 0);
if (listen_fd == -1) {
fprintf(stderr, "socket returned %s\n", strerror(errno));
exit(1);
}
in_addr.sin_family = AF_INET;
inet_aton("0.0.0.0", &in_addr.sin_addr);
in_addr.sin_port = htons(4711);
res = bind(listen_fd, (struct sockaddr *)&in_addr, sizeof(in_addr));
if (res == -1) {
fprintf(stderr, "bind returned %s\n", strerror(errno));
exit(1);
}
res = listen(listen_fd, 5);
if (res == -1) {
fprintf(stderr, "listen returned %s\n", strerror(errno));
exit(1);
}
sock = accept(listen_fd, NULL, NULL);
if (sock == -1) {
fprintf(stderr, "accept returned %s\n", strerror(errno));
exit(1);
}
while (1) {
ssize_t nread, nwritten;
nread = splice(sock, NULL, pipefds[1], NULL, to_read,
SPLICE_F_MOVE);
if (nread == -1) {
fprintf(stderr, "splice failed: %s\n",
strerror(errno));
exit(1);
}
if (nread == 0) {
printf("EOF\n");
return 0;
}
nwritten = splice(pipefds[0], NULL, file_fd, NULL, nread,
SPLICE_F_MOVE);
if (nwritten != nread) {
fprintf(stderr, "splice failed: %d/%d %s\n",
(int)nread, (int)nwritten,
nwritten == -1 ? strerror(errno) : "");
exit(1);
}
}
return 0;
}
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
next reply other threads:[~2009-01-08 10:48 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-01-08 10:13 Volker Lendecke [this message]
2009-01-13 20:37 ` maximum buffer size for splice(2) tcp->pipe? Andrew Morton
2009-01-13 23:15 ` Eric Dumazet
2009-01-13 23:38 ` Eric Dumazet
2009-01-15 4:58 ` David Miller
2009-01-15 11:47 ` Eric Dumazet
2009-01-14 7:40 ` Volker Lendecke
2009-01-14 9:13 ` Eric Dumazet
2009-01-14 10:03 ` Volker Lendecke
2009-01-14 10:17 ` Eric Dumazet
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=E1LKrp3-004Tub-IR@intern.SerNet.DE \
--to=volker.lendecke@sernet.de \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox