On Tue, Feb 18, 2020 at 9:50 PM Peter Xu <pet...@redhat.com> wrote:
>
> 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 <stefa...@redhat.com>
> > ---
> >  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?

No, it will decrease but only the next time
address_space_update_ioeventfds() is called.  That's when we'll use
the next ioeventfds_nb as the starting point.

> 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...

I also considered doing a final g_realloc() at the end of the function
to get rid of the excess allocation but I'm not sure it's worth it...

> > +
> >      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?

I'm happy to tweak the policy.  Let's see what Paolo thinks.

Stefan

Reply via email to