qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Alex Bennée" <alex.bennee@linaro.org>
To: "Marc-André Lureau" <marcandre.lureau@gmail.com>
Cc: qemu-devel@nongnu.org, pbonzini@redhat.com, cota@braap.org,
	stefanha@redhat.com, kwolf@redhat.com,
	mttcg@listserver.greensocs.com, peter.maydell@linaro.org,
	claudio.fontana@huawei.com, nikunj@linux.vnet.ibm.com,
	jan.kiszka@siemens.com, mark.burton@greensocs.com,
	a.rigo@virtualopensystems.com, serge.fdrv@gmail.com,
	bobby.prani@gmail.com, rth@twiddle.net,
	"Andreas Färber" <afaerber@suse.de>,
	fred.konrad@greensocs.com
Subject: Re: [Qemu-devel] [RFC 5/8] qom/object: update class cache atomically
Date: Tue, 20 Sep 2016 15:59:32 +0100	[thread overview]
Message-ID: <87ponyborv.fsf@linaro.org> (raw)
In-Reply-To: <CAJ+F1CJmXvvLnNLmXqqdmYXd6Bg7SvAYLxW=YxuZ6SXv3B4Ftw@mail.gmail.com>


Marc-André Lureau <marcandre.lureau@gmail.com> writes:

> Hi
>
> On Mon, Sep 19, 2016 at 7:54 PM Alex Bennée <alex.bennee@linaro.org> wrote:
>
>> The idiom CPU_GET_CLASS(cpu) is fairly extensively used in various
>> threads and trips of ThreadSanitizer due to the fact it updates
>> obj->class->object_cast_cache behind the scenes. As this is just a
>> fast-path cache there is no need to lock updates just ensure that we
>> don't get torn-updates from two racing lookups. While this is unlikely
>> on x86 we use the plain atomic_read/set primitives to make this
>> explicit and keep the sanitizer happy.
>>
>> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
>>
>
> Looks fine to me, would be nicer to have an idea of the performance hit,
> but I suppose it is marginal.

I was surprised that CONFIG_QOM_CAST_DEBUG is the default because it
does a bunch of stuff on every cast. The other option of course would be
to use --disable-qom-cast-debug when building for sanitizers although
maybe we should just be defaulting to off?

> btw, object_dynamic_cast_assert code is a bit weird: it always inserts at
> the end of the array, and shifts the other cached values down (why?). If
> there are class hierarchies with a depth and interfaces over 4
> (OBJECT_CLASS_CAST_CACHE) this looks like it may be inefficient, no? I
> can't find performance tests for object, perhaps it doesn't matter after
> all.

TBH the whole object model thing is a bit of a mystery to me that I
haven't delved that far into it. I guess I should learn about it some
more at some point.

