Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753233AbdHJMPo (ORCPT ); Thu, 10 Aug 2017 08:15:44 -0400 Received: from terminus.zytor.com ([65.50.211.136]:33257 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753220AbdHJMPk (ORCPT ); Thu, 10 Aug 2017 08:15:40 -0400 Date: Thu, 10 Aug 2017 05:10:56 -0700 From: tip-bot for Peter Zijlstra Message-ID: Cc: torvalds@linux-foundation.org, boqun.feng@gmail.com, mingo@kernel.org, linux-kernel@vger.kernel.org, paulmck@linux.vnet.ibm.com, peterz@infradead.org, will.deacon@arm.com, tglx@linutronix.de, hpa@zytor.com Reply-To: linux-kernel@vger.kernel.org, mingo@kernel.org, will.deacon@arm.com, tglx@linutronix.de, hpa@zytor.com, peterz@infradead.org, paulmck@linux.vnet.ibm.com, torvalds@linux-foundation.org, boqun.feng@gmail.com In-Reply-To: <20170609110506.yod47flaav3wgoj5@hirez.programming.kicks-ass.net> References: <20170609110506.yod47flaav3wgoj5@hirez.programming.kicks-ass.net> To: linux-tip-commits@vger.kernel.org Subject: [tip:locking/core] locking/atomic: Fix atomic_set_release() for 'funny' architectures Git-Commit-ID: 9d664c0aec3bfdb77fcf7de61cfe1febbecdd389 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5158 Lines: 140 Commit-ID: 9d664c0aec3bfdb77fcf7de61cfe1febbecdd389 Gitweb: http://git.kernel.org/tip/9d664c0aec3bfdb77fcf7de61cfe1febbecdd389 Author: Peter Zijlstra AuthorDate: Fri, 9 Jun 2017 13:05:06 +0200 Committer: Ingo Molnar CommitDate: Thu, 10 Aug 2017 12:28:54 +0200 locking/atomic: Fix atomic_set_release() for 'funny' architectures Those architectures that have a special atomic_set implementation also need a special atomic_set_release(), because for the very same reason WRITE_ONCE() is broken for them, smp_store_release() is too. The vast majority is architectures that have spinlock hash based atomic implementation except hexagon which seems to have a hardware 'feature'. The spinlock based atomics should be SC, that is, none of them appear to place extra barriers in atomic_cmpxchg() or any of the other SC atomic primitives and therefore seem to rely on their spinlock implementation being SC (I did not fully validate all that). Therefore, the normal atomic_set() is SC and can be used at atomic_set_release(). Signed-off-by: Peter Zijlstra (Intel) Acked-by: Chris Metcalf [for tile] Cc: Boqun Feng Cc: Linus Torvalds Cc: Paul McKenney Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Will Deacon Cc: davem@davemloft.net Cc: james.hogan@imgtec.com Cc: jejb@parisc-linux.org Cc: rkuo@codeaurora.org Cc: vgupta@synopsys.com Link: http://lkml.kernel.org/r/20170609110506.yod47flaav3wgoj5@hirez.programming.kicks-ass.net Signed-off-by: Ingo Molnar --- arch/arc/include/asm/atomic.h | 2 ++ arch/hexagon/include/asm/atomic.h | 2 ++ arch/metag/include/asm/atomic_lock1.h | 2 ++ arch/parisc/include/asm/atomic.h | 2 ++ arch/sparc/include/asm/atomic_32.h | 2 ++ arch/tile/include/asm/atomic_32.h | 2 ++ include/asm-generic/atomic64.h | 2 ++ 7 files changed, 14 insertions(+) diff --git a/arch/arc/include/asm/atomic.h b/arch/arc/include/asm/atomic.h index 54b54da..1185928 100644 --- a/arch/arc/include/asm/atomic.h +++ b/arch/arc/include/asm/atomic.h @@ -123,6 +123,8 @@ static inline void atomic_set(atomic_t *v, int i) atomic_ops_unlock(flags); } +#define atomic_set_release(v, i) atomic_set((v), (i)) + #endif /* diff --git a/arch/hexagon/include/asm/atomic.h b/arch/hexagon/include/asm/atomic.h index a62ba36..fb3dfb2 100644 --- a/arch/hexagon/include/asm/atomic.h +++ b/arch/hexagon/include/asm/atomic.h @@ -42,6 +42,8 @@ static inline void atomic_set(atomic_t *v, int new) ); } +#define atomic_set_release(v, i) atomic_set((v), (i)) + /** * atomic_read - reads a word, atomically * @v: pointer to atomic value diff --git a/arch/metag/include/asm/atomic_lock1.h b/arch/metag/include/asm/atomic_lock1.h index 6c1380a..eee779f 100644 --- a/arch/metag/include/asm/atomic_lock1.h +++ b/arch/metag/include/asm/atomic_lock1.h @@ -37,6 +37,8 @@ static inline int atomic_set(atomic_t *v, int i) return i; } +#define atomic_set_release(v, i) atomic_set((v), (i)) + #define ATOMIC_OP(op, c_op) \ static inline void atomic_##op(int i, atomic_t *v) \ { \ diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h index 5394b9c..17b98a8 100644 --- a/arch/parisc/include/asm/atomic.h +++ b/arch/parisc/include/asm/atomic.h @@ -65,6 +65,8 @@ static __inline__ void atomic_set(atomic_t *v, int i) _atomic_spin_unlock_irqrestore(v, flags); } +#define atomic_set_release(v, i) atomic_set((v), (i)) + static __inline__ int atomic_read(const atomic_t *v) { return READ_ONCE((v)->counter); diff --git a/arch/sparc/include/asm/atomic_32.h b/arch/sparc/include/asm/atomic_32.h index ee3f11c..7643e97 100644 --- a/arch/sparc/include/asm/atomic_32.h +++ b/arch/sparc/include/asm/atomic_32.h @@ -29,6 +29,8 @@ int atomic_xchg(atomic_t *, int); int __atomic_add_unless(atomic_t *, int, int); void atomic_set(atomic_t *, int); +#define atomic_set_release(v, i) atomic_set((v), (i)) + #define atomic_read(v) ACCESS_ONCE((v)->counter) #define atomic_add(i, v) ((void)atomic_add_return( (int)(i), (v))) diff --git a/arch/tile/include/asm/atomic_32.h b/arch/tile/include/asm/atomic_32.h index a937742..53a423e 100644 --- a/arch/tile/include/asm/atomic_32.h +++ b/arch/tile/include/asm/atomic_32.h @@ -101,6 +101,8 @@ static inline void atomic_set(atomic_t *v, int n) _atomic_xchg(&v->counter, n); } +#define atomic_set_release(v, i) atomic_set((v), (i)) + /* A 64bit atomic type */ typedef struct { diff --git a/include/asm-generic/atomic64.h b/include/asm-generic/atomic64.h index dad68bf..8d28eb0 100644 --- a/include/asm-generic/atomic64.h +++ b/include/asm-generic/atomic64.h @@ -21,6 +21,8 @@ typedef struct { extern long long atomic64_read(const atomic64_t *v); extern void atomic64_set(atomic64_t *v, long long i); +#define atomic64_set_release(v, i) atomic64_set((v), (i)) + #define ATOMIC64_OP(op) \ extern void atomic64_##op(long long a, atomic64_t *v);