From 7f9744812291853425b614f68668f48d49882a1f Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 2 Jun 2010 11:40:54 +0300 Subject: virtio-net: stop vhost backend on vmstop vhost net currently keeps running after vmstop, which causes trouble as qemy does not check for dirty pages anymore. The fix is to simply keep vm and vhost running/stopped status in sync. Tested-by: David L Stevens Signed-off-by: Michael S. Tsirkin --- hw/virtio-net.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/hw/virtio-net.c b/hw/virtio-net.c index cb664e6207..6a9d560a9b 100644 --- a/hw/virtio-net.c +++ b/hw/virtio-net.c @@ -877,12 +877,11 @@ static void virtio_net_set_status(struct VirtIODevice *vdev, uint8_t status) static void virtio_net_vmstate_change(void *opaque, int running, int reason) { VirtIONet *n = opaque; - if (!running) { - return; - } - /* This is called when vm is started, it will start vhost backend if - * appropriate e.g. after migration. */ - virtio_net_set_status(&n->vdev, n->vdev.status); + uint8_t status = running ? VIRTIO_CONFIG_S_DRIVER_OK : 0; + /* This is called when vm is started/stopped, + * it will start/stop vhost backend if * appropriate + * e.g. after migration. */ + virtio_net_set_status(&n->vdev, n->vdev.status & status); } VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf) -- cgit v1.2.3 From 940cda94dc01e955b6008c47b782817a1ed3b201 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 6 Jun 2010 18:53:10 +0300 Subject: virtio-net: truncating packet virtio net attempts to peek into virtio queue to determine that we have enough space for the complete packet to fit. However, it fails to account for space consumed by virtio net header when it does this, under stress this results in a failure with the message 'truncating packet'. redhat bz 591494. Signed-off-by: Michael S. Tsirkin --- hw/virtio-net.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/hw/virtio-net.c b/hw/virtio-net.c index 6a9d560a9b..06ba48103d 100644 --- a/hw/virtio-net.c +++ b/hw/virtio-net.c @@ -532,16 +532,17 @@ static ssize_t virtio_net_receive(VLANClientState *nc, const uint8_t *buf, size_ if (!virtio_net_can_receive(&n->nic->nc)) return -1; - if (!virtio_net_has_buffers(n, size)) + /* hdr_len refers to the header we supply to the guest */ + hdr_len = n->mergeable_rx_bufs ? + sizeof(struct virtio_net_hdr_mrg_rxbuf) : sizeof(struct virtio_net_hdr); + + + if (!virtio_net_has_buffers(n, size + hdr_len)) return 0; if (!receive_filter(n, buf, size)) return size; - /* hdr_len refers to the header we supply to the guest */ - hdr_len = n->mergeable_rx_bufs ? - sizeof(struct virtio_net_hdr_mrg_rxbuf) : sizeof(struct virtio_net_hdr); - offset = i = 0; while (offset < size) { @@ -555,7 +556,9 @@ static ssize_t virtio_net_receive(VLANClientState *nc, const uint8_t *buf, size_ virtqueue_pop(n->rx_vq, &elem) == 0) { if (i == 0) return -1; - fprintf(stderr, "virtio-net truncating packet\n"); + fprintf(stderr, "virtio-net truncating packet: " + "offset %zd, size %zd, hdr_len %zd\n", + offset, size, hdr_len); exit(1); } -- cgit v1.2.3 From 50e32ea8f31035877decc10f1075aa0e619e09cb Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Tue, 8 Jun 2010 21:13:58 +0530 Subject: net: Fix hotplug with pci_add The correct model type wasn't getting added when hotplugging nics with pci_add. Testcase: start VM with default nic type. In the qemu_monitor: (qemu) pci_add auto nic model=virtio This results in a nic hot-plug of the same nic type as the default. This was broken in 5294e2c774f120e10b44652ac143abda356f44eb Also changes the behaviour where no .init is defined for a net_client_type. Previously, 0 was returned, which indicated the init was successful and that 0 was the index into the nd_tables[] array. Return -1, indicating unsuccessful init, in such a case. Signed-off-by: Amit Shah Signed-off-by: Michael S. Tsirkin --- net.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/net.c b/net.c index 378edfccd0..22f5cf1f32 100644 --- a/net.c +++ b/net.c @@ -1106,6 +1106,7 @@ int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev) for (i = 0; net_client_types[i].type != NULL; i++) { if (!strcmp(net_client_types[i].type, type)) { VLANState *vlan = NULL; + int ret; if (qemu_opts_validate(opts, &net_client_types[i].desc[0]) == -1) { return -1; @@ -1118,14 +1119,16 @@ int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev) vlan = qemu_find_vlan(qemu_opt_get_number(opts, "vlan", 0), 1); } + ret = -1; if (net_client_types[i].init) { - if (net_client_types[i].init(opts, mon, name, vlan) < 0) { + ret = net_client_types[i].init(opts, mon, name, vlan); + if (ret < 0) { /* TODO push error reporting into init() methods */ qerror_report(QERR_DEVICE_INIT_FAILED, type); return -1; } } - return 0; + return ret; } } -- cgit v1.2.3