udp: Convert udp_sendpage() to use MSG_SPLICE_PAGES
Convert udp_sendpage() to use sendmsg() with MSG_SPLICE_PAGES rather than directly splicing in the pages itself. This allows ->sendpage() to be replaced by something that can handle multiple multipage folios in a single transaction. Signed-off-by: David Howells <dhowells@redhat.com> cc: Willem de Bruijn <willemdebruijn.kernel@gmail.com> cc: David Ahern <dsahern@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
6d8192bd69
commit
7ac7c98785
|
@ -1332,54 +1332,15 @@ EXPORT_SYMBOL(udp_sendmsg);
|
||||||
int udp_sendpage(struct sock *sk, struct page *page, int offset,
|
int udp_sendpage(struct sock *sk, struct page *page, int offset,
|
||||||
size_t size, int flags)
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
struct inet_sock *inet = inet_sk(sk);
|
struct bio_vec bvec;
|
||||||
struct udp_sock *up = udp_sk(sk);
|
struct msghdr msg = { .msg_flags = flags | MSG_SPLICE_PAGES };
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (flags & MSG_SENDPAGE_NOTLAST)
|
if (flags & MSG_SENDPAGE_NOTLAST)
|
||||||
flags |= MSG_MORE;
|
msg.msg_flags |= MSG_MORE;
|
||||||
|
|
||||||
if (!up->pending) {
|
bvec_set_page(&bvec, page, size, offset);
|
||||||
struct msghdr msg = { .msg_flags = flags|MSG_MORE };
|
iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, &bvec, 1, size);
|
||||||
|
return udp_sendmsg(sk, &msg, size);
|
||||||
/* Call udp_sendmsg to specify destination address which
|
|
||||||
* sendpage interface can't pass.
|
|
||||||
* This will succeed only when the socket is connected.
|
|
||||||
*/
|
|
||||||
ret = udp_sendmsg(sk, &msg, 0);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
lock_sock(sk);
|
|
||||||
|
|
||||||
if (unlikely(!up->pending)) {
|
|
||||||
release_sock(sk);
|
|
||||||
|
|
||||||
net_dbg_ratelimited("cork failed\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = ip_append_page(sk, &inet->cork.fl.u.ip4,
|
|
||||||
page, offset, size, flags);
|
|
||||||
if (ret == -EOPNOTSUPP) {
|
|
||||||
release_sock(sk);
|
|
||||||
return sock_no_sendpage(sk->sk_socket, page, offset,
|
|
||||||
size, flags);
|
|
||||||
}
|
|
||||||
if (ret < 0) {
|
|
||||||
udp_flush_pending_frames(sk);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
up->len += size;
|
|
||||||
if (!(READ_ONCE(up->corkflag) || (flags&MSG_MORE)))
|
|
||||||
ret = udp_push_pending_frames(sk);
|
|
||||||
if (!ret)
|
|
||||||
ret = size;
|
|
||||||
out:
|
|
||||||
release_sock(sk);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define UDP_SKB_IS_STATELESS 0x80000000
|
#define UDP_SKB_IS_STATELESS 0x80000000
|
||||||
|
|
Loading…
Reference in New Issue