From: Wei Xu <[email protected]> A new feature bit 'VIRTIO_NET_F_GUEST_RSC' is introduced to support WHQL Receive-Segment-Offload test, this feature will coalesce tcp packets in IPv4/6 for userspace virtio-net driver.
This feature can be enabled either by 'ACK' the feature when loading the driver in the guest, or by sending the 'VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET' command to the host via control queue. Signed-off-by: Wei Xu <[email protected]> --- hw/net/virtio-net.c | 29 +++++++++++++++++++++++++++-- include/standard-headers/linux/virtio_net.h | 1 + 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 5798f87..bd91a4b 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -537,6 +537,7 @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features, virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_TSO4); virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_TSO6); virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_ECN); + virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_RSC); } if (!peer_has_vnet_hdr(n) || !peer_has_ufo(n)) { @@ -582,7 +583,8 @@ static uint64_t virtio_net_guest_offloads_by_features(uint32_t features) (1ULL << VIRTIO_NET_F_GUEST_TSO4) | (1ULL << VIRTIO_NET_F_GUEST_TSO6) | (1ULL << VIRTIO_NET_F_GUEST_ECN) | - (1ULL << VIRTIO_NET_F_GUEST_UFO); + (1ULL << VIRTIO_NET_F_GUEST_UFO) | + (1ULL << VIRTIO_NET_F_GUEST_RSC); return guest_offloads_mask & features; } @@ -1089,7 +1091,8 @@ static int receive_filter(VirtIONet *n, const uint8_t *buf, int size) return 0; } -static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t size) +static ssize_t virtio_net_do_receive(NetClientState *nc, + const uint8_t *buf, size_t size) { VirtIONet *n = qemu_get_nic_opaque(nc); VirtIONetQueue *q = virtio_net_get_subqueue(nc); @@ -1685,6 +1688,26 @@ static int virtio_net_load_device(VirtIODevice *vdev, QEMUFile *f, return 0; } + +static ssize_t virtio_net_rsc_receive(NetClientState *nc, + const uint8_t *buf, size_t size) +{ + return virtio_net_do_receive(nc, buf, size); +} + +static ssize_t virtio_net_receive(NetClientState *nc, + const uint8_t *buf, size_t size) +{ + VirtIONet *n; + + n = qemu_get_nic_opaque(nc); + if (n->curr_guest_offloads & VIRTIO_NET_F_GUEST_RSC) { + return virtio_net_rsc_receive(nc, buf, size); + } else { + return virtio_net_do_receive(nc, buf, size); + } +} + static NetClientInfo net_virtio_info = { .type = NET_CLIENT_OPTIONS_KIND_NIC, .size = sizeof(NICState), @@ -1909,6 +1932,8 @@ static Property virtio_net_properties[] = { TX_TIMER_INTERVAL), DEFINE_PROP_INT32("x-txburst", VirtIONet, net_conf.txburst, TX_BURST), DEFINE_PROP_STRING("tx", VirtIONet, net_conf.tx), + DEFINE_PROP_BIT("guest_rsc", VirtIONet, host_features, + VIRTIO_NET_F_GUEST_RSC, true), DEFINE_PROP_END_OF_LIST(), }; diff --git a/include/standard-headers/linux/virtio_net.h b/include/standard-headers/linux/virtio_net.h index a78f33e..5b95762 100644 --- a/include/standard-headers/linux/virtio_net.h +++ b/include/standard-headers/linux/virtio_net.h @@ -55,6 +55,7 @@ #define VIRTIO_NET_F_MQ 22 /* Device supports Receive Flow * Steering */ #define VIRTIO_NET_F_CTRL_MAC_ADDR 23 /* Set MAC address */ +#define VIRTIO_NET_F_GUEST_RSC 24 /* Guest can coalesce tcp packets */ #ifndef VIRTIO_NET_NO_LEGACY #define VIRTIO_NET_F_GSO 6 /* Host handles pkts w/ any GSO type */ -- 2.5.0
