Skip to contentSkip to conversation

msix: make [un]use vectors on reset/load optional

PATCH In review Michael S. Tsirkin 4 participants 9 messages Aug 29, 2012 – Aug 30, 2012

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 msix: make [un]use vectors on reset/load optional

The facility to use/unuse vectors dynamically is helpful for virtio but little else: everyone just seems to use vectors in their init function.

Avoid clearing msix vector use info on reset and load. For virtio, clear it explicitly.
This should fix regressions reported with ivshmem - though I didn't test this, I verified that virtio keeps working like it did.

---
 hw/msix.c       | 13 +++++++++++--
 hw/virtio-pci.c |  2 ++
 2 files changed, 13 insertions(+), 2 deletions(-)
hw/msix.c +11 -2
index 800fc32..d040cc2 100644
@@ -340,6 +340,15 @@ static void msix_free_irq_entries(PCIDevice *dev)
     }
 }
 
+static void msix_clear_all_vectors(PCIDevice *dev)
+{
+    int vector;
+
+    for (vector = 0; vector < dev->msix_entries_nr; ++vector) {
+        msix_clr_pending(dev, vector);
+    }
+}
+
 /* Clean up resources for the device. */
 void msix_uninit(PCIDevice *dev, MemoryRegion *table_bar, MemoryRegion *pba_bar)
 {
@@ -394,7 +403,7 @@ void msix_load(PCIDevice *dev, QEMUFile *f)
         return;
     }
 
-    msix_free_irq_entries(dev);
+    msix_clear_all_vectors(dev);
     qemu_get_buffer(f, dev->msix_table, n * PCI_MSIX_ENTRY_SIZE);
     qemu_get_buffer(f, dev->msix_pba, (n + 7) / 8);
     msix_update_function_masked(dev);
@@ -440,7 +449,7 @@ void msix_reset(PCIDevice *dev)
     if (!msix_present(dev)) {
         return;
     }
-    msix_free_irq_entries(dev);
+    msix_clear_all_vectors(dev);
     dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &=
 	    ~dev->wmask[dev->msix_cap + MSIX_CONTROL_OFFSET];
     memset(dev->msix_table, 0, dev->msix_entries_nr * PCI_MSIX_ENTRY_SIZE);
hw/virtio-pci.c +2 -0
index 125eded..ca0b204 100644
@@ -131,6 +131,7 @@ static int virtio_pci_load_config(void * opaque, QEMUFile *f)
     if (ret) {
         return ret;
     }
+    msix_unuse_all_vectors(&proxy->pci_dev);
     msix_load(&proxy->pci_dev, f);
     if (msix_present(&proxy->pci_dev)) {
         qemu_get_be16s(f, &proxy->vdev->config_vector);
@@ -246,6 +247,7 @@ void virtio_pci_reset(DeviceState *d)
     VirtIOPCIProxy *proxy = container_of(d, VirtIOPCIProxy, pci_dev.qdev);
     virtio_pci_stop_ioeventfd(proxy);
     virtio_reset(proxy->vdev);
+    msix_unuse_all_vectors(&proxy->pci_dev);
     proxy->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
 }
 
Signature · 1 line
MST
#1 lore raw
Quoted 68 lines · Michael S. Tsirkin

The facility to use/unuse vectors dynamically is helpful for virtio but little else: everyone just seems to use vectors in their init function.

Avoid clearing msix vector use info on reset and load. For virtio, clear it explicitly.
This should fix regressions reported with ivshmem - though I didn't test this, I verified that virtio keeps working like it did.

---
 hw/msix.c       | 13 +++++++++++--
 hw/virtio-pci.c |  2 ++
 2 files changed, 13 insertions(+), 2 deletions(-)
hw/msix.c +11 -2
index 800fc32..d040cc2 100644
@@ -340,6 +340,15 @@ static void msix_free_irq_entries(PCIDevice *dev)
     }
 }
 
+static void msix_clear_all_vectors(PCIDevice *dev)
+{
+    int vector;
+
+    for (vector = 0; vector < dev->msix_entries_nr; ++vector) {
+        msix_clr_pending(dev, vector);
+    }
+}
+
 /* Clean up resources for the device. */
 void msix_uninit(PCIDevice *dev, MemoryRegion *table_bar, MemoryRegion *pba_bar)
 {
@@ -394,7 +403,7 @@ void msix_load(PCIDevice *dev, QEMUFile *f)
         return;
     }
 
-    msix_free_irq_entries(dev);
+    msix_clear_all_vectors(dev);
     qemu_get_buffer(f, dev->msix_table, n * PCI_MSIX_ENTRY_SIZE);
     qemu_get_buffer(f, dev->msix_pba, (n + 7) / 8);
     msix_update_function_masked(dev);
