All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Daniel P. Berrange" <berrange@redhat.com>
To: "Andreas Färber" <afaerber@suse.de>
Cc: 'Peter Maydell' <peter.maydell@linaro.org>,
	David Hildenbrand <dahi@linux.vnet.ibm.com>,
	Pavel Fedin <p.fedin@samsung.com>,
	qemu-devel@nongnu.org, 'Markus Armbruster' <armbru@redhat.com>,
	Christian Borntraeger <borntraeger@de.ibm.com>,
	Cornelia Huck <cornelia.huck@de.ibm.com>,
	'Paolo Bonzini' <pbonzini@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v4 6/7] qom: replace object property list with GHashTable
Date: Mon, 16 Nov 2015 16:53:01 +0000	[thread overview]
Message-ID: <20151116165300.GF20157@redhat.com> (raw)
In-Reply-To: <564A07F3.4040200@suse.de>

On Mon, Nov 16, 2015 at 05:44:35PM +0100, Andreas Färber wrote:
> Am 16.11.2015 um 10:38 schrieb Andreas Färber:
> > Am 16.11.2015 um 09:16 schrieb Christian Borntraeger:
> >> On 11/16/2015 08:13 AM, Pavel Fedin wrote:
> >>>>>> (process:4102): GLib-CRITICAL **: g_hash_table_iter_next: assertion
> >>>>>> 'ri->version == ri->hash_table->version' failed
> >>>>>>
> >>>>>> (process:4102): GLib-CRITICAL **: g_hash_table_iter_next: assertion
> >>>>>> 'ri->version == ri->hash_table->version' failed
> >>>>>>
> >>>>>> (process:4102): GLib-CRITICAL **: iter_remove_or_steal: assertion
> >>>>>> 'ri->version == ri->hash_table->version' failed
> >>>
> >>>  Wow... Actually this may come from attempts to modify the tree inside iteration.
> >>>
> >>>> Thanks! sclp_init() seems to violate several QOM design principles in
> >>>> that it uses object_new() during TypeInfo::instance_init() and uses a
> >>>> TYPE_... constant as property name. But nothing else stands out immediately.
> >>>
> >>>  I think we should refactor this and retry. If not all problems go away, then we are indeed modifying the tree during iteration, and
> >>> we have to find some solution.
> >>
> >> David, Conny,
> >>
> >> the current tree of afaerber
> >>
> >> https://github.com/afaerber/qemu-cpu/commits/qom-next
> >>
> >> has this patch:
> >>
> >>> From: Pavel Fedin <p.fedin@samsung.com>
> >>>
> >>> ARM GICv3 systems with large number of CPUs create lots of IRQ pins. Since
> >>> every pin is represented as a property, number of these properties becomes
> >>> very large. Every property add first makes sure there's no duplicates.
> >>> Traversing the list becomes very slow, therefore qemu initialization takes
> >>> significant time (several seconds for e. g. 16 CPUs).
> >>>
> >>> This patch replaces list with GHashTable, making lookup very fast. The only
> >>> drawback is that object_child_foreach() and object_child_foreach_recursive()
> >>> cannot modify their objects during traversal, since GHashTableIter does not
> >>> have modify-safe version. However, the code seems not to modify objects via
> >>> these functions.
> >>>
> >>> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
> >>> Signed-off-by: Pavel Fedin <p.fedin@samsung.com>
> >>
> >> which causes failures in make check. A simple reproducer is
> >>
> >> qemu-system-s390x -device sclp,help
> >>
> >>
> >> any idea what would be the most simple fix?
> >> Can we refactor this to create the event facility and the bus in the
> >> machine or whatever?
> > 
> > I believe it is rather a very general problem with the new
> > object_property_del_all() implementation. It iterates through
> > properties, releasing child<> and link<> properties, which results in an
> > unref, which at some point unparents that device, removing it in the
> > parent's properties hashtable while the parent is iterating through it.
> > 
> > In this case it seems to be about the bus child<> on the event facility.
> > 
> >>>  I wonder... Could we have both list and hashtable? hashtable for searching by name and list for iteration. In this case we would
> >>> not have to use glib's iterators, and would be free of problems with them. Just keep the list and hashtable in sync.
> >>>  Or, is there any hashtable implementation out there which would keep iterators valid during modification?
> >>>  OTOH, glib has a function "remove the element at iterator's position", and we could postpone addition. So, perhaps, using both
> >>> containers would be an overkill, just refactor the code to adapt to the new behavior.
> > 
> > My idea, which I wanted to investigate after the weekend, is iterating
> > through the hashtable to create a list of prop->release functions and
> > call them only after finishing the iteration. That might not work
> > either, so we may need to loop over the releasing to allow for released
> > properties to disappear after prop->release().
> 
> I went with the latter and squashed the attached fixup (without last two
> hunks, preparing a separate patch for that), interrupting each iteration
> after prop->release() to be safe. That seems to fix it.
> 
> Will prepend and test Dan's unit test next.

