From patchwork Thu Jun 21 12:13:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Rutland X-Patchwork-Id: 139534 Delivered-To: patch@linaro.org Received: by 2002:a2e:970d:0:0:0:0:0 with SMTP id r13-v6csp1991782lji; Thu, 21 Jun 2018 05:14:06 -0700 (PDT) X-Google-Smtp-Source: ADUXVKJSv5YozmZlkzOTxrk1zXWJSjLH7IB1DjQY0AB/hRdKXKd/nsmIsEkpIKK6a/MriRf/Ausn X-Received: by 2002:a62:a8e:: with SMTP id 14-v6mr27082023pfk.57.1529583246730; Thu, 21 Jun 2018 05:14:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1529583246; cv=none; d=google.com; s=arc-20160816; b=nIgybKTbhqXVSb36QFPVUUG9QLG0wf+wqRUPgqj7zP5t9KMLt5/uCw6GRDjLXDV9hz bSqPAnj2GwZngpDScjhCEHZpm99nGY3mZhubdlNb64JgdpPfE48ViZicAV8NDzW3BY/U woBTeeP4GAXnIMUyBzsqAQFYSigA0loPqakkFu6m9sYJu9d8CCaZ09dif7RWY7XhwcLo SolVMdGfa++6du8BpKdIoc5d3AiyEsYfTb7HDYDrx+HJ4PLr+B3BD1nZHc17V+st8GaK 808KfV5M9N9Cg1JOM3MrijdRnQDeAF94JAXVvls6ELZc1BPv2h9xBSkFRJg/3xepbz1+ J7bw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=91317aOK6qhHniFFw5ZDkLTporPt/s7O4PaaWnt2qD8=; b=qwTMcj73JbAUprS3VG41JxisobW/KUfzSuXv56VWZLxil9EoXGF2zRp26f2/fK9sGf 4TULlVL9E8szRcybViqABP1erJnDCSf29T8Djijye6Y6heaKf0c9OqnRtOmQjuA2Y5a2 OxFP3lBZ1Zt86GhGorH0CWiCEoAahBF9b38mOcHv/Xfk1f25m95Jy3IkJc95uhRo21VX jiERmpW/8HB9l0aCN6hGFM3rNFjQoQvZJIWDpqhX9t/poJNHunhnN6pWkdya7jVoJik5 lnTDWWFNB+OgHlMgoYEiMFtDV0ql1MHhWvBxwMaIeYgejBMgVRaWSL4+h7fsYPYDuXyh JEjQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f90-v6si4668924pfe.291.2018.06.21.05.14.06; Thu, 21 Jun 2018 05:14:06 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933772AbeFUMOE (ORCPT + 30 others); Thu, 21 Jun 2018 08:14:04 -0400 Received: from foss.arm.com ([217.140.101.70]:49420 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933743AbeFUMOC (ORCPT ); Thu, 21 Jun 2018 08:14:02 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 5C9F31529; Thu, 21 Jun 2018 05:14:02 -0700 (PDT) Received: from lakrids.cambridge.arm.com (usa-sjc-imap-foss1.foss.arm.com [10.72.51.249]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 291893F578; Thu, 21 Jun 2018 05:14:01 -0700 (PDT) From: Mark Rutland To: mingo@kernel.org, will.deacon@arm.com, peterz@infradead.org, linux-kernel@vger.kernel.org Cc: Mark Rutland , Boqun Feng Subject: [PATCHv4 14/18] atomics/treewide: make atomic64_fetch_add_unless() optional Date: Thu, 21 Jun 2018 13:13:17 +0100 Message-Id: <20180621121321.4761-15-mark.rutland@arm.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180621121321.4761-1-mark.rutland@arm.com> References: <20180621121321.4761-1-mark.rutland@arm.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Architectures with atomic64_fetch_add_unless() provide a preprocessor symbol if they do so, and all other architectures have trivial C implementations of atomic64_add_unless() which are near-identical. Let's unify the trivial definitions of atomic64_fetch_add_unless() in , so that we always have both atomic64_fetch_add_unless() and atomic64_add_unless() with less boilerplate code. This means that atomic64_add_unless() is always implemented in core code, and the instrumented atomics are updated accordingly. There should be no functional change as a result of this patch. Signed-off-by: Mark Rutland Acked-by: Peter Zijlstra (Intel) Reviewed-by: Will Deacon Cc: Boqun Feng --- arch/arm64/include/asm/atomic.h | 12 ------------ arch/ia64/include/asm/atomic.h | 15 --------------- arch/mips/include/asm/atomic.h | 24 ------------------------ arch/parisc/include/asm/atomic.h | 24 ------------------------ arch/s390/include/asm/atomic.h | 16 ---------------- arch/sparc/include/asm/atomic_64.h | 15 --------------- arch/x86/include/asm/atomic64_64.h | 19 ------------------- include/asm-generic/atomic-instrumented.h | 6 ------ include/linux/atomic.h | 26 ++++++++++++++++++++++++-- 9 files changed, 24 insertions(+), 133 deletions(-) -- 2.11.0 diff --git a/arch/arm64/include/asm/atomic.h b/arch/arm64/include/asm/atomic.h index 22c8c43d6689..82db0e4febd4 100644 --- a/arch/arm64/include/asm/atomic.h +++ b/arch/arm64/include/asm/atomic.h @@ -40,17 +40,6 @@ #include -#define ___atomic_add_unless(v, a, u, sfx) \ -({ \ - typeof((v)->counter) c, old; \ - \ - c = atomic##sfx##_read(v); \ - while (c != (u) && \ - (old = atomic##sfx##_cmpxchg((v), c, c + (a))) != c) \ - c = old; \ - c; \ - }) - #define ATOMIC_INIT(i) { (i) } #define atomic_read(v) READ_ONCE((v)->counter) @@ -200,7 +189,6 @@ #define atomic64_dec_and_test(v) (atomic64_dec_return(v) == 0) #define atomic64_sub_and_test(i, v) (atomic64_sub_return((i), (v)) == 0) #define atomic64_add_negative(i, v) (atomic64_add_return((i), (v)) < 0) -#define atomic64_add_unless(v, a, u) (___atomic_add_unless(v, a, u, 64) != u) #define atomic64_andnot atomic64_andnot #endif diff --git a/arch/ia64/include/asm/atomic.h b/arch/ia64/include/asm/atomic.h index cfe44086338e..0f80a3eafaba 100644 --- a/arch/ia64/include/asm/atomic.h +++ b/arch/ia64/include/asm/atomic.h @@ -215,21 +215,6 @@ ATOMIC64_FETCH_OP(xor, ^) (cmpxchg(&((v)->counter), old, new)) #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) -static __inline__ long atomic64_add_unless(atomic64_t *v, long a, long u) -{ - long c, old; - c = atomic64_read(v); - for (;;) { - if (unlikely(c == (u))) - break; - old = atomic64_cmpxchg((v), c, c + (a)); - if (likely(old == c)) - break; - c = old; - } - return c != (u); -} - static __inline__ long atomic64_dec_if_positive(atomic64_t *v) { long c, old, dec; diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h index 794734e730d9..d42b27df1548 100644 --- a/arch/mips/include/asm/atomic.h +++ b/arch/mips/include/asm/atomic.h @@ -596,30 +596,6 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n))) #define atomic64_xchg(v, new) (xchg(&((v)->counter), (new))) -/** - * atomic64_add_unless - add unless the number is a given value - * @v: pointer of type atomic64_t - * @a: the amount to add to v... - * @u: ...unless v is equal to u. - * - * Atomically adds @a to @v, so long as it was not @u. - * Returns true iff @v was not @u. - */ -static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) -{ - long c, old; - c = atomic64_read(v); - for (;;) { - if (unlikely(c == (u))) - break; - old = atomic64_cmpxchg((v), c, c + (a)); - if (likely(old == c)) - break; - c = old; - } - return c != (u); -} - #define atomic64_dec_return(v) atomic64_sub_return(1, (v)) #define atomic64_inc_return(v) atomic64_add_return(1, (v)) diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h index b2b6261d05e7..f53ba2d6ff67 100644 --- a/arch/parisc/include/asm/atomic.h +++ b/arch/parisc/include/asm/atomic.h @@ -257,30 +257,6 @@ atomic64_read(const atomic64_t *v) ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n))) #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) -/** - * atomic64_add_unless - add unless the number is a given value - * @v: pointer of type atomic64_t - * @a: the amount to add to v... - * @u: ...unless v is equal to u. - * - * Atomically adds @a to @v, so long as it was not @u. - * Returns the old value of @v. - */ -static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) -{ - long c, old; - c = atomic64_read(v); - for (;;) { - if (unlikely(c == (u))) - break; - old = atomic64_cmpxchg((v), c, c + (a)); - if (likely(old == c)) - break; - c = old; - } - return c != (u); -} - /* * atomic64_dec_if_positive - decrement by 1 if old value positive * @v: pointer of type atomic_t diff --git a/arch/s390/include/asm/atomic.h b/arch/s390/include/asm/atomic.h index 26c6b713a7a3..eb9329741bad 100644 --- a/arch/s390/include/asm/atomic.h +++ b/arch/s390/include/asm/atomic.h @@ -153,22 +153,6 @@ ATOMIC64_OPS(xor) #undef ATOMIC64_OPS -static inline int atomic64_add_unless(atomic64_t *v, long i, long u) -{ - long c, old; - - c = atomic64_read(v); - for (;;) { - if (unlikely(c == u)) - break; - old = atomic64_cmpxchg(v, c, c + i); - if (likely(old == c)) - break; - c = old; - } - return c != u; -} - static inline long atomic64_dec_if_positive(atomic64_t *v) { long c, old, dec; diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h index e4f1c93db31f..458783e99997 100644 --- a/arch/sparc/include/asm/atomic_64.h +++ b/arch/sparc/include/asm/atomic_64.h @@ -93,21 +93,6 @@ static inline int atomic_xchg(atomic_t *v, int new) ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n))) #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) -static inline long atomic64_add_unless(atomic64_t *v, long a, long u) -{ - long c, old; - c = atomic64_read(v); - for (;;) { - if (unlikely(c == (u))) - break; - old = atomic64_cmpxchg((v), c, c + (a)); - if (likely(old == c)) - break; - c = old; - } - return c != (u); -} - long atomic64_dec_if_positive(atomic64_t *v); #endif /* !(__ARCH_SPARC64_ATOMIC__) */ diff --git a/arch/x86/include/asm/atomic64_64.h b/arch/x86/include/asm/atomic64_64.h index 6f95023894b7..7e04b294e6eb 100644 --- a/arch/x86/include/asm/atomic64_64.h +++ b/arch/x86/include/asm/atomic64_64.h @@ -188,25 +188,6 @@ static inline long arch_atomic64_xchg(atomic64_t *v, long new) return xchg(&v->counter, new); } -/** - * arch_atomic64_add_unless - add unless the number is a given value - * @v: pointer of type atomic64_t - * @a: the amount to add to v... - * @u: ...unless v is equal to u. - * - * Atomically adds @a to @v, so long as it was not @u. - * Returns the old value of @v. - */ -static inline bool arch_atomic64_add_unless(atomic64_t *v, long a, long u) -{ - s64 c = arch_atomic64_read(v); - do { - if (unlikely(c == u)) - return false; - } while (!arch_atomic64_try_cmpxchg(v, &c, c + a)); - return true; -} - /* * arch_atomic64_dec_if_positive - decrement by 1 if old value positive * @v: pointer of type atomic_t diff --git a/include/asm-generic/atomic-instrumented.h b/include/asm-generic/atomic-instrumented.h index 444bf2f9d54d..2b487f28ef35 100644 --- a/include/asm-generic/atomic-instrumented.h +++ b/include/asm-generic/atomic-instrumented.h @@ -100,12 +100,6 @@ static __always_inline s64 atomic64_fetch_add_unless(atomic64_t *v, s64 a, s64 u kasan_check_write(v, sizeof(*v)); return arch_atomic64_fetch_add_unless(v, a, u); } -#else -static __always_inline bool atomic64_add_unless(atomic64_t *v, s64 a, s64 u) -{ - kasan_check_write(v, sizeof(*v)); - return arch_atomic64_add_unless(v, a, u); -} #endif static __always_inline void atomic_inc(atomic_t *v) diff --git a/include/linux/atomic.h b/include/linux/atomic.h index 3c03de648007..530562ac7909 100644 --- a/include/linux/atomic.h +++ b/include/linux/atomic.h @@ -1043,6 +1043,30 @@ static inline int atomic_dec_if_positive(atomic_t *v) #endif /* atomic64_try_cmpxchg */ /** + * atomic64_fetch_add_unless - add unless the number is already a given value + * @v: pointer of type atomic64_t + * @a: the amount to add to v... + * @u: ...unless v is equal to u. + * + * Atomically adds @a to @v, if @v was not already @u. + * Returns the original value of @v. + */ +#ifndef atomic64_fetch_add_unless +static inline long long atomic64_fetch_add_unless(atomic64_t *v, long long a, + long long u) +{ + long long c = atomic64_read(v); + + do { + if (unlikely(c == u)) + break; + } while (!atomic64_try_cmpxchg(v, &c, c + a)); + + return c; +} +#endif + +/** * atomic64_add_unless - add unless the number is already a given value * @v: pointer of type atomic_t * @a: the amount to add to v... @@ -1051,12 +1075,10 @@ static inline int atomic_dec_if_positive(atomic_t *v) * Atomically adds @a to @v, if @v was not already @u. * Returns true if the addition was done. */ -#ifdef atomic64_fetch_add_unless static inline bool atomic64_add_unless(atomic64_t *v, long long a, long long u) { return atomic64_fetch_add_unless(v, a, u) != u; } -#endif /** * atomic64_inc_not_zero - increment unless the number is zero