diff mbox

[RFC,v3,3/3] virtio-net: Add MTU feature support

Message ID 20161130101017.13382-4-maxime.coquelin@redhat.com
State New
Headers show

Commit Message

Maxime Coquelin Nov. 30, 2016, 10:10 a.m. UTC
This patch allows advising guest with host MTU's by setting
host_mtu parameter.

If VIRTIO_NET_F_MTU has been successfully negotiated, MTU
value is passed to the backend.

Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Aaron Conole <aconole@redhat.com
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 hw/net/virtio-net.c            | 13 +++++++++++++
 include/hw/virtio/virtio-net.h |  1 +
 2 files changed, 14 insertions(+)

Comments

Jason Wang Nov. 30, 2016, 11:24 a.m. UTC | #1
On 2016年11月30日 18:10, Maxime Coquelin wrote:
> This patch allows advising guest with host MTU's by setting
> host_mtu parameter.
>
> If VIRTIO_NET_F_MTU has been successfully negotiated, MTU
> value is passed to the backend.
>
> Cc: Michael S. Tsirkin <mst@redhat.com>
> Cc: Aaron Conole <aconole@redhat.com
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
>   hw/net/virtio-net.c            | 13 +++++++++++++
>   include/hw/virtio/virtio-net.h |  1 +
>   2 files changed, 14 insertions(+)
>
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> index 5009533..5225e9b 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
> @@ -55,6 +55,8 @@ static VirtIOFeature feature_sizes[] = {
>        .end = endof(struct virtio_net_config, status)},
>       {.flags = 1 << VIRTIO_NET_F_MQ,
>        .end = endof(struct virtio_net_config, max_virtqueue_pairs)},
> +    {.flags = 1 << VIRTIO_NET_F_MTU,
> +     .end = endof(struct virtio_net_config, mtu)},
>       {}
>   };
>   
> @@ -81,6 +83,7 @@ static void virtio_net_get_config(VirtIODevice *vdev, uint8_t *config)
>   
>       virtio_stw_p(vdev, &netcfg.status, n->status);
>       virtio_stw_p(vdev, &netcfg.max_virtqueue_pairs, n->max_queues);
> +    virtio_stw_p(vdev, &netcfg.mtu, n->net_conf.mtu);
>       memcpy(netcfg.mac, n->mac, ETH_ALEN);
>       memcpy(config, &netcfg, n->config_size);
>   }
> @@ -152,6 +155,10 @@ static void virtio_net_vhost_status(VirtIONet *n, uint8_t status)
>               qemu_net_queue_purge(qnc->incoming_queue, qnc->peer);
>           }
>   
> +        if (virtio_has_feature(vdev->guest_features, VIRTIO_NET_F_MTU)) {
> +            vhost_net_set_mtu(get_vhost_net(nc->peer), n->net_conf.mtu);
> +        }

We'd better not ignore errors here and that's why we need management 
tool (who can make sure the mtu is set correctly before launching qemu).

> +
>           n->vhost_started = 1;
>           r = vhost_net_start(vdev, n->nic->ncs, queues);
>           if (r < 0) {
> @@ -1695,6 +1702,7 @@ static void virtio_net_set_config_size(VirtIONet *n, uint64_t host_features)
>   {
>       int i, config_size = 0;
>       virtio_add_feature(&host_features, VIRTIO_NET_F_MAC);
> +
>       for (i = 0; feature_sizes[i].flags != 0; i++) {
>           if (host_features & feature_sizes[i].flags) {
>               config_size = MAX(feature_sizes[i].end, config_size);
> @@ -1724,6 +1732,10 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
>       NetClientState *nc;
>       int i;
>   
> +    if (n->net_conf.mtu) {
> +        n->host_features |= (0x1 << VIRTIO_NET_F_MTU);
> +    }
> +
>       virtio_net_set_config_size(n, n->host_features);
>       virtio_init(vdev, "virtio-net", VIRTIO_ID_NET, n->config_size);
>   
> @@ -1922,6 +1934,7 @@ static Property virtio_net_properties[] = {
>       DEFINE_PROP_STRING("tx", VirtIONet, net_conf.tx),
>       DEFINE_PROP_UINT16("rx_queue_size", VirtIONet, net_conf.rx_queue_size,
>                          VIRTIO_NET_RX_QUEUE_DEFAULT_SIZE),
> +    DEFINE_PROP_UINT16("host_mtu", VirtIONet, net_conf.mtu, 0),
>       DEFINE_PROP_END_OF_LIST(),
>   };
>   
> diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
> index 0ced975..8ea56a8 100644
> --- a/include/hw/virtio/virtio-net.h
> +++ b/include/hw/virtio/virtio-net.h
> @@ -36,6 +36,7 @@ typedef struct virtio_net_conf
>       int32_t txburst;
>       char *tx;
>       uint16_t rx_queue_size;
> +    uint16_t mtu;
>   } virtio_net_conf;
>   
>   /* Maximum packet size we can receive from tap device: header + 64k */
Maxime Coquelin Nov. 30, 2016, 12:24 p.m. UTC | #2
On 11/30/2016 12:24 PM, Jason Wang wrote:
>
>
> On 2016年11月30日 18:10, Maxime Coquelin wrote:
>> This patch allows advising guest with host MTU's by setting
>> host_mtu parameter.
>>
>> If VIRTIO_NET_F_MTU has been successfully negotiated, MTU
>> value is passed to the backend.
>>
>> Cc: Michael S. Tsirkin <mst@redhat.com>
>> Cc: Aaron Conole <aconole@redhat.com
>> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
>> ---
>>   hw/net/virtio-net.c            | 13 +++++++++++++
>>   include/hw/virtio/virtio-net.h |  1 +
>>   2 files changed, 14 insertions(+)
>>
>> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
>> index 5009533..5225e9b 100644
>> --- a/hw/net/virtio-net.c
>> +++ b/hw/net/virtio-net.c
>> @@ -55,6 +55,8 @@ static VirtIOFeature feature_sizes[] = {
>>        .end = endof(struct virtio_net_config, status)},
>>       {.flags = 1 << VIRTIO_NET_F_MQ,
>>        .end = endof(struct virtio_net_config, max_virtqueue_pairs)},
>> +    {.flags = 1 << VIRTIO_NET_F_MTU,
>> +     .end = endof(struct virtio_net_config, mtu)},
>>       {}
>>   };
>>   @@ -81,6 +83,7 @@ static void virtio_net_get_config(VirtIODevice
>> *vdev, uint8_t *config)
>>         virtio_stw_p(vdev, &netcfg.status, n->status);
>>       virtio_stw_p(vdev, &netcfg.max_virtqueue_pairs, n->max_queues);
>> +    virtio_stw_p(vdev, &netcfg.mtu, n->net_conf.mtu);
>>       memcpy(netcfg.mac, n->mac, ETH_ALEN);
>>       memcpy(config, &netcfg, n->config_size);
>>   }
>> @@ -152,6 +155,10 @@ static void virtio_net_vhost_status(VirtIONet *n,
>> uint8_t status)
>>               qemu_net_queue_purge(qnc->incoming_queue, qnc->peer);
>>           }
>>   +        if (virtio_has_feature(vdev->guest_features,
>> VIRTIO_NET_F_MTU)) {
>> +            vhost_net_set_mtu(get_vhost_net(nc->peer), n->net_conf.mtu);
>> +        }
>
> We'd better not ignore errors here and that's why we need management
> tool (who can make sure the mtu is set correctly before launching qemu).

