From 6c6668232e71b7cf7ff39fa1a7abf660c40f9cea Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 4 Jul 2016 14:47:37 +0300 Subject: Revert "virtio-net: unbreak self announcement and guest offloads after migration" This reverts commit 1f8828ef573c83365b4a87a776daf8bcef1caa21. Cc: qemu-stable@nongnu.org Reported-by: Robin Geuze Tested-by: Robin Geuze Signed-off-by: Michael S. Tsirkin --- hw/net/virtio-net.c | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) (limited to 'hw/net') diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 7e6a60aa12..999989934e 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -1542,33 +1542,11 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id) { VirtIONet *n = opaque; VirtIODevice *vdev = VIRTIO_DEVICE(n); - int ret; if (version_id < 2 || version_id > VIRTIO_NET_VM_VERSION) return -EINVAL; - ret = virtio_load(vdev, f, version_id); - if (ret) { - return ret; - } - - if (virtio_vdev_has_feature(vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)) { - n->curr_guest_offloads = qemu_get_be64(f); - } else { - n->curr_guest_offloads = virtio_net_supported_guest_offloads(n); - } - - if (peer_has_vnet_hdr(n)) { - virtio_net_apply_guest_offloads(n); - } - - if (virtio_vdev_has_feature(vdev, VIRTIO_NET_F_GUEST_ANNOUNCE) && - virtio_vdev_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ)) { - n->announce_counter = SELF_ANNOUNCE_ROUNDS; - timer_mod(n->announce_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL)); - } - - return 0; + return virtio_load(vdev, f, version_id); } static int virtio_net_load_device(VirtIODevice *vdev, QEMUFile *f, @@ -1665,6 +1643,16 @@ static int virtio_net_load_device(VirtIODevice *vdev, QEMUFile *f, } } + if (virtio_vdev_has_feature(vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)) { + n->curr_guest_offloads = qemu_get_be64(f); + } else { + n->curr_guest_offloads = virtio_net_supported_guest_offloads(n); + } + + if (peer_has_vnet_hdr(n)) { + virtio_net_apply_guest_offloads(n); + } + virtio_net_set_queues(n); /* Find the first multicast entry in the saved MAC filter */ @@ -1682,6 +1670,12 @@ static int virtio_net_load_device(VirtIODevice *vdev, QEMUFile *f, qemu_get_subqueue(n->nic, i)->link_down = link_down; } + if (virtio_vdev_has_feature(vdev, VIRTIO_NET_F_GUEST_ANNOUNCE) && + virtio_vdev_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ)) { + n->announce_counter = SELF_ANNOUNCE_ROUNDS; + timer_mod(n->announce_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL)); + } + return 0; } -- cgit v1.2.3 From 1108b2f8a939fb5778d384149e2f1b99062a72da Mon Sep 17 00:00:00 2001 From: Cao jin Date: Mon, 20 Jun 2016 14:13:39 +0800 Subject: pci: Convert msi_init() to Error and fix callers to check it msi_init() reports errors with error_report(), which is wrong when it's used in realize(). Fix by converting it to Error. Fix its callers to handle failure instead of ignoring it. For those callers who don't handle the failure, it might happen: when user want msi on, but he doesn't get what he want because of msi_init fails silently. cc: Gerd Hoffmann cc: John Snow cc: Dmitry Fleytman cc: Jason Wang cc: Michael S. Tsirkin cc: Hannes Reinecke cc: Paolo Bonzini cc: Alex Williamson cc: Markus Armbruster cc: Marcel Apfelbaum Reviewed-by: Markus Armbruster Signed-off-by: Cao jin Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Hannes Reinecke --- hw/net/e1000e.c | 8 ++------ hw/net/vmxnet3.c | 37 ++++++++++++------------------------- 2 files changed, 14 insertions(+), 31 deletions(-) (limited to 'hw/net') diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c index 692283fdd7..a06d1848d2 100644 --- a/hw/net/e1000e.c +++ b/hw/net/e1000e.c @@ -268,13 +268,9 @@ e1000e_init_msi(E1000EState *s) { int res; - res = msi_init(PCI_DEVICE(s), - 0xD0, /* MSI capability offset */ - 1, /* MAC MSI interrupts */ - true, /* 64-bit message addresses supported */ - false); /* Per vector mask supported */ + res = msi_init(PCI_DEVICE(s), 0xD0, 1, true, false, NULL); - if (res > 0) { + if (!res) { s->intr_state |= E1000E_USE_MSI; } else { trace_e1000e_msi_init_fail(res); diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 92236d3919..f24298cc49 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -2216,27 +2216,6 @@ vmxnet3_cleanup_msix(VMXNET3State *s) } } -#define VMXNET3_USE_64BIT (true) -#define VMXNET3_PER_VECTOR_MASK (false) - -static bool -vmxnet3_init_msi(VMXNET3State *s) -{ - PCIDevice *d = PCI_DEVICE(s); - int res; - - res = msi_init(d, VMXNET3_MSI_OFFSET(s), VMXNET3_MAX_NMSIX_INTRS, - VMXNET3_USE_64BIT, VMXNET3_PER_VECTOR_MASK); - if (0 > res) { - VMW_WRPRN("Failed to initialize MSI, error %d", res); - s->msi_used = false; - } else { - s->msi_used = true; - } - - return s->msi_used; -} - static void vmxnet3_cleanup_msi(VMXNET3State *s) { @@ -2298,10 +2277,15 @@ static uint64_t vmxnet3_device_serial_num(VMXNET3State *s) return dsn_payload; } + +#define VMXNET3_USE_64BIT (true) +#define VMXNET3_PER_VECTOR_MASK (false) + static void vmxnet3_pci_realize(PCIDevice *pci_dev, Error **errp) { DeviceState *dev = DEVICE(pci_dev); VMXNET3State *s = VMXNET3(pci_dev); + int ret; VMW_CBPRN("Starting init..."); @@ -2325,14 +2309,17 @@ static void vmxnet3_pci_realize(PCIDevice *pci_dev, Error **errp) /* Interrupt pin A */ pci_dev->config[PCI_INTERRUPT_PIN] = 0x01; + ret = msi_init(pci_dev, VMXNET3_MSI_OFFSET(s), VMXNET3_MAX_NMSIX_INTRS, + VMXNET3_USE_64BIT, VMXNET3_PER_VECTOR_MASK, NULL); + /* Any error other than -ENOTSUP(board's MSI support is broken) + * is a programming error. Fall back to INTx silently on -ENOTSUP */ + assert(!ret || ret == -ENOTSUP); + s->msi_used = !ret; + if (!vmxnet3_init_msix(s)) { VMW_WRPRN("Failed to initialize MSI-X, configuration is inconsistent."); } - if (!vmxnet3_init_msi(s)) { - VMW_WRPRN("Failed to initialize MSI, configuration is inconsistent."); - } - vmxnet3_net_init(s); if (pci_is_express(pci_dev)) { -- cgit v1.2.3 From 1070048eae6d1adb971af749c92ef39a3168cfb4 Mon Sep 17 00:00:00 2001 From: Cao jin Date: Mon, 20 Jun 2016 14:13:42 +0800 Subject: vmxnet3: remove unnecessary internal msi state flag Internal flag msi_used is unnecessary, it has the same effect as msi_enabled(). msi_uninit() could be called directly without risk. cc: Paolo Bonzini cc: Dmitry Fleytman cc: Markus Armbruster cc: Marcel Apfelbaum cc: Michael S. Tsirkin Reviewed-by: Markus Armbruster Signed-off-by: Cao jin Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/net/vmxnet3.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) (limited to 'hw/net') diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index f24298cc49..5994890691 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -283,8 +283,6 @@ typedef struct { /* Whether MSI-X support was installed successfully */ bool msix_used; - /* Whether MSI support was installed successfully */ - bool msi_used; hwaddr drv_shmem; hwaddr temp_shared_guest_driver_memory; @@ -366,7 +364,7 @@ static bool _vmxnet3_assert_interrupt_line(VMXNET3State *s, uint32_t int_idx) msix_notify(d, int_idx); return false; } - if (s->msi_used && msi_enabled(d)) { + if (msi_enabled(d)) { VMW_IRPRN("Sending MSI notification for vector %u", int_idx); msi_notify(d, int_idx); return false; @@ -390,7 +388,7 @@ static void _vmxnet3_deassert_interrupt_line(VMXNET3State *s, int lidx) * This function should never be called for MSI(X) interrupts * because deassertion never required for message interrupts */ - assert(!s->msi_used || !msi_enabled(d)); + assert(!msi_enabled(d)); VMW_IRPRN("Deasserting line for interrupt %u", lidx); pci_irq_deassert(d); @@ -427,7 +425,7 @@ static void vmxnet3_trigger_interrupt(VMXNET3State *s, int lidx) goto do_automask; } - if (s->msi_used && msi_enabled(d) && s->auto_int_masking) { + if (msi_enabled(d) && s->auto_int_masking) { goto do_automask; } @@ -1425,8 +1423,8 @@ static void vmxnet3_update_features(VMXNET3State *s) static bool vmxnet3_verify_intx(VMXNET3State *s, int intx) { - return s->msix_used || s->msi_used || (intx == - (pci_get_byte(s->parent_obj.config + PCI_INTERRUPT_PIN) - 1)); + return s->msix_used || msi_enabled(PCI_DEVICE(s)) + || intx == pci_get_byte(s->parent_obj.config + PCI_INTERRUPT_PIN) - 1; } static void vmxnet3_validate_interrupt_idx(bool is_msix, int idx) @@ -2221,9 +2219,7 @@ vmxnet3_cleanup_msi(VMXNET3State *s) { PCIDevice *d = PCI_DEVICE(s); - if (s->msi_used) { - msi_uninit(d); - } + msi_uninit(d); } static void @@ -2314,7 +2310,6 @@ static void vmxnet3_pci_realize(PCIDevice *pci_dev, Error **errp) /* Any error other than -ENOTSUP(board's MSI support is broken) * is a programming error. Fall back to INTx silently on -ENOTSUP */ assert(!ret || ret == -ENOTSUP); - s->msi_used = !ret; if (!vmxnet3_init_msix(s)) { VMW_WRPRN("Failed to initialize MSI-X, configuration is inconsistent."); -- cgit v1.2.3 From 66bf7d58d830e6370895e4f1bb1257d135661872 Mon Sep 17 00:00:00 2001 From: Cao jin Date: Mon, 20 Jun 2016 14:13:43 +0800 Subject: e1000e: remove unnecessary internal msi state flag Internal big flag E1000E_USE_MSI is unnecessary, also is the helper function: e1000e_init_msi(), e1000e_cleanup_msi(), so, remove them all. cc: Dmitry Fleytman cc: Jason Wang cc: Markus Armbruster cc: Marcel Apfelbaum cc: Michael S. Tsirkin Signed-off-by: Cao jin Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Markus Armbruster --- hw/net/e1000e.c | 33 +++++++-------------------------- 1 file changed, 7 insertions(+), 26 deletions(-) (limited to 'hw/net') diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c index a06d1848d2..c7d33ee395 100644 --- a/hw/net/e1000e.c +++ b/hw/net/e1000e.c @@ -89,8 +89,7 @@ typedef struct E1000EState { #define E1000E_MSIX_TABLE (0x0000) #define E1000E_MSIX_PBA (0x2000) -#define E1000E_USE_MSI BIT(0) -#define E1000E_USE_MSIX BIT(1) +#define E1000E_USE_MSIX BIT(0) static uint64_t e1000e_mmio_read(void *opaque, hwaddr addr, unsigned size) @@ -263,28 +262,6 @@ static void e1000e_core_realize(E1000EState *s) s->core.owner_nic = s->nic; } -static void -e1000e_init_msi(E1000EState *s) -{ - int res; - - res = msi_init(PCI_DEVICE(s), 0xD0, 1, true, false, NULL); - - if (!res) { - s->intr_state |= E1000E_USE_MSI; - } else { - trace_e1000e_msi_init_fail(res); - } -} - -static void -e1000e_cleanup_msi(E1000EState *s) -{ - if (s->intr_state & E1000E_USE_MSI) { - msi_uninit(PCI_DEVICE(s)); - } -} - static void e1000e_unuse_msix_vectors(E1000EState *s, int num_vectors) { @@ -440,6 +417,7 @@ static void e1000e_pci_realize(PCIDevice *pci_dev, Error **errp) static const uint16_t e1000e_dsn_offset = 0x140; E1000EState *s = E1000E(pci_dev); uint8_t *macaddr; + int ret; trace_e1000e_cb_pci_realize(); @@ -489,7 +467,10 @@ static void e1000e_pci_realize(PCIDevice *pci_dev, Error **errp) hw_error("Failed to initialize PCIe capability"); } - e1000e_init_msi(s); + ret = msi_init(PCI_DEVICE(s), 0xD0, 1, true, false, NULL); + if (ret) { + trace_e1000e_msi_init_fail(ret); + } if (e1000e_add_pm_capability(pci_dev, e1000e_pmrb_offset, PCI_PM_CAP_DSI) < 0) { @@ -528,7 +509,7 @@ static void e1000e_pci_uninit(PCIDevice *pci_dev) qemu_del_nic(s->nic); e1000e_cleanup_msix(s); - e1000e_cleanup_msi(s); + msi_uninit(pci_dev); } static void e1000e_qdev_reset(DeviceState *dev) -- cgit v1.2.3