All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Alex Bennée" <alex.bennee@linaro.org>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: mttcg@greensocs.com, peter.maydell@linaro.org,
	mark.burton@greensocs.com, a.rigo@virtualopensystems.com,
	qemu-devel@nongnu.org, stefanha@redhat.com,
	fred.konrad@greensocs.com
Subject: Re: [Qemu-devel] [PATCH v1 3/5] include/qemu/atomic.h: default to __atomic functions
Date: Fri, 29 Jan 2016 16:06:04 +0000	[thread overview]
Message-ID: <87si1ggykz.fsf@linaro.org> (raw)
In-Reply-To: <56A9F4BA.1030508@redhat.com>


Paolo Bonzini <pbonzini@redhat.com> writes:

> On 28/01/2016 11:15, Alex Bennée wrote:
>> +/* atomic_mb_read/set semantics map Java volatile variables. They are
>> + * less expensive on some platforms (notably POWER & ARM) than fully
>> + * sequentially consistent operations.
>> + *
>> + * As long as they are used as paired operations they are safe to
>> + * use. See docs/atomic.txt for more discussion.
>> + */
>> +
>> +#define atomic_mb_read(ptr)                             \
>> +    ({                                                  \
>> +    typeof(*ptr) _val;                                  \
>> +     __atomic_load(ptr, &_val, __ATOMIC_RELAXED);       \
>> +     smp_rmb();                                         \
>> +    _val;                                               \
>> +    })
>> +
>> +#define atomic_mb_set(ptr, i)  do {                     \
>> +    typeof(*ptr) _val = (i);                            \
>> +    smp_wmb();                                          \
>> +    __atomic_store(ptr, &_val, __ATOMIC_RELAXED);       \
>> +    smp_mb();                                           \
>> +} while(0)
>
> Great... I'll change this to
>
> #if defined(_ARCH_PPC)
> #define atomic_mb_read(ptr)                             \
>     ({                                                  \
>     typeof(*ptr) _val;                                  \
>      __atomic_load(ptr, &_val, __ATOMIC_RELAXED);       \
>      smp_rmb();                                         \
>     _val;                                               \
>     })
>
> #define atomic_mb_set(ptr, i)  do {                     \
>     typeof(*ptr) _val = (i);                            \
>     smp_wmb();                                          \
>     __atomic_store(ptr, &_val, __ATOMIC_RELAXED);       \
>     smp_mb();                                           \
> } while(0)
> #else
> #define atomic_mb_read(ptr)                       \
>     ({                                            \
>     typeof(*ptr) _val;                            \
>      __atomic_load(ptr, &_val, __ATOMIC_SEQ_CST); \
>     _val;                                         \
>     })
>
> #define atomic_mb_set(ptr, i)  do {               \
>     typeof(*ptr) _val = (i);                      \
>     __atomic_store(ptr, &_val, __ATOMIC_SEQ_CST); \
> } while(0)
> #endif
>
> since this benefits x86 (which can generate mov/xchg respectively) and
> aarch64 (where atomic_mb_read/atomic_mb_set map directly to
> ldar/stlr).

The original comment mentioned both POWER and ARM so I wondering if we
should also special case for the ARMv7?

>
>> +/* Returns the eventual value, failed or not */

Yeah this comment in bogus.

>> +#define atomic_cmpxchg(ptr, old, new)                                   \
>> +    ({                                                                  \
>> +    typeof(*ptr) _old = (old), _new = (new);                            \
>> +    __atomic_compare_exchange(ptr, &_old, &_new, false,                 \
>> +                              __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);      \
>> +    _old; /* can this race if cmpxchg not used elsewhere? */            \
>> +    })
>
> How so?

My mistake, I was having a worry that we weren't following the old
semantics. In fact having read even more closely I understand that _old is
updated by the __atomic function if the update fails. In fact _old is a
poor name because its _expected at the start and _current in the case it
fails. In fact:

    This compares the contents of *ptr with the contents of *expected. If
    equal, the operation is a read-modify-write operation that writes
    desired into *ptr. If they are not equal, the operation is a read and
    the current contents of *ptr are written into *expected. <snip>...

    If desired is written into *ptr then true is returned and memory is
    affected according to the memory order specified by success_memorder.
    There are no restrictions on what memory order can be used here.

I was wondering if this was subtly different from the old
__sync_val_compare_and_swap:

    The “val” version returns the contents of *ptr before the operation.

I think we are OK because if cmpxchg succeeds _old was by definition
what was already there but it is confusing and leads to funny code like
this:

    if (atomic_cmpxchg(&data[i].n, 0, 3) == 0) {
        data[i].ret = -ECANCELED;
        ...

and

    if (atomic_cmpxchg(&s->state, old_state, new_state) == old_state) {
       ...

Which might be easier to read if atomic_cmpxchg used the bool
semantics, i.e. return true for a successful cmpxchg.

The old code even has a atomic_bool_cmpxchg which no one seems to use. I
wonder if the correct solution is to convert atomic_cmpxchg calls to use
atomic_cmpxchg_bool calls and remove atomic_cmpxchg from atomic.h?

What do you think?

>
> Paolo


--
Alex Bennée

  reply	other threads:[~2016-01-29 16:06 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-28 10:15 [Qemu-devel] [PATCH v1 0/5] ThreadSanitizer support Alex Bennée
2016-01-28 10:15 ` [Qemu-devel] [PATCH v1 1/5] configure: introduce --extra-libs Alex Bennée
2016-01-28 11:14   ` Paolo Bonzini
2016-01-28 11:38     ` Alex Bennée
2016-01-28 10:15 ` [Qemu-devel] [PATCH v1 2/5] configure: ensure ldflags propagated to config_host Alex Bennée
2016-01-28 11:10   ` Paolo Bonzini
2016-01-28 11:13   ` Paolo Bonzini
2016-01-29 15:26     ` Alex Bennée
2016-01-28 10:15 ` [Qemu-devel] [PATCH v1 3/5] include/qemu/atomic.h: default to __atomic functions Alex Bennée
2016-01-28 11:00   ` Paolo Bonzini
2016-01-29 16:06     ` Alex Bennée [this message]
2016-02-04 12:40       ` Paolo Bonzini
2016-02-04 13:00         ` Peter Maydell
2016-04-01 14:30   ` James Hogan
2016-04-01 14:51     ` Peter Maydell
2016-04-01 16:06     ` Alex Bennée
2016-04-01 20:35   ` Pranith Kumar
2016-04-04  8:14     ` Paolo Bonzini
2016-04-04 16:26       ` Pranith Kumar
2016-04-04 17:03         ` Paolo Bonzini
2016-04-04 20:15           ` Paolo Bonzini
2016-04-05  3:35           ` Pranith Kumar
2016-04-05 12:47             ` Paolo Bonzini
2016-01-28 10:15 ` [Qemu-devel] [PATCH v1 4/5] async.c: various atomic fixes for tsan Alex Bennée
2016-01-28 10:45   ` Paolo Bonzini
2016-01-28 10:15 ` [Qemu-devel] [PATCH v1 5/5] thread-pool: atomic fixes from tsan Alex Bennée
2016-01-28 10:44   ` Paolo Bonzini

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=87si1ggykz.fsf@linaro.org \
    --to=alex.bennee@linaro.org \
    --cc=a.rigo@virtualopensystems.com \
    --cc=fred.konrad@greensocs.com \
    --cc=mark.burton@greensocs.com \
    --cc=mttcg@greensocs.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --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 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.