mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-21 07:39:16 -04:00
vsock/virtio: rewrite MSG_ZEROCOPY flag handling
Logically it was based on TCP implementation, so to make further support easier, rewrite it in the TCP way (like in 'tcp_sendmsg_locked()'). By this way, patch also adds handling case when 'msg_ubuf' is already set. Signed-off-by: Arseniy Krasnov <avkrasnov@rulkc.org> Acked-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com> Link: https://patch.msgid.link/20260628182052.951760-1-avkrasnov@rulkc.org Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
committed by
Paolo Abeni
parent
cef9d68040
commit
f456c1922c
@@ -328,38 +328,35 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk,
|
||||
if (pkt_len == 0 && info->op == VIRTIO_VSOCK_OP_RW)
|
||||
return pkt_len;
|
||||
|
||||
if (info->msg) {
|
||||
/* If zerocopy is not enabled by 'setsockopt()', we behave as
|
||||
* there is no MSG_ZEROCOPY flag set.
|
||||
if (info->msg && (info->msg->msg_flags & MSG_ZEROCOPY)) {
|
||||
/* If 'info->msg' is not NULL, this is only VIRTIO_VSOCK_OP_RW.
|
||||
* 'MSG_ZEROCOPY' flag handling here is based on the same flag
|
||||
* handling from 'tcp_sendmsg_locked()'.
|
||||
*/
|
||||
if (!sock_flag(sk_vsock(vsk), SOCK_ZEROCOPY))
|
||||
info->msg->msg_flags &= ~MSG_ZEROCOPY;
|
||||
|
||||
if (info->msg->msg_flags & MSG_ZEROCOPY)
|
||||
if (info->msg->msg_ubuf) {
|
||||
uarg = info->msg->msg_ubuf;
|
||||
can_zcopy = virtio_transport_can_zcopy(t_ops, info, pkt_len);
|
||||
} else if (sock_flag(sk_vsock(vsk), SOCK_ZEROCOPY)) {
|
||||
uarg = msg_zerocopy_realloc(sk_vsock(vsk), pkt_len,
|
||||
NULL, false);
|
||||
if (!uarg) {
|
||||
virtio_transport_put_credit(vvs, pkt_len);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
can_zcopy = virtio_transport_can_zcopy(t_ops, info, pkt_len);
|
||||
if (!can_zcopy)
|
||||
uarg_to_msgzc(uarg)->zerocopy = 0;
|
||||
|
||||
have_uref = true;
|
||||
}
|
||||
|
||||
/* 'can_zcopy' means that this transmission will be
|
||||
* in zerocopy way (e.g. using 'frags' array).
|
||||
*/
|
||||
if (can_zcopy)
|
||||
max_skb_len = min_t(u32, VIRTIO_VSOCK_MAX_PKT_BUF_SIZE,
|
||||
(MAX_SKB_FRAGS * PAGE_SIZE));
|
||||
|
||||
if (info->msg->msg_flags & MSG_ZEROCOPY &&
|
||||
info->op == VIRTIO_VSOCK_OP_RW) {
|
||||
uarg = info->msg->msg_ubuf;
|
||||
|
||||
if (!uarg) {
|
||||
uarg = msg_zerocopy_realloc(sk_vsock(vsk),
|
||||
pkt_len, NULL, false);
|
||||
if (!uarg) {
|
||||
virtio_transport_put_credit(vvs, pkt_len);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (!can_zcopy)
|
||||
uarg_to_msgzc(uarg)->zerocopy = 0;
|
||||
|
||||
have_uref = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rest_len = pkt_len;
|
||||
|
||||
Reference in New Issue
Block a user