All of lore.kernel.org
 help / color / mirror / Atom feed
From: Julien Grall <julien.grall@linaro.org>
To: Ian Campbell <ian.campbell@citrix.com>
Cc: stefano.stabellini@eu.citrix.com, tim@xen.org, xen-devel@lists.xen.org
Subject: Re: [PATCH 11/17] xen: arm64: atomics: fix use of acquire + release for full barrier semantics
Date: Thu, 20 Mar 2014 17:43:59 +0000	[thread overview]
Message-ID: <532B28DF.2080005@linaro.org> (raw)
In-Reply-To: <1395330365-9901-11-git-send-email-ian.campbell@citrix.com>

On 03/20/2014 03:45 PM, Ian Campbell wrote:
> Xen, like Linux, expects full barrier semantics for bitops, atomics and
> cmpxchgs. This issue was discovered on Linux and we get our implementation of
> these from Linux so quoting Will Deacon in Linux commit 8e86f0b409a4 for the
> gory details:
>     Linux requires a number of atomic operations to provide full barrier
>     semantics, that is no memory accesses after the operation can be
>     observed before any accesses up to and including the operation in
>     program order.
> 
>     On arm64, these operations have been incorrectly implemented as follows:
> 
>         // A, B, C are independent memory locations
> 
>         <Access [A]>
> 
>         // atomic_op (B)
>     1:  ldaxr   x0, [B]         // Exclusive load with acquire
>         <op(B)>
>         stlxr   w1, x0, [B]     // Exclusive store with release
>         cbnz    w1, 1b
> 
>         <Access [C]>
> 
>     The assumption here being that two half barriers are equivalent to a
>     full barrier, so the only permitted ordering would be A -> B -> C
>     (where B is the atomic operation involving both a load and a store).
> 
>     Unfortunately, this is not the case by the letter of the architecture
>     and, in fact, the accesses to A and C are permitted to pass their
>     nearest half barrier resulting in orderings such as Bl -> A -> C -> Bs
>     or Bl -> C -> A -> Bs (where Bl is the load-acquire on B and Bs is the
>     store-release on B). This is a clear violation of the full barrier
>     requirement.
> 
>     The simple way to fix this is to implement the same algorithm as ARMv7
>     using explicit barriers:
> 
>         <Access [A]>
> 
>         // atomic_op (B)
>         dmb     ish             // Full barrier
>     1:  ldxr    x0, [B]         // Exclusive load
>         <op(B)>
>         stxr    w1, x0, [B]     // Exclusive store
>         cbnz    w1, 1b
>         dmb     ish             // Full barrier
> 
>         <Access [C]>
> 
>     but this has the undesirable effect of introducing *two* full barrier
>     instructions. A better approach is actually the following, non-intuitive
>     sequence:
> 
>         <Access [A]>
> 
>         // atomic_op (B)
>     1:  ldxr    x0, [B]         // Exclusive load
>         <op(B)>
>         stlxr   w1, x0, [B]     // Exclusive store with release
>         cbnz    w1, 1b
>         dmb     ish             // Full barrier
> 
>         <Access [C]>
> 
>     The simple observations here are:
> 
>       - The dmb ensures that no subsequent accesses (e.g. the access to C)
>         can enter or pass the atomic sequence.
> 
>       - The dmb also ensures that no prior accesses (e.g. the access to A)
>         can pass the atomic sequence.
> 
>       - Therefore, no prior access can pass a subsequent access, or
>         vice-versa (i.e. A is strictly ordered before C).
> 
>       - The stlxr ensures that no prior access can pass the store component
>         of the atomic operation.
> 
>     The only tricky part remaining is the ordering between the ldxr and the
>     access to A, since the absence of the first dmb means that we're now
>     permitting re-ordering between the ldxr and any prior accesses.
> 
>     From an (arbitrary) observer's point of view, there are two scenarios:
> 
>       1. We have observed the ldxr. This means that if we perform a store to
>          [B], the ldxr will still return older data. If we can observe the
>          ldxr, then we can potentially observe the permitted re-ordering
>          with the access to A, which is clearly an issue when compared to
>          the dmb variant of the code. Thankfully, the exclusive monitor will
>          save us here since it will be cleared as a result of the store and
>          the ldxr will retry. Notice that any use of a later memory
>          observation to imply observation of the ldxr will also imply
>          observation of the access to A, since the stlxr/dmb ensure strict
>          ordering.
> 
>       2. We have not observed the ldxr. This means we can perform a store
>          and influence the later ldxr. However, that doesn't actually tell
>          us anything about the access to [A], so we've not lost anything
>          here either when compared to the dmb variant.
> 
>     This patch implements this solution for our barriered atomic operations,
>     ensuring that we satisfy the full barrier requirements where they are
>     needed.
> 
>     Cc: <stable@vger.kernel.org>
>     Cc: Peter Zijlstra <peterz@infradead.org>
>     Signed-off-by: Will Deacon <will.deacon@arm.com>
>     Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
> 
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Julien Grall <julien.grall@linaro.org>

