Skip to content

Commit

Permalink
udp: Convert udp_sendpage() to use MSG_SPLICE_PAGES
Browse files Browse the repository at this point in the history
[ Upstream commit 7ac7c98 ]

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>
Stable-dep-of: a000212 ("udp: move udp->no_check6_tx to udp->udp_flags")
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
dhowells authored and gregkh committed Jan 10, 2024
1 parent 6bcc79a commit ac8c69e
Showing 1 changed file with 6 additions and 45 deletions.
51 changes: 6 additions & 45 deletions net/ipv4/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1335,54 +1335,15 @@ EXPORT_SYMBOL(udp_sendmsg);
int udp_sendpage(struct sock *sk, struct page *page, int offset,
size_t size, int flags)
{
struct inet_sock *inet = inet_sk(sk);
struct udp_sock *up = udp_sk(sk);
int ret;
struct bio_vec bvec;
struct msghdr msg = { .msg_flags = flags | MSG_SPLICE_PAGES };

if (flags & MSG_SENDPAGE_NOTLAST)
flags |= MSG_MORE;

if (!up->pending) {
struct msghdr msg = { .msg_flags = flags|MSG_MORE };

/* 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);
msg.msg_flags |= MSG_MORE;

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;
bvec_set_page(&bvec, page, size, offset);
iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, &bvec, 1, size);
return udp_sendmsg(sk, &msg, size);
}

#define UDP_SKB_IS_STATELESS 0x80000000
Expand Down

0 comments on commit ac8c69e

Please sign in to comment.