virtio-net: Copy header only when necessary

The copied header is only used for byte swapping.

Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
This commit is contained in:
Akihiko Odaki 2024-04-28 16:00:52 +09:00 committed by Jason Wang
parent 8c49756825
commit ad57f700f4

View File

@ -360,7 +360,8 @@ static void virtio_net_vnet_endian_status(VirtIONet *n, uint8_t status)
* can't do it, we fallback onto fixing the headers in the core
* virtio-net code.
*/
n->needs_vnet_hdr_swap = virtio_net_set_vnet_endian(vdev, n->nic->ncs,
n->needs_vnet_hdr_swap = n->has_vnet_hdr &&
virtio_net_set_vnet_endian(vdev, n->nic->ncs,
queue_pairs, true);
} else if (virtio_net_started(n, vdev->status)) {
/* After using the device, we need to reset the network backend to
@ -2751,7 +2752,7 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
return -EINVAL;
}
if (n->has_vnet_hdr) {
if (n->needs_vnet_hdr_swap) {
if (iov_to_buf(out_sg, out_num, 0, &vhdr, n->guest_hdr_len) <
n->guest_hdr_len) {
virtio_error(vdev, "virtio-net header incorrect");
@ -2759,19 +2760,16 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
g_free(elem);
return -EINVAL;
}
if (n->needs_vnet_hdr_swap) {
virtio_net_hdr_swap(vdev, (void *) &vhdr);
sg2[0].iov_base = &vhdr;
sg2[0].iov_len = n->guest_hdr_len;
out_num = iov_copy(&sg2[1], ARRAY_SIZE(sg2) - 1,
out_sg, out_num,
n->guest_hdr_len, -1);
if (out_num == VIRTQUEUE_MAX_SIZE) {
goto drop;
}
out_num += 1;
out_sg = sg2;
virtio_net_hdr_swap(vdev, (void *) &vhdr);
sg2[0].iov_base = &vhdr;
sg2[0].iov_len = n->guest_hdr_len;
out_num = iov_copy(&sg2[1], ARRAY_SIZE(sg2) - 1, out_sg, out_num,
n->guest_hdr_len, -1);
if (out_num == VIRTQUEUE_MAX_SIZE) {
goto drop;
}
out_num += 1;
out_sg = sg2;
}
/*
* If host wants to see the guest header as is, we can