lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Message-ID: <4AF2A929.3000201@gmail.com> Date: Thu, 05 Nov 2009 11:30:01 +0100 From: Eric Dumazet <eric.dumazet@...il.com> To: Max Kellermann <mk@...all.com> CC: linux-kernel@...r.kernel.org, jens.axboe@...cle.com, max@...mpel.org, Linux Netdev List <netdev@...r.kernel.org> Subject: Re: [PATCH] tcp: set SPLICE_F_NONBLOCK after first buffer has been spliced Max Kellermann a écrit : > When splicing a large amount of bytes from a TCP socket to a pipe > (more than PIPE_BUFFERS), splice() can block, even though the pipe was > empty. The correct behavior would be to copy as much as possible, and > return without blocking. Block only if nothing can be transferred. > When the destination pipe is (initially) writable, splice() should do > the same with or without SPLICE_F_NONBLOCK. > > The cause is the loop in tcp_splice_read(): it calls > __tcp_splice_read() (and thus skb_splice_bits() and splice_to_pipe()) > again and again, until the requested number of bytes has been > transferred, or an error occurs. In the first iteration, up to 64 kB > is copied, and the second iteration will block, because > splice_to_pipe() is called again and sees the pipe is already full. > > This patch adds SPLICE_F_NONBLOCK to the splice flags after the first > iteration has finished successfully. This prevents the second > splice_to_pipe() call from blocking. The resulting EAGAIN error is > handled gracefully, and tcp_splice_read() returns the number of bytes > successfully moved. > --- > > net/ipv4/tcp.c | 5 +++++ > 1 files changed, 5 insertions(+), 0 deletions(-) > > diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c > index 9114524..0f8b01f 100644 > --- a/net/ipv4/tcp.c > +++ b/net/ipv4/tcp.c > @@ -628,6 +628,11 @@ ssize_t tcp_splice_read(struct socket *sock, loff_t *ppos, > (sk->sk_shutdown & RCV_SHUTDOWN) || > signal_pending(current)) > break; > + > + /* the following splice_to_pipe() calls should not > + block, because we have already successfully > + transferred at least one buffer */ > + tss.flags |= SPLICE_F_NONBLOCK; > } > > release_sock(sk); > CC netdev I dont think this patch is correct. Could you describe your use case ? If you dont want to block on output pipe, you should set this NONBLOCK flag before calling splice(SPLICE_F_NONBLOCK) syscall. ie : Use the socket in blocking mode, but output pipe in non-blocking mode. Some application could have a thread working in full blocking mode, and have another thread reading the pipe (and eventually unblocking first thread) Thanks -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists