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
next prev parent 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).