Ok.
Currently, errors are reported if it failed to send the request
(protocol feature not present), maybe the request should require a
reply from the backend whether or not configured MTU is consistent
with what management tool set.

Make sense?

Thanks,
Maxime
diff mbox

Patch

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 5009533..5225e9b 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -55,6 +55,8 @@  static VirtIOFeature feature_sizes[] = {
      .end = endof(struct virtio_net_config, status)},
     {.flags = 1 << VIRTIO_NET_F_MQ,
      .end = endof(struct virtio_net_config, max_virtqueue_pairs)},
+    {.flags = 1 << VIRTIO_NET_F_MTU,
+     .end = endof(struct virtio_net_config, mtu)},
     {}
 };
 
@@ -81,6 +83,7 @@  static void virtio_net_get_config(VirtIODevice *vdev, uint8_t *config)
 
     virtio_stw_p(vdev, &netcfg.status, n->status);
     virtio_stw_p(vdev, &netcfg.max_virtqueue_pairs, n->max_queues);
+    virtio_stw_p(vdev, &netcfg.mtu, n->net_conf.mtu);
     memcpy(netcfg.mac, n->mac, ETH_ALEN);
     memcpy(config, &netcfg, n->config_size);
 }
@@ -152,6 +155,10 @@  static void virtio_net_vhost_status(VirtIONet *n, uint8_t status)
             qemu_net_queue_purge(qnc->incoming_queue, qnc->peer);
         }
 
+        if (virtio_has_feature(vdev->guest_features, VIRTIO_NET_F_MTU)) {
+            vhost_net_set_mtu(get_vhost_net(nc->peer), n->net_conf.mtu);
+        }
+
         n->vhost_started = 1;
         r = vhost_net_start(vdev, n->nic->ncs, queues);
         if (r < 0) {
@@ -1695,6 +1702,7 @@  static void virtio_net_set_config_size(VirtIONet *n, uint64_t host_features)
 {
     int i, config_size = 0;
     virtio_add_feature(&host_features, VIRTIO_NET_F_MAC);
+
     for (i = 0; feature_sizes[i].flags != 0; i++) {
         if (host_features & feature_sizes[i].flags) {
             config_size = MAX(feature_sizes[i].end, config_size);
@@ -1724,6 +1732,10 @@  static void virtio_net_device_realize(DeviceState *dev, Error **errp)
     NetClientState *nc;
     int i;
 
+    if (n->net_conf.mtu) {
+        n->host_features |= (0x1 << VIRTIO_NET_F_MTU);
+    }
+
     virtio_net_set_config_size(n, n->host_features);
     virtio_init(vdev, "virtio-net", VIRTIO_ID_NET, n->config_size);
 
@@ -1922,6 +1934,7 @@  static Property virtio_net_properties[] = {
     DEFINE_PROP_STRING("tx", VirtIONet, net_conf.tx),
     DEFINE_PROP_UINT16("rx_queue_size", VirtIONet, net_conf.rx_queue_size,
                        VIRTIO_NET_RX_QUEUE_DEFAULT_SIZE),
+    DEFINE_PROP_UINT16("host_mtu", VirtIONet, net_conf.mtu, 0),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index 0ced975..8ea56a8 100644
--- a/include/hw/virtio/virtio-net.h
+++ b/include/hw/virtio/virtio-net.h
@@ -36,6 +36,7 @@  typedef struct virtio_net_conf
     int32_t txburst;
     char *tx;
     uint16_t rx_queue_size;
+    uint16_t mtu;
 } virtio_net_conf;
 
 /* Maximum packet size we can receive from tap device: header + 64k */