@@ -440,7 +449,7 @@ void msix_reset(PCIDevice *dev)
     if (!msix_present(dev)) {
         return;
     }
-    msix_free_irq_entries(dev);
+    msix_clear_all_vectors(dev);
     dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &=
 	    ~dev->wmask[dev->msix_cap + MSIX_CONTROL_OFFSET];
     memset(dev->msix_table, 0, dev->msix_entries_nr * PCI_MSIX_ENTRY_SIZE);
hw/virtio-pci.c +1 -0
index 125eded..ca0b204 100644
@@ -131,6 +131,7 @@ static int virtio_pci_load_config(void * opaque, QEMUFile *f)
     if (ret) {
         return ret;
     }
+    msix_unuse_all_vectors(&proxy->pci_dev);
     msix_load(&proxy->pci_dev, f);
     if (msix_present(&proxy->pci_dev)) {
         qemu_get_be16s(f, &proxy->vdev->config_vector);

hw/virtio-pci.c void virtio_pci_reset(DeviceState *d) · line 253

Quoted 7 lines
hw/virtio-pci.c +1 -0
@@ -246,6 +247,7 @@ void virtio_pci_reset(DeviceState *d)
     VirtIOPCIProxy *proxy = container_of(d, VirtIOPCIProxy, pci_dev.qdev);
     virtio_pci_stop_ioeventfd(proxy);
     virtio_reset(proxy->vdev);
+    msix_unuse_all_vectors(&proxy->pci_dev);
     proxy->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
 }
 

Fine with me, but let's ask Cam to test.

Jan

Signature · 2 lines
Siemens AG, Corporate Technology, CT RTC ITP SDP-DE
Corporate Competence Center Embedded Linux
#2 lore raw
Quoted 79 lines · Jan Kiszka
Quoted 68 lines · Michael S. Tsirkin

The facility to use/unuse vectors dynamically is helpful for virtio but little else: everyone just seems to use vectors in their init function.

Avoid clearing msix vector use info on reset and load. For virtio, clear it explicitly.
This should fix regressions reported with ivshmem - though I didn't test this, I verified that virtio keeps working like it did.

---
 hw/msix.c       | 13 +++++++++++--
 hw/virtio-pci.c |  2 ++
 2 files changed, 13 insertions(+), 2 deletions(-)
hw/msix.c +11 -2
index 800fc32..d040cc2 100644
@@ -340,6 +340,15 @@ static void msix_free_irq_entries(PCIDevice *dev)
     }
 }
 
+static void msix_clear_all_vectors(PCIDevice *dev)
+{
+    int vector;
+
+    for (vector = 0; vector < dev->msix_entries_nr; ++vector) {
+        msix_clr_pending(dev, vector);
+    }
+}
+
 /* Clean up resources for the device. */
 void msix_uninit(PCIDevice *dev, MemoryRegion *table_bar, MemoryRegion *pba_bar)
 {
@@ -394,7 +403,7 @@ void msix_load(PCIDevice *dev, QEMUFile *f)
         return;
     }
 
-    msix_free_irq_entries(dev);
+    msix_clear_all_vectors(dev);
     qemu_get_buffer(f, dev->msix_table, n * PCI_MSIX_ENTRY_SIZE);
     qemu_get_buffer(f, dev->msix_pba, (n + 7) / 8);
     msix_update_function_masked(dev);
@@ -440,7 +449,7 @@ void msix_reset(PCIDevice *dev)
     if (!msix_present(dev)) {
         return;
     }
-    msix_free_irq_entries(dev);
+    msix_clear_all_vectors(dev);
     dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &=
 	    ~dev->wmask[dev->msix_cap + MSIX_CONTROL_OFFSET];
     memset(dev->msix_table, 0, dev->msix_entries_nr * PCI_MSIX_ENTRY_SIZE);
hw/virtio-pci.c +1 -0
index 125eded..ca0b204 100644
@@ -131,6 +131,7 @@ static int virtio_pci_load_config(void * opaque, QEMUFile *f)
     if (ret) {
         return ret;
     }
+    msix_unuse_all_vectors(&proxy->pci_dev);
     msix_load(&proxy->pci_dev, f);
     if (msix_present(&proxy->pci_dev)) {
         qemu_get_be16s(f, &proxy->vdev->config_vector);

hw/virtio-pci.c void virtio_pci_reset(DeviceState *d) · line 253

Quoted 7 lines
hw/virtio-pci.c +1 -0
@@ -246,6 +247,7 @@ void virtio_pci_reset(DeviceState *d)
     VirtIOPCIProxy *proxy = container_of(d, VirtIOPCIProxy, pci_dev.qdev);
     virtio_pci_stop_ioeventfd(proxy);
     virtio_reset(proxy->vdev);
+    msix_unuse_all_vectors(&proxy->pci_dev);
     proxy->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
 }
 

Fine with me, but let's ask Cam to test.

Quoted 1 line

Jan

Cam deadline is today - can u test quickly pls?

Quoted 3 lines
Signature · 2 lines
Siemens AG, Corporate Technology, CT RTC ITP SDP-DE
Corporate Competence Center Embedded Linux
#3 lore raw

Yes, will test shortly.

Cam

Quoted 88 lines · Michael S. Tsirkin
Quoted 79 lines · Jan Kiszka
Quoted 68 lines · Michael S. Tsirkin

The facility to use/unuse vectors dynamically is helpful for virtio but little else: everyone just seems to use vectors in their init function.

Avoid clearing msix vector use info on reset and load. For virtio, clear it explicitly.
This should fix regressions reported with ivshmem - though I didn't test this, I verified that virtio keeps working like it did.

---
 hw/msix.c       | 13 +++++++++++--
 hw/virtio-pci.c |  2 ++
 2 files changed, 13 insertions(+), 2 deletions(-)
hw/msix.c +11 -2
index 800fc32..d040cc2 100644
@@ -340,6 +340,15 @@ static void msix_free_irq_entries(PCIDevice *dev)
     }
 }
 
+static void msix_clear_all_vectors(PCIDevice *dev)
+{
+    int vector;
+
+    for (vector = 0; vector < dev->msix_entries_nr; ++vector) {
+        msix_clr_pending(dev, vector);
+    }
+}
+
 /* Clean up resources for the device. */
 void msix_uninit(PCIDevice *dev, MemoryRegion *table_bar, MemoryRegion *pba_bar)
 {
@@ -394,7 +403,7 @@ void msix_load(PCIDevice *dev, QEMUFile *f)
         return;
     }
 
-    msix_free_irq_entries(dev);
+    msix_clear_all_vectors(dev);
     qemu_get_buffer(f, dev->msix_table, n * PCI_MSIX_ENTRY_SIZE);
     qemu_get_buffer(f, dev->msix_pba, (n + 7) / 8);
     msix_update_function_masked(dev);
@@ -440,7 +449,7 @@ void msix_reset(PCIDevice *dev)
     if (!msix_present(dev)) {
         return;
     }
-    msix_free_irq_entries(dev);
+    msix_clear_all_vectors(dev);
     dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &=
        ~dev->wmask[dev->msix_cap + MSIX_CONTROL_OFFSET];
     memset(dev->msix_table, 0, dev->msix_entries_nr * PCI_MSIX_ENTRY_SIZE);
hw/virtio-pci.c +1 -0
index 125eded..ca0b204 100644
@@ -131,6 +131,7 @@ static int virtio_pci_load_config(void * opaque, QEMUFile *f)
     if (ret) {
         return ret;
     }
+    msix_unuse_all_vectors(&proxy->pci_dev);
     msix_load(&proxy->pci_dev, f);
     if (msix_present(&proxy->pci_dev)) {
         qemu_get_be16s(f, &proxy->vdev->config_vector);

hw/virtio-pci.c void virtio_pci_reset(DeviceState *d) · line 253

Quoted 7 lines
hw/virtio-pci.c +1 -0
@@ -246,6 +247,7 @@ void virtio_pci_reset(DeviceState *d)
     VirtIOPCIProxy *proxy = container_of(d, VirtIOPCIProxy, pci_dev.qdev);
     virtio_pci_stop_ioeventfd(proxy);
     virtio_reset(proxy->vdev);
+    msix_unuse_all_vectors(&proxy->pci_dev);
     proxy->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
 }
 

Fine with me, but let's ask Cam to test.

Quoted 1 line

Jan

Cam deadline is today - can u test quickly pls?

Quoted 3 lines

--
Siemens AG, Corporate Technology, CT RTC ITP SDP-DE Corporate Competence Center Embedded Linux

#4 lore raw
In reply to Michael S. Tsirkin

$subject: "[un]used vectors"? -- could be fixed by committer.

/-F

Am 29.08.2012 18:40, schrieb Michael S. Tsirkin:

Quoted 11 lines

The facility to use/unuse vectors dynamically is helpful for virtio but little else: everyone just seems to use vectors in their init function.

Avoid clearing msix vector use info on reset and load. For virtio, clear it explicitly.
This should fix regressions reported with ivshmem - though I didn't test this, I verified that virtio keeps working like it did.

Signature · 2 lines
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
#5 lore raw
Quoted 3 lines · Andreas Färber

$subject: "[un]used vectors"? -- could be fixed by committer.

/-F

Sorry I don't unedrstand. it's not 'unused': it's use and unuse. What is wrong with the subject?

Quoted 16 lines

Am 29.08.2012 18:40, schrieb Michael S. Tsirkin:

Quoted 11 lines

The facility to use/unuse vectors dynamically is helpful for virtio but little else: everyone just seems to use vectors in their init function.

Avoid clearing msix vector use info on reset and load. For virtio, clear it explicitly.
This should fix regressions reported with ivshmem - though I didn't test this, I verified that virtio keeps working like it did.

Signature · 2 lines
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
#6 lore raw

Am 29.08.2012 20:13, schrieb Michael S. Tsirkin:

Quoted 5 lines · Andreas Färber
Quoted 1 line

$subject: "[un]used vectors"? -- could be fixed by committer.

Sorry I don't unedrstand. it's not 'unused': it's use and unuse. What is wrong with the subject?

The grammar with two verbs "make [un]use" sounded wrong to my ears. Given your explanation of [un]use above, did you mean "make clearing [un]use vectors optional on reset/load" or something like that?

/-F

Signature · 2 lines
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
#7 lore raw
Quoted 4 lines · Andreas Färber

Am 29.08.2012 20:13, schrieb Michael S. Tsirkin:

Quoted 3 lines · Andreas Färber
Quoted 1 line

$subject: "[un]used vectors"? -- could be fixed by committer.

Quoted 8 lines
Quoted 2 lines

Sorry I don't unedrstand. it's not 'unused': it's use and unuse. What is wrong with the subject?

The grammar with two verbs "make [un]use" sounded wrong to my ears. Given your explanation of [un]use above, did you mean "make clearing [un]use vectors optional on reset/load" or something like that?

/-F

No, sorry. What is meant is simply functions
msix_vector_use/msix_vector_unuse:
calling these on reset/load was required but
is now optional.

Quoted 3 lines
Signature · 2 lines
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Tested-by on v1 1/1
#8 lore raw
In reply to Michael S. Tsirkin

Yes, works for me.

Quoted 11 lines · Michael S. Tsirkin

The facility to use/unuse vectors dynamically is helpful for virtio but little else: everyone just seems to use vectors in their init function.

Avoid clearing msix vector use info on reset and load. For virtio, clear it explicitly.
This should fix regressions reported with ivshmem - though I didn't test this, I verified that virtio keeps working like it did.

Quoted 66 lines
---
 hw/msix.c       | 13 +++++++++++--
 hw/virtio-pci.c |  2 ++
 2 files changed, 13 insertions(+), 2 deletions(-)
hw/msix.c +11 -2
index 800fc32..d040cc2 100644
@@ -340,6 +340,15 @@ static void msix_free_irq_entries(PCIDevice *dev)
     }
 }
 
+static void msix_clear_all_vectors(PCIDevice *dev)
+{
+    int vector;
+
+    for (vector = 0; vector < dev->msix_entries_nr; ++vector) {
+        msix_clr_pending(dev, vector);
+    }
+}
+
 /* Clean up resources for the device. */
 void msix_uninit(PCIDevice *dev, MemoryRegion *table_bar, MemoryRegion *pba_bar)
 {
@@ -394,7 +403,7 @@ void msix_load(PCIDevice *dev, QEMUFile *f)
         return;
     }
 
-    msix_free_irq_entries(dev);
+    msix_clear_all_vectors(dev);
     qemu_get_buffer(f, dev->msix_table, n * PCI_MSIX_ENTRY_SIZE);
     qemu_get_buffer(f, dev->msix_pba, (n + 7) / 8);
     msix_update_function_masked(dev);
@@ -440,7 +449,7 @@ void msix_reset(PCIDevice *dev)
     if (!msix_present(dev)) {
         return;
     }
-    msix_free_irq_entries(dev);
+    msix_clear_all_vectors(dev);
     dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &=
            ~dev->wmask[dev->msix_cap + MSIX_CONTROL_OFFSET];
     memset(dev->msix_table, 0, dev->msix_entries_nr * PCI_MSIX_ENTRY_SIZE);
hw/virtio-pci.c +2 -1
index 125eded..ca0b204 100644
@@ -131,6 +131,7 @@ static int virtio_pci_load_config(void * opaque, QEMUFile *f)
     if (ret) {
         return ret;
     }
+    msix_unuse_all_vectors(&proxy->pci_dev);
     msix_load(&proxy->pci_dev, f);
     if (msix_present(&proxy->pci_dev)) {
         qemu_get_be16s(f, &proxy->vdev->config_vector);
@@ -246,6 +247,7 @@ void virtio_pci_reset(DeviceState *d)
     VirtIOPCIProxy *proxy = container_of(d, VirtIOPCIProxy, pci_dev.qdev);
     virtio_pci_stop_ioeventfd(proxy);
     virtio_reset(proxy->vdev);
+    msix_unuse_all_vectors(&proxy->pci_dev);
     proxy->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
 }
 
--

MST