>
> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>
>
>> ---
>>  qom/object.c | 15 ++++++++-------
>>  1 file changed, 8 insertions(+), 7 deletions(-)
>>
>> diff --git a/qom/object.c b/qom/object.c
>> index 8166b7d..7a05e35 100644
>> --- a/qom/object.c
>> +++ b/qom/object.c
>> @@ -614,7 +614,7 @@ Object *object_dynamic_cast_assert(Object *obj, const
>> char *typename,
>>      Object *inst;
>>
>>      for (i = 0; obj && i < OBJECT_CLASS_CAST_CACHE; i++) {
>> -        if (obj->class->object_cast_cache[i] == typename) {
>> +        if (atomic_read(&obj->class->object_cast_cache[i]) == typename) {
>>              goto out;
>>          }
>>      }
>> @@ -631,10 +631,10 @@ Object *object_dynamic_cast_assert(Object *obj,
>> const char *typename,
>>
>>      if (obj && obj == inst) {
>>          for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
>> -            obj->class->object_cast_cache[i - 1] =
>> -                    obj->class->object_cast_cache[i];
>> +            atomic_set(&obj->class->object_cast_cache[i - 1],
>> +                       atomic_read(&obj->class->object_cast_cache[i]));
>>          }
>> -        obj->class->object_cast_cache[i - 1] = typename;
>> +        atomic_set(&obj->class->object_cast_cache[i - 1], typename);
>>      }
>>
>>  out:
>> @@ -704,7 +704,7 @@ ObjectClass
>> *object_class_dynamic_cast_assert(ObjectClass *class,
>>      int i;
>>
>>      for (i = 0; class && i < OBJECT_CLASS_CAST_CACHE; i++) {
>> -        if (class->class_cast_cache[i] == typename) {
>> +        if (atomic_read(&class->class_cast_cache[i]) == typename) {
>>              ret = class;
>>              goto out;
>>          }
>> @@ -725,9 +725,10 @@ ObjectClass
>> *object_class_dynamic_cast_assert(ObjectClass *class,
>>  #ifdef CONFIG_QOM_CAST_DEBUG
>>      if (class && ret == class) {
>>          for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
>> -            class->class_cast_cache[i - 1] = class->class_cast_cache[i];
>> +            atomic_set(&class->class_cast_cache[i - 1],
>> +                       atomic_read(&class->class_cast_cache[i]));
>>          }
>> -        class->class_cast_cache[i - 1] = typename;
>> +        atomic_set(&class->class_cast_cache[i - 1], typename);
>>      }
>>  out:
>>  #endif
>> --
>> 2.9.3
>>
>>
>> --
> Marc-André Lureau


--
Alex Bennée

  reply	other threads:[~2016-09-20 15:00 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-19 15:51 [Qemu-devel] [RFC 0/8] A couple of fixes for ThreadSanitizer Alex Bennée
2016-09-19 15:51 ` [Qemu-devel] [RFC 1/8] ui/vnc-enc-tight: add abort() for unexpected default Alex Bennée
2016-09-20  8:02   ` Marc-André Lureau
2016-09-20  8:24     ` Paolo Bonzini
2016-09-20 14:59       ` Alex Bennée
2016-09-19 15:51 ` [Qemu-devel] [RFC 2/8] tcg/optimize: move default return out of if statement Alex Bennée
2016-09-20  8:02   ` Marc-André Lureau
2016-09-19 15:51 ` [Qemu-devel] [RFC 3/8] new: blacklist.tsan Alex Bennée
2016-09-20  8:03   ` Marc-André Lureau
2016-09-19 15:51 ` [Qemu-devel] [RFC 4/8] seqlock: use atomic writes for the sequence Alex Bennée
2016-09-19 15:51 ` [Qemu-devel] [RFC 5/8] qom/object: update class cache atomically Alex Bennée
2016-09-20  8:36   ` Marc-André Lureau
2016-09-20 14:59     ` Alex Bennée [this message]
2016-09-20 15:04       ` Paolo Bonzini
2016-09-19 15:51 ` [Qemu-devel] [RFC 6/8] cpu: atomically modify cpu->exit_request Alex Bennée
2016-09-19 15:51 ` [Qemu-devel] [RFC 7/8] util/qht: atomically set b->hashes Alex Bennée
2016-09-19 18:06   ` Emilio G. Cota
2016-09-19 18:37     ` Paolo Bonzini
2016-09-19 19:06       ` Emilio G. Cota
2016-09-20  7:39         ` Paolo Bonzini
2016-09-22  9:51           ` Alex Bennée
2016-09-19 15:51 ` [Qemu-devel] [RFC 8/8] .travis.yml: add gcc sanitizer build Alex Bennée

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=87ponyborv.fsf@linaro.org \
    --to=alex.bennee@linaro.org \
    --cc=a.rigo@virtualopensystems.com \
    --cc=afaerber@suse.de \
    --cc=bobby.prani@gmail.com \
    --cc=claudio.fontana@huawei.com \
    --cc=cota@braap.org \
    --cc=fred.konrad@greensocs.com \
    --cc=jan.kiszka@siemens.com \
    --cc=kwolf@redhat.com \
    --cc=marcandre.lureau@gmail.com \
    --cc=mark.burton@greensocs.com \
    --cc=mttcg@listserver.greensocs.com \
    --cc=nikunj@linux.vnet.ibm.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=rth@twiddle.net \
    --cc=serge.fdrv@gmail.com \
    --cc=stefanha@redhat.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).