mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-24 14:07:52 -04:00
splice, net: Use sendmsg(MSG_SPLICE_PAGES) rather than ->sendpage()
Replace generic_splice_sendpage() + splice_from_pipe + pipe_to_sendpage() with a net-specific handler, splice_to_socket(), that calls sendmsg() with MSG_SPLICE_PAGES set instead of calling ->sendpage(). MSG_MORE is used to indicate if the sendmsg() is expected to be followed with more data. This allows multiple pipe-buffer pages to be passed in a single call in a BVEC iterator, allowing the processing to be pushed down to a loop in the protocol driver. This helps pave the way for passing multipage folios down too. Protocols that haven't been converted to handle MSG_SPLICE_PAGES yet should just ignore it and do a normal sendmsg() for now - although that may be a bit slower as it may copy everything. Signed-off-by: David Howells <dhowells@redhat.com> Reviewed-by: Jakub Kicinski <kuba@kernel.org> cc: Jens Axboe <axboe@kernel.dk> cc: Matthew Wilcox <willy@infradead.org> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
81840b3b91
commit
2dc334f1a6
4 changed files with 131 additions and 57 deletions
26
net/socket.c
26
net/socket.c
|
@ -57,6 +57,7 @@
|
|||
#include <linux/mm.h>
|
||||
#include <linux/socket.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/splice.h>
|
||||
#include <linux/net.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/thread_info.h>
|
||||
|
@ -126,8 +127,6 @@ static long compat_sock_ioctl(struct file *file,
|
|||
unsigned int cmd, unsigned long arg);
|
||||
#endif
|
||||
static int sock_fasync(int fd, struct file *filp, int on);
|
||||
static ssize_t sock_sendpage(struct file *file, struct page *page,
|
||||
int offset, size_t size, loff_t *ppos, int more);
|
||||
static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
|
||||
struct pipe_inode_info *pipe, size_t len,
|
||||
unsigned int flags);
|
||||
|
@ -162,8 +161,7 @@ static const struct file_operations socket_file_ops = {
|
|||
.mmap = sock_mmap,
|
||||
.release = sock_close,
|
||||
.fasync = sock_fasync,
|
||||
.sendpage = sock_sendpage,
|
||||
.splice_write = generic_splice_sendpage,
|
||||
.splice_write = splice_to_socket,
|
||||
.splice_read = sock_splice_read,
|
||||
.show_fdinfo = sock_show_fdinfo,
|
||||
};
|
||||
|
@ -1066,26 +1064,6 @@ int kernel_recvmsg(struct socket *sock, struct msghdr *msg,
|
|||
}
|
||||
EXPORT_SYMBOL(kernel_recvmsg);
|
||||
|
||||
static ssize_t sock_sendpage(struct file *file, struct page *page,
|
||||
int offset, size_t size, loff_t *ppos, int more)
|
||||
{
|
||||
struct socket *sock;
|
||||
int flags;
|
||||
int ret;
|
||||
|
||||
sock = file->private_data;
|
||||
|
||||
flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
|
||||
/* more is a combination of MSG_MORE and MSG_SENDPAGE_NOTLAST */
|
||||
flags |= more;
|
||||
|
||||
ret = kernel_sendpage(sock, page, offset, size, flags);
|
||||
|
||||
if (trace_sock_send_length_enabled())
|
||||
call_trace_sock_send_length(sock->sk, ret, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
|
||||
struct pipe_inode_info *pipe, size_t len,
|
||||
unsigned int flags)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue