]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
vhost: Don't set vring call if guest notifier is unused
authorHuaitong Han <hanht2@chinatelecom.cn>
Thu, 22 May 2025 10:05:48 +0000 (18:05 +0800)
committerMichael Tokarev <mjt@tls.msk.ru>
Mon, 2 Jun 2025 20:50:21 +0000 (23:50 +0300)
The vring call fd is set even when the guest does not use MSI-X (e.g., in the
case of virtio PMD), leading to unnecessary CPU overhead for processing
interrupts.

The commit 96a3d98d2c("vhost: don't set vring call if no vector") optimized the
case where MSI-X is enabled but the queue vector is unset. However, there's an
additional case where the guest uses INTx and the INTx_DISABLED bit in the PCI
config is set, meaning that no interrupt notifier will actually be used.

In such cases, the vring call fd should also be cleared to avoid redundant
interrupt handling.

Fixes: 96a3d98d2c("vhost: don't set vring call if no vector")
Reported-by: Zhiyuan Yuan <yuanzhiyuan@chinatelecom.cn>
Signed-off-by: Jidong Xia <xiajd@chinatelecom.cn>
Signed-off-by: Huaitong Han <hanht2@chinatelecom.cn>
Message-Id: <20250522100548.212740-1-hanht2@chinatelecom.cn>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit a9403bfcd93025df7b1924d0cf34fbc408955b33)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
hw/pci/pci.c
hw/virtio/virtio-pci.c
include/hw/pci/pci.h

index 2f450f6a728ed9a7c3cadfff4b144fd0bdc5ef50..c389172f27c8b6ffccc1b9f137452396ad676662 100644 (file)
@@ -1484,7 +1484,7 @@ static void pci_update_mappings(PCIDevice *d)
     pci_update_vga(d);
 }
 
-static inline int pci_irq_disabled(PCIDevice *d)
+int pci_irq_disabled(PCIDevice *d)
 {
     return pci_get_word(d->config + PCI_COMMAND) & PCI_COMMAND_INTX_DISABLE;
 }
index e5e74a71605ab917e5fd33b4e3985f7856bf12ce..a447a2bd0f134f9b7e991fc55c9ebc3c2c5db4a9 100644 (file)
@@ -1040,7 +1040,12 @@ static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign,
 static bool virtio_pci_query_guest_notifiers(DeviceState *d)
 {
     VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
-    return msix_enabled(&proxy->pci_dev);
+
+    if (msix_enabled(&proxy->pci_dev)) {
+        return true;
+    } else {
+        return pci_irq_disabled(&proxy->pci_dev);
+    }
 }
 
 static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
index 6ccaaf5154825417a5a838e0161805e1f59f832d..9c3fe5632318697a2e9f5765fea4dcc9cb132fe2 100644 (file)
@@ -749,6 +749,7 @@ void lsi53c8xx_handle_legacy_cmdline(DeviceState *lsi_dev);
 
 qemu_irq pci_allocate_irq(PCIDevice *pci_dev);
 void pci_set_irq(PCIDevice *pci_dev, int level);
+int pci_irq_disabled(PCIDevice *d);
 
 static inline int pci_intx(PCIDevice *pci_dev)
 {