-- 
Julien Grall

  reply	other threads:[~2014-03-20 17:43 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-03-20 15:45 [PATCH 00/17] xen: arm: resync low level asm primitive from Linux Ian Campbell
2014-03-20 15:45 ` [PATCH 01/17] xen: x86 & generic: change to __builtin_prefetch() Ian Campbell
2014-03-20 16:12   ` Jan Beulich
2014-03-20 15:45 ` [PATCH 02/17] xen: arm32: resync bitops with Linux v3.14-rc7 Ian Campbell
2014-03-20 17:13   ` Julien Grall
2014-03-20 15:45 ` [PATCH 03/17] xen: arm32: ensure cmpxchg has full barrier semantics Ian Campbell
2014-03-20 17:22   ` Julien Grall
2014-03-20 15:45 ` [PATCH 04/17] xen: arm32: replace hard tabs in atomics.h Ian Campbell
2014-03-20 17:23   ` Julien Grall
2014-03-20 15:45 ` [PATCH 05/17] xen: arm32: resync atomics with (almost) v3.14-rc7 Ian Campbell
2014-03-20 17:27   ` Julien Grall
2014-03-21  8:41     ` Ian Campbell
2014-03-20 15:45 ` [PATCH 06/17] xen: arm32: resync mem* with Linux v3.14-rc7 Ian Campbell
2014-03-20 17:29   ` Julien Grall
2014-03-20 15:45 ` [PATCH 07/17] xen: arm32: add optimised memchr routine Ian Campbell
2014-03-20 17:32   ` Julien Grall
2014-03-20 15:45 ` [PATCH 08/17] xen: arm32: add optimised strchr and strrchr routines Ian Campbell
2014-03-20 17:33   ` Julien Grall
2014-03-20 15:45 ` [PATCH 09/17] xen: arm: remove atomic_clear_mask() Ian Campbell
2014-03-20 17:35   ` Julien Grall
2014-03-20 15:45 ` [PATCH 10/17] xen: arm64: disable alignment traps Ian Campbell
2014-03-20 15:57   ` Andrew Cooper
2014-03-20 15:59     ` Ian Campbell
2014-03-20 16:21       ` Gordan Bobic
2014-03-20 16:27         ` Ian Campbell
2014-03-20 16:43           ` Gordan Bobic
2014-03-20 16:54             ` Ian Campbell
2014-03-20 17:54   ` Julien Grall
2014-03-20 15:45 ` [PATCH 11/17] xen: arm64: atomics: fix use of acquire + release for full barrier semantics Ian Campbell
2014-03-20 17:43   ` Julien Grall [this message]
2014-03-20 15:46 ` [PATCH 12/17] xen: arm64: reinstate hard tabs in system.h cmpxchg Ian Campbell
2014-03-20 17:44   ` Julien Grall
2014-03-20 15:46 ` [PATCH 13/17] xen: arm64: asm: remove redundant "cc" clobbers Ian Campbell
2014-03-20 17:45   ` Julien Grall
2014-03-20 15:46 ` [PATCH 14/17] xen: arm64: assembly optimised mem* and str* Ian Campbell
2014-03-20 17:48   ` Julien Grall
2014-03-20 15:46 ` [PATCH 15/17] xen: arm64: optimised clear_page Ian Campbell
2014-03-20 15:46 ` [PATCH 16/17] xen: arm: refactor xchg and cmpxchg into their own headers Ian Campbell
2014-03-20 17:52   ` Julien Grall
2014-03-21  8:42     ` Ian Campbell
2014-03-20 15:46 ` [PATCH 17/17] xen: arm: document what low level primitives we have imported from Linux Ian Campbell
2014-03-20 16:23   ` Ian Campbell

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=532B28DF.2080005@linaro.org \
    --to=julien.grall@linaro.org \
    --cc=ian.campbell@citrix.com \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=tim@xen.org \
    --cc=xen-devel@lists.xen.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.