Hi Alex,

> On July 28, 2023 1:25 AM,  Alex Williamson <alex.william...@redhat.com> wrote:
> 
> On Thu, 27 Jul 2023 03:24:09 -0400
> Jing Liu <jing2....@intel.com> wrote:
> 
> > The vector_use callback is used to enable vector that is unmasked in
> > guest. The kernel used to only support static MSI-X allocation. When
> > allocating a new interrupt using "static MSI-X allocation" kernels,
> > Qemu first disables all previously allocated vectors and then
> > re-allocates all including the new one. The nr_vectors of
> > VFIOPCIDevice indicates that all vectors from 0 to nr_vectors are
> > allocated (and may be enabled), which is used to to loop all the
> > possibly used vectors When, e.g., disabling MSI-X interrupts.
> >
> > Extend the vector_use function to support dynamic MSI-X allocation
> > when host supports the capability. Qemu therefore can individually
> > allocate and enable a new interrupt without affecting others or
> > causing interrupts lost during runtime.
> >
> > Utilize nr_vectors to calculate the upper bound of enabled vectors in
> > dynamic MSI-X allocation mode since looping all msix_entries_nr is not
> > efficient and unnecessary.
> >
> > Signed-off-by: Jing Liu <jing2....@intel.com>
> > Tested-by: Reinette Chatre <reinette.cha...@intel.com>
> > ---
> >  hw/vfio/pci.c | 40 +++++++++++++++++++++++++++-------------
> >  1 file changed, 27 insertions(+), 13 deletions(-)
> >
> > diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index
> > 0c4ac0873d40..8c485636445c 100644
> > --- a/hw/vfio/pci.c
> > +++ b/hw/vfio/pci.c
> > @@ -512,12 +512,20 @@ static int vfio_msix_vector_do_use(PCIDevice
> *pdev, unsigned int nr,
> >      }
> >
> >      /*
> > -     * We don't want to have the host allocate all possible MSI vectors
> > -     * for a device if they're not in use, so we shutdown and incrementally
> > -     * increase them as needed.
> > +     * When dynamic allocation is not supported, we don't want to have the
> > +     * host allocate all possible MSI vectors for a device if they're not
> > +     * in use, so we shutdown and incrementally increase them as needed.
> > +     * And nr_vectors stands for the number of vectors being allocated.
> 
> "nr_vectors represents the total number of vectors allocated."

Will change.

> 
> > +     *
> > +     * When dynamic allocation is supported, let the host only allocate
> > +     * and enable a vector when it is in use in guest. nr_vectors stands
> > +     * for the upper bound of vectors being enabled (but not all of the
> > +     * ranges is allocated or enabled).
> 
> s/stands for/represents/
Will change.
> 
> >       */
> > -    if (vdev->nr_vectors < nr + 1) {
> > +    if ((vdev->msix->irq_info_flags & VFIO_IRQ_INFO_NORESIZE) &&
> 
> Testing vdev->msix->noresize would be cleaner.
> 
> > +        (vdev->nr_vectors < nr + 1)) {
> >          vdev->nr_vectors = nr + 1;
> > +
> >          if (!vdev->defer_kvm_irq_routing) {
> >              vfio_disable_irqindex(&vdev->vbasedev, 
> > VFIO_PCI_MSIX_IRQ_INDEX);
> >              ret = vfio_enable_vectors(vdev, true); @@ -529,16 +537,22
> > @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
> >          Error *err = NULL;
> >          int32_t fd;
> >
> > -        if (vector->virq >= 0) {
> > -            fd = event_notifier_get_fd(&vector->kvm_interrupt);
> > -        } else {
> > -            fd = event_notifier_get_fd(&vector->interrupt);
> > -        }
> > +        if (!vdev->defer_kvm_irq_routing) {
> > +            if (vector->virq >= 0) {
> > +                fd = event_notifier_get_fd(&vector->kvm_interrupt);
> > +            } else {
> > +                fd = event_notifier_get_fd(&vector->interrupt);
> > +            }
> >
> > -        if (vfio_set_irq_signaling(&vdev->vbasedev,
> > -                                     VFIO_PCI_MSIX_IRQ_INDEX, nr,
> > -                                     VFIO_IRQ_SET_ACTION_TRIGGER, fd, 
> > &err)) {
> > -            error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
> > +            if (vfio_set_irq_signaling(&vdev->vbasedev,
> > +                                       VFIO_PCI_MSIX_IRQ_INDEX, nr,
> > +                                       VFIO_IRQ_SET_ACTION_TRIGGER, fd, 
> > &err)) {
> > +                error_reportf_err(err, VFIO_MSG_PREFIX, 
> > vdev->vbasedev.name);
> > +            }
> > +        }
> > +        /* Increase for dynamic allocation case. */
> > +        if (vdev->nr_vectors < nr + 1) {
> > +            vdev->nr_vectors = nr + 1;
> >          }
> 
> We now have two branches where the bulk of the code is skipped when
> defer_kvm_irq_routing is enabled and doing effectively the same update to
> nr_vectors otherwise.  This suggests we should move the
> defer_kvm_irq_routing test out and create a common place to update
> nr_vectors.  Thanks,

I make a new logic as follows that moves the defer_kvm_irq_routing test out.
Since the vfio_enable_vectors() function need an updated nr_vectors value
so need first update and test the different conditions using old value,
e.g. old_nr_vec.

int old_nr_vec = vdev->nr_vectors;
...
...
if (vdev->nr_vectors < nr + 1) {
    vdev->nr_vectors = nr + 1;
}
if (!vdev->defer_kvm_irq_routing) {
    if (vdev->msix->noresize && (old_nr_vec < nr + 1)) {
            vfio_disable_irqindex(&vdev->vbasedev, VFIO_PCI_MSIX_IRQ_INDEX);
            ret = vfio_enable_vectors(vdev, true);  // use updated nr_vectors
            ...
    } else {
            if (vector->virq >= 0) {
                fd = event_notifier_get_fd(&vector->kvm_interrupt);
            } else {
                fd = event_notifier_get_fd(&vector->interrupt);
            }
            if (vfio_set_irq_signaling(&vdev->vbasedev,
                                       VFIO_PCI_MSIX_IRQ_INDEX, nr,
                                       VFIO_IRQ_SET_ACTION_TRIGGER, fd, &err)) {
                error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
            }        
    }
}
Thanks,
Jing

> 
> Alex


Reply via email to