> diff --git a/qom/object.c b/qom/object.c
> index 0ac3bc1..284fa38 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -377,14 +377,22 @@ static void object_property_del_all(Object *obj)
>      ObjectProperty *prop;
>      GHashTableIter iter;
>      gpointer key, value;
> +    bool released;
>  
> -    g_hash_table_iter_init(&iter, obj->properties);
> -    while (g_hash_table_iter_next(&iter, &key, &value)) {
> -        prop = value;
> -        if (prop->release) {
> -            prop->release(obj, prop->name, prop->opaque);
> +    do {
> +        released = false;
> +        g_hash_table_iter_init(&iter, obj->properties);
> +        while (g_hash_table_iter_next(&iter, &key, &value)) {
> +            prop = value;
> +            if (prop->release) {
> +                prop->release(obj, prop->name, prop->opaque);
> +                prop->release = NULL;
> +                released = true;
> +                break;
> +            }
> +            g_hash_table_iter_remove(&iter);
>          }
> -    }
> +    } while (released);
>  
>      g_hash_table_unref(obj->properties);
>  }
> @@ -401,7 +409,15 @@ static void object_property_del_child(Object *obj, Object *child, Error **errp)
>          if (object_property_is_child(prop) && prop->opaque == child) {
>              if (prop->release) {
>                  prop->release(obj, prop->name, prop->opaque);
> +                prop->release = NULL;
>              }
> +            break;
> +        }
> +    }
> +    g_hash_table_iter_init(&iter, obj->properties);
> +    while (g_hash_table_iter_next(&iter, &key, &value)) {
> +        prop = value;
> +        if (object_property_is_child(prop) && prop->opaque == child) {
>              g_hash_table_iter_remove(&iter);
>              break;
>          }
> @@ -856,7 +872,7 @@ void object_ref(Object *obj)
>      if (!obj) {
>          return;
>      }
> -     atomic_inc(&obj->ref);
> +    atomic_inc(&obj->ref);
>  }
>  
>  void object_unref(Object *obj)
> @@ -864,7 +880,7 @@ void object_unref(Object *obj)
>      if (!obj) {
>          return;
>      }
> -    g_assert(obj->ref > 0);
> +    g_assert_cmpint(obj->ref, >, 0);
>  
>      /* parent always holds a reference to its children */
>      if (atomic_fetch_dec(&obj->ref) == 1) {

This looks good to me so can add Signed-off-by: Daniel P. Berrange
to this change.

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|

  reply	other threads:[~2015-11-16 16:53 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-13 12:37 [Qemu-devel] [PATCH v4 0/7] qom: more efficient object property handling Daniel P. Berrange
2015-10-13 12:37 ` [Qemu-devel] [PATCH v4 1/7] qom: introduce ObjectPropertyIterator struct for iteration Daniel P. Berrange
2015-11-05 16:59   ` Andreas Färber
2015-11-17 15:25   ` Markus Armbruster
2015-11-17 15:27     ` Daniel P. Berrange
2015-11-17 15:35       ` Markus Armbruster
2015-10-13 12:37 ` [Qemu-devel] [PATCH v4 2/7] qmp: convert QMP code to use object property iterators Daniel P. Berrange
2015-11-05 17:08   ` Andreas Färber
2015-11-17 15:26     ` Markus Armbruster
2015-10-13 12:37 ` [Qemu-devel] [PATCH v4 3/7] vl: convert machine help " Daniel P. Berrange
2015-11-05 17:10   ` Andreas Färber
2015-10-13 12:37 ` [Qemu-devel] [PATCH v4 4/7] ppc: convert spapr " Daniel P. Berrange
2015-11-05 17:16   ` Andreas Färber
2015-10-13 12:37 ` [Qemu-devel] [PATCH v4 5/7] net: convert net filter " Daniel P. Berrange
2015-11-05 17:18   ` Andreas Färber
2015-10-13 12:37 ` [Qemu-devel] [PATCH v4 6/7] qom: replace object property list with GHashTable Daniel P. Berrange
2015-11-05 18:05   ` Andreas Färber
2015-11-06  9:02     ` Pavel Fedin
2015-11-06  9:31     ` Daniel P. Berrange
2015-11-06  9:37       ` Pavel Fedin
2015-11-13 18:14   ` Andreas Färber
2015-11-13 21:00     ` Christian Borntraeger
2015-11-13 21:25       ` Andreas Färber
2015-11-16  7:13         ` Pavel Fedin
2015-11-16  8:16           ` Christian Borntraeger
2015-11-16  9:38             ` Andreas Färber
2015-11-16 10:31               ` Pavel Fedin
2015-11-16 16:44               ` Andreas Färber
2015-11-16 16:53                 ` Daniel P. Berrange [this message]
2015-11-16  8:53         ` Paolo Bonzini
2015-11-16  9:48           ` Andreas Färber
2015-11-16  9:50             ` Paolo Bonzini
2015-11-16 11:35       ` Daniel P. Berrange
2015-10-13 12:37 ` [Qemu-devel] [PATCH v4 7/7] qom: allow properties to be registered against classes Daniel P. Berrange
2015-10-13 13:18   ` Pavel Fedin
2015-11-05 18:12     ` Andreas Färber
2015-11-06  9:32       ` Daniel P. Berrange
2015-11-18 23:35         ` Andreas Färber
2015-10-13 12:54 ` [Qemu-devel] [PATCH v4 0/7] qom: more efficient object property handling Andreas Färber
2015-10-13 12:59   ` Daniel P. Berrange
2015-10-14  6:57 ` Pavel Fedin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20151116165300.GF20157@redhat.com \
    --to=berrange@redhat.com \
    --cc=afaerber@suse.de \
    --cc=armbru@redhat.com \
    --cc=borntraeger@de.ibm.com \
    --cc=cornelia.huck@de.ibm.com \
    --cc=dahi@linux.vnet.ibm.com \
    --cc=p.fedin@samsung.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.