1. 25 3月, 2015 1 次提交
  2. 20 11月, 2014 1 次提交
    • S
      arm64: percpu: Implement this_cpu operations · f97fc810
      Steve Capper 提交于
      The generic this_cpu operations disable interrupts to ensure that the
      requested operation is protected from pre-emption. For arm64, this is
      overkill and can hurt throughput and latency.
      
      This patch provides arm64 specific implementations for the this_cpu
      operations. Rather than disable interrupts, we use the exclusive
      monitor or atomic operations as appropriate.
      
      The following operations are implemented: add, add_return, and, or,
      read, write, xchg. We also wire up a cmpxchg implementation from
      cmpxchg.h.
      
      Testing was performed using the percpu_test module and hackbench on a
      Juno board running 3.18-rc4.
      Signed-off-by: NSteve Capper <steve.capper@linaro.org>
      Reviewed-by: NWill Deacon <will.deacon@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      f97fc810
  3. 07 11月, 2014 1 次提交
    • S
      arm64: xchg: Implement cmpxchg_double · 5284e1b4
      Steve Capper 提交于
      The arm64 architecture has the ability to exclusively load and store
      a pair of registers from an address (ldxp/stxp). Also the SLUB can take
      advantage of a cmpxchg_double implementation to avoid taking some
      locks.
      
      This patch provides an implementation of cmpxchg_double for 64-bit
      pairs, and activates the logic required for the SLUB to use these
      functions (HAVE_ALIGNED_STRUCT_PAGE and HAVE_CMPXCHG_DOUBLE).
      
      Also definitions of this_cpu_cmpxchg_8 and this_cpu_cmpxchg_double_8
      are wired up to cmpxchg_local and cmpxchg_double_local (rather than the
      stock implementations that perform non-atomic operations with
      interrupts disabled) as they are used by the SLUB.
      
      On a Juno platform running on only the A57s I get quite a noticeable
      performance improvement with 5 runs of hackbench on v3.17:
      
               Baseline | With Patch
       -----------------+-----------
       Mean    119.2312 | 106.1782
       StdDev    0.4919 |   0.4494
      
      (times taken to complete `./hackbench 100 process 1000', in seconds)
      Signed-off-by: NSteve Capper <steve.capper@linaro.org>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      5284e1b4
  4. 10 5月, 2014 1 次提交
    • W
      arm64: xchg: prevent warning if return value is unused · e1dfda9c
      Will Deacon 提交于
      Some users of xchg() don't bother using the return value, which results
      in a compiler warning like the following (from kgdb):
      
      In file included from linux/arch/arm64/include/asm/atomic.h:27:0,
                       from include/linux/atomic.h:4,
                       from include/linux/spinlock.h:402,
                       from include/linux/seqlock.h:35,
                       from include/linux/time.h:5,
                       from include/uapi/linux/timex.h:56,
                       from include/linux/timex.h:56,
                       from include/linux/sched.h:19,
                       from include/linux/pid_namespace.h:4,
                       from kernel/debug/debug_core.c:30:
      kernel/debug/debug_core.c: In function ‘kgdb_cpu_enter’:
      linux/arch/arm64/include/asm/cmpxchg.h:75:3: warning: value computed is not used [-Wunused-value]
        ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
         ^
      linux/arch/arm64/include/asm/atomic.h:132:30: note: in expansion of macro ‘xchg’
       #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
      
      kernel/debug/debug_core.c:504:4: note: in expansion of macro ‘atomic_xchg’
          atomic_xchg(&kgdb_active, cpu);
          ^
      
      This patch makes use of the same trick as we do for cmpxchg, by assigning
      the return value to a dummy variable in the xchg() macro itself.
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      Signed-off-by: NCatalin Marinas <catalin.marinas@arm.com>
      e1dfda9c
  5. 08 2月, 2014 2 次提交
    • W
      arm64: asm: remove redundant "cc" clobbers · 95c41896
      Will Deacon 提交于
      cbnz/tbnz don't update the condition flags, so remove the "cc" clobbers
      from inline asm blocks that only use these instructions to implement
      conditional branches.
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      Signed-off-by: NCatalin Marinas <catalin.marinas@arm.com>
      95c41896
    • W
      arm64: atomics: fix use of acquire + release for full barrier semantics · 8e86f0b4
      Will Deacon 提交于
      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: NWill Deacon <will.deacon@arm.com>
      Signed-off-by: NCatalin Marinas <catalin.marinas@arm.com>
      8e86f0b4
  6. 20 12月, 2013 1 次提交
  7. 24 10月, 2013 1 次提交
  8. 23 4月, 2013 1 次提交
  9. 12 2月, 2013 1 次提交
    • W
      arm64: atomics: fix grossly inconsistent asm constraints for exclusives · 3a0310eb
      Will Deacon 提交于
      Our uses of inline asm constraints for atomic operations are fairly
      wild and varied. We basically need to guarantee the following:
      
        1. Any instructions with barrier implications
           (load-acquire/store-release) have a "memory" clobber
      
        2. When performing exclusive accesses, the addresing mode is generated
           using the "Q" constraint
      
        3. Atomic blocks which use the condition flags, have a "cc" clobber
      
      This patch addresses these concerns which, as well as fixing the
      semantics of the code, stops GCC complaining about impossible asm
      constraints.
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      Signed-off-by: NCatalin Marinas <catalin.marinas@arm.com>
      3a0310eb
  10. 17 9月, 2012 1 次提交