qemu-devel
[Top][All Lists]
Advanced

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

Re: [PATCH] memory: batch allocate ioeventfds[] in address_space_update_


From: Peter Xu
Subject: Re: [PATCH] memory: batch allocate ioeventfds[] in address_space_update_ioeventfds()
Date: Tue, 18 Feb 2020 16:49:32 -0500

On Tue, Feb 18, 2020 at 06:22:26PM +0000, Stefan Hajnoczi wrote:
> Reallocing the ioeventfds[] array each time an element is added is very
> expensive as the number of ioeventfds increases.  Batch allocate instead
> to amortize the cost of realloc.
> 
> This patch reduces Linux guest boot times from 362s to 140s when there
> are 2 virtio-blk devices with 1 virtqueue and 99 virtio-blk devices with
> 32 virtqueues.
> 
> Signed-off-by: Stefan Hajnoczi <address@hidden>
> ---
>  memory.c | 17 ++++++++++++++---
>  1 file changed, 14 insertions(+), 3 deletions(-)
> 
> diff --git a/memory.c b/memory.c
> index aeaa8dcc9e..2d6f931f8c 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -794,10 +794,18 @@ static void 
> address_space_update_ioeventfds(AddressSpace *as)
>      FlatView *view;
>      FlatRange *fr;
>      unsigned ioeventfd_nb = 0;
> -    MemoryRegionIoeventfd *ioeventfds = NULL;
> +    unsigned ioeventfd_max;
> +    MemoryRegionIoeventfd *ioeventfds;
>      AddrRange tmp;
>      unsigned i;
>  
> +    /*
> +     * It is likely that the number of ioeventfds hasn't changed much, so use
> +     * the previous size as the starting value.
> +     */
> +    ioeventfd_max = as->ioeventfd_nb;
> +    ioeventfds = g_new(MemoryRegionIoeventfd, ioeventfd_max);

Would the ioeventfd_max being cached and never goes down but it can
only keep or increase?  I'm not sure if that's a big problem, but
considering the commit message mentioned 99 virtio-blk with 32 queues
each, I'm not sure... :)

I'm thinking maybe start with a relative big number but always under
control (e.g., 64), then...

> +
>      view = address_space_get_flatview(as);
>      FOR_EACH_FLAT_RANGE(fr, view) {
>          for (i = 0; i < fr->mr->ioeventfd_nb; ++i) {
> @@ -806,8 +814,11 @@ static void address_space_update_ioeventfds(AddressSpace 
> *as)
>                                               
> int128_make64(fr->offset_in_region)));
>              if (addrrange_intersects(fr->addr, tmp)) {
>                  ++ioeventfd_nb;
> -                ioeventfds = g_realloc(ioeventfds,
> -                                          ioeventfd_nb * 
> sizeof(*ioeventfds));
> +                if (ioeventfd_nb > ioeventfd_max) {
> +                    ioeventfd_max += 64;

... do exponential increase here (max*=2) instead so still easy to
converge?

Thanks,

> +                    ioeventfds = g_realloc(ioeventfds,
> +                            ioeventfd_max * sizeof(*ioeventfds));
> +                }
>                  ioeventfds[ioeventfd_nb-1] = fr->mr->ioeventfds[i];
>                  ioeventfds[ioeventfd_nb-1].addr = tmp;
>              }
> -- 
> 2.24.1
> 

-- 
Peter Xu




reply via email to

[Prev in Thread] Current Thread [Next in Thread]