aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHuaitong Han <hanht2@chinatelecom.cn>2025-05-22 18:05:48 +0800
committerMichael S. Tsirkin <mst@redhat.com>2025-06-02 14:29:15 -0400
commita9403bfcd93025df7b1924d0cf34fbc408955b33 (patch)
treedf88014dfbbc632cea4f798e7cae0b86e687dd5c
parent82acc8c83f93814bb01669412a0a226c39fa8d77 (diff)
downloadqemu-a9403bfcd93025df7b1924d0cf34fbc408955b33.zip
qemu-a9403bfcd93025df7b1924d0cf34fbc408955b33.tar.gz
qemu-a9403bfcd93025df7b1924d0cf34fbc408955b33.tar.bz2
vhost: Don't set vring call if guest notifier is unused
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>
-rw-r--r--hw/pci/pci.c2
-rw-r--r--hw/virtio/virtio-pci.c7
-rw-r--r--include/hw/pci/pci.h1
3 files changed, 8 insertions, 2 deletions
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index c6b5768..9b4bf48 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -1730,7 +1730,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;
}
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 9b48aa8..7e309d1 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1215,7 +1215,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)
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index a6854da..35d59d7 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -983,6 +983,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 void pci_irq_assert(PCIDevice *pci_dev)
{