Thanks for the patch!
I an waiting for Stefan's comments to be addressed.
Additionally, something to improve:

On Wed, Mar 26, 2025 at 04:25:37PM +0800, oen...@gmail.com wrote:
> From: Huaitong Han <han...@chinatelecom.cn>
> 
> The vring call fd is set even when the guest does not use msix (e.g., in the
> case of virtio pmd), leading to unnecessary CPU overhead for processing
> interrupts. The previous patch optimized the condition where msix is enabled
> but the queue vector is unset. However, there is a additional case where the
> guest interrupt notifier is effectively unused and the vring call fd should
> also be cleared: the guest does not use msix and the INTX_DISABLED bit in the 
> PCI
> config is set.
> 
> Fixes: 96a3d98d2c ("vhost: don't set vring call if no vector")

this must be with no empty lines adjacent to the rest of trailers.

> Test result:
> https://raw.githubusercontent.com/oenhan/build_log/refs/heads/main/qemu/2503261015/build/meson-logs/testlog.txt

just include the summary here inline.

> Reported-by: Zhiyuan Yuan <yuanzhiy...@chinatelecom.cn>
> Signed-off-by: Jidong Xia <xi...@chinatelecom.cn>
> Signed-off-by: Huaitong Han <han...@chinatelecom.cn>
> ---
>  hw/pci/pci.c                   |  2 +-
>  hw/s390x/virtio-ccw.c          |  9 ++++++---
>  hw/virtio/vhost.c              |  5 ++---
>  hw/virtio/virtio-pci.c         | 15 ++++++++++-----
>  include/hw/pci/pci.h           |  1 +
>  include/hw/virtio/virtio-bus.h |  2 +-
>  6 files changed, 21 insertions(+), 13 deletions(-)
> 
> diff --git a/hw/pci/pci.c b/hw/pci/pci.c
> index 2844ec5556..503a897528 100644
> --- a/hw/pci/pci.c
> +++ b/hw/pci/pci.c
> @@ -1719,7 +1719,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/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
> index 43f3b162c8..af482a22cd 100644
> --- a/hw/s390x/virtio-ccw.c
> +++ b/hw/s390x/virtio-ccw.c
> @@ -936,11 +936,14 @@ static void virtio_ccw_vmstate_change(DeviceState *d, 
> bool running)
>      }
>  }
>  
> -static bool virtio_ccw_query_guest_notifiers(DeviceState *d)
> +static bool virtio_ccw_query_guest_notifiers_used(DeviceState *d, int n)
>  {
>      CcwDevice *dev = CCW_DEVICE(d);
> +    VirtioCcwDevice *vdev = VIRTIO_CCW_DEVICE(d);
> +    VirtIODevice *virtio_dev = virtio_bus_get_device(&vdev->bus);
>  
> -    return !!(dev->sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ENA);
> +    return !!(dev->sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ENA)
> +            && virtio_queue_vector(virtio_dev, n) != VIRTIO_NO_VECTOR;
>  }
>  
>  static int virtio_ccw_get_mappings(VirtioCcwDevice *dev)
> @@ -1270,7 +1273,7 @@ static void virtio_ccw_bus_class_init(ObjectClass 
> *klass, void *data)
>      bus_class->max_dev = 1;
>      k->notify = virtio_ccw_notify;
>      k->vmstate_change = virtio_ccw_vmstate_change;
> -    k->query_guest_notifiers = virtio_ccw_query_guest_notifiers;
> +    k->query_guest_notifiers_used = virtio_ccw_query_guest_notifiers_used;
>      k->set_guest_notifiers = virtio_ccw_set_guest_notifiers;
>      k->save_queue = virtio_ccw_save_queue;
>      k->load_queue = virtio_ccw_load_queue;
> diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
> index 6aa72fd434..32634da836 100644
> --- a/hw/virtio/vhost.c
> +++ b/hw/virtio/vhost.c
> @@ -1341,9 +1341,8 @@ int vhost_virtqueue_start(struct vhost_dev *dev,
>          vhost_virtqueue_mask(dev, vdev, idx, false);
>      }
>  
> -    if (k->query_guest_notifiers &&
> -        k->query_guest_notifiers(qbus->parent) &&
> -        virtio_queue_vector(vdev, idx) == VIRTIO_NO_VECTOR) {
> +    if (k->query_guest_notifiers_used &&
> +        !k->query_guest_notifiers_used(qbus->parent, idx)) {
>          file.fd = -1;
>          r = dev->vhost_ops->vhost_set_vring_call(dev, &file);
>          if (r) {
> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> index 3ca3f849d3..25ff869618 100644
> --- a/hw/virtio/virtio-pci.c
> +++ b/hw/virtio/virtio-pci.c
> @@ -30,6 +30,7 @@
>  #include "qemu/error-report.h"
>  #include "qemu/log.h"
>  #include "qemu/module.h"
> +#include "hw/pci/pci.h"
>  #include "hw/pci/msi.h"
>  #include "hw/pci/msix.h"
>  #include "hw/loader.h"
> @@ -1031,7 +1032,7 @@ static void virtio_pci_one_vector_mask(VirtIOPCIProxy 
> *proxy,
>  
>      /* If guest supports masking, keep irqfd but mask it.
>       * Otherwise, clean it up now.
> -     */ 
> +     */
>      if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
>          k->guest_notifier_mask(vdev, queue_no, true);
>      } else {
> @@ -1212,10 +1213,15 @@ static int virtio_pci_set_guest_notifier(DeviceState 
> *d, int n, bool assign,
>      return 0;
>  }
>  
> -static bool virtio_pci_query_guest_notifiers(DeviceState *d)
> +static bool virtio_pci_query_guest_notifiers_used(DeviceState *d, int n)
>  {
>      VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
> -    return msix_enabled(&proxy->pci_dev);
> +    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
> +
> +    if (msix_enabled(&proxy->pci_dev))
> +        return virtio_queue_vector(vdev, n) != VIRTIO_NO_VECTOR;
> +    else
> +        return !pci_irq_disabled(&proxy->pci_dev);
>  }
>  
>  static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool 
> assign)
> @@ -2599,7 +2605,7 @@ static void virtio_pci_bus_class_init(ObjectClass 
> *klass, void *data)
>      k->save_extra_state = virtio_pci_save_extra_state;
>      k->load_extra_state = virtio_pci_load_extra_state;
>      k->has_extra_state = virtio_pci_has_extra_state;
> -    k->query_guest_notifiers = virtio_pci_query_guest_notifiers;
> +    k->query_guest_notifiers_used = virtio_pci_query_guest_notifiers_used;
>      k->set_guest_notifiers = virtio_pci_set_guest_notifiers;
>      k->set_host_notifier_mr = virtio_pci_set_host_notifier_mr;
>      k->vmstate_change = virtio_pci_vmstate_change;
> @@ -2630,4 +2636,3 @@ static void virtio_pci_register_types(void)
>  }
>  
>  type_init(virtio_pci_register_types)
> -
> diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
> index 822fbacdf0..de4ab28046 100644
> --- a/include/hw/pci/pci.h
> +++ b/include/hw/pci/pci.h
> @@ -256,6 +256,7 @@ void pci_del_capability(PCIDevice *pci_dev, uint8_t 
> cap_id, uint8_t cap_size);
>  
>  uint8_t pci_find_capability(PCIDevice *pci_dev, uint8_t cap_id);
>  
> +int pci_irq_disabled(PCIDevice *d);
>  
>  uint32_t pci_default_read_config(PCIDevice *d,
>                                   uint32_t address, int len);
> diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h
> index 7ab8c9dab0..de75a44895 100644
> --- a/include/hw/virtio/virtio-bus.h
> +++ b/include/hw/virtio/virtio-bus.h
> @@ -48,7 +48,7 @@ struct VirtioBusClass {
>      int (*load_done)(DeviceState *d, QEMUFile *f);
>      int (*load_extra_state)(DeviceState *d, QEMUFile *f);
>      bool (*has_extra_state)(DeviceState *d);
> -    bool (*query_guest_notifiers)(DeviceState *d);
> +    bool (*query_guest_notifiers_used)(DeviceState *d, int n);


I don't see why we need to change the name, and you don't explain
in the commit log. The new name isn't really clear, either.


>      int (*set_guest_notifiers)(DeviceState *d, int nvqs, bool assign);
>      int (*set_host_notifier_mr)(DeviceState *d, int n,
>                                  MemoryRegion *mr, bool assign);
> -- 
> 2.43.5


Reply via email to