Re: [PATCH] kvm: use insert sort in kvm_io_bus_register_dev function

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



2018-01-16 21:34 GMT+08:00 Gal Hammer <ghammer@xxxxxxxxxx>:
> The loading time of a VM is quite significant with a CPU usage
> reaching 100% when loading a VM that its virtio devices use a
> large amount of virt-queues (e.g. a virtio-serial device with
> max_ports=511). Most of the time is spend in re-sorting the
> kvm_io_bus kvm_io_range array when a new eventfd is registered.
>
> The patch replaces the existing method with an insert sort.

If we should stop to use bsearch when searching io bus later?

Regards,
Wanpeng Li

>
> Reviewed-by: Marcel Apfelbaum <marcel@xxxxxxxxxx>
> Reviewed-by: Uri Lublin <ulublin@xxxxxxxxxx>
> Signed-off-by: Gal Hammer <ghammer@xxxxxxxxxx>
> ---
>  virt/kvm/kvm_main.c | 36 ++++++++++++++++++------------------
>  1 file changed, 18 insertions(+), 18 deletions(-)
>
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index 210bf82..1e467fc 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -3419,21 +3419,6 @@ static int kvm_io_bus_sort_cmp(const void *p1, const void *p2)
>         return kvm_io_bus_cmp(p1, p2);
>  }
>
> -static int kvm_io_bus_insert_dev(struct kvm_io_bus *bus, struct kvm_io_device *dev,
> -                         gpa_t addr, int len)
> -{
> -       bus->range[bus->dev_count++] = (struct kvm_io_range) {
> -               .addr = addr,
> -               .len = len,
> -               .dev = dev,
> -       };
> -
> -       sort(bus->range, bus->dev_count, sizeof(struct kvm_io_range),
> -               kvm_io_bus_sort_cmp, NULL);
> -
> -       return 0;
> -}
> -
>  static int kvm_io_bus_get_first_dev(struct kvm_io_bus *bus,
>                              gpa_t addr, int len)
>  {
> @@ -3574,7 +3559,9 @@ int kvm_io_bus_read(struct kvm_vcpu *vcpu, enum kvm_bus bus_idx, gpa_t addr,
>  int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
>                             int len, struct kvm_io_device *dev)
>  {
> +       int i;
>         struct kvm_io_bus *new_bus, *bus;
> +       struct kvm_io_range range;
>
>         bus = kvm_get_bus(kvm, bus_idx);
>         if (!bus)
> @@ -3588,9 +3575,22 @@ int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
>                           sizeof(struct kvm_io_range)), GFP_KERNEL);
>         if (!new_bus)
>                 return -ENOMEM;
> -       memcpy(new_bus, bus, sizeof(*bus) + (bus->dev_count *
> -              sizeof(struct kvm_io_range)));
> -       kvm_io_bus_insert_dev(new_bus, dev, addr, len);
> +
> +       range = (struct kvm_io_range) {
> +               .addr = addr,
> +               .len = len,
> +               .dev = dev,
> +       };
> +
> +       for (i = 0; i < bus->dev_count; i++)
> +               if (kvm_io_bus_cmp(&bus->range[i], &range) > 0)
> +                       break;
> +
> +       memcpy(new_bus, bus, sizeof(*bus) + i * sizeof(struct kvm_io_range));
> +       new_bus->dev_count++;
> +       new_bus->range[i] = range;
> +       memcpy(new_bus->range + i + 1, bus->range + i,
> +               (bus->dev_count - i) * sizeof(struct kvm_io_range));
>         rcu_assign_pointer(kvm->buses[bus_idx], new_bus);
>         synchronize_srcu_expedited(&kvm->srcu);
>         kfree(bus);
> --
> 2.7.5
>



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux