Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751568AbdGZQ2v (ORCPT ); Wed, 26 Jul 2017 12:28:51 -0400 Received: from merlin.infradead.org ([205.233.59.134]:49768 "EHLO merlin.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750867AbdGZQ2t (ORCPT ); Wed, 26 Jul 2017 12:28:49 -0400 Subject: Re: [RFC][PATCH v3]: documentation,atomic: Add new documents To: Peter Zijlstra , Boqun Feng Cc: Will Deacon , Paul McKenney , linux-kernel@vger.kernel.org, Ingo Molnar , Thomas Gleixner References: <20170609092450.jwmldgtli57ozxgq@hirez.programming.kicks-ass.net> <20170609154442.GB9236@arm.com> <20170609193604.ncw3hhgvewzc3h5u@hirez.programming.kicks-ass.net> <20170611135632.sl72klbeklelupej@tardis> <20170612144929.3wiwtbqopsfpm3qk@hirez.programming.kicks-ass.net> <20170726115328.2sxiitivlnlq64dk@hirez.programming.kicks-ass.net> From: Randy Dunlap Message-ID: <2a0f5fc7-4096-dcb7-ac3b-29c4552a5462@infradead.org> Date: Wed, 26 Jul 2017 09:28:42 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.2.1 MIME-Version: 1.0 In-Reply-To: <20170726115328.2sxiitivlnlq64dk@hirez.programming.kicks-ass.net> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5171 Lines: 208 nits... On 07/26/2017 04:53 AM, Peter Zijlstra wrote: > --- > Subject: documentation,atomic: Add new documents > From: Peter Zijlstra > Date: Mon Jun 12 14:50:27 CEST 2017 > > Since we've vastly expanded the atomic_t interface in recent years the > existing documentation is woefully out of date and people seem to get > confused a bit. > > Start a new document to hopefully better explain the current state of > affairs. > > The old atomic_ops.txt also covers bitmaps and a few more details so > this is not a full replacement and we'll therefore keep that document > around until such a time that we've managed to write more text to cover > its entire. > > Also please, ReST people, go away. > > Signed-off-by: Peter Zijlstra (Intel) > --- > Documentation/atomic_bitops.txt | 66 ++++++++++++ > Documentation/atomic_t.txt | 200 ++++++++++++++++++++++++++++++++++++++ > Documentation/memory-barriers.txt | 88 ---------------- > 3 files changed, 269 insertions(+), 85 deletions(-) > > --- /dev/null > +++ b/Documentation/atomic_bitops.txt > @@ -0,0 +1,66 @@ > + > +On atomic bitops. > + > + > +While our bitmap_{}() functions are non-atomic, we have a number of operations > +operating on single bits in a bitmap that are atomic. > + > + > +API > +--- > + > +The single bit operations are: > + > +Non RmW ops: Non-RmW ops: > + > + test_bit() > + [] > --- /dev/null > +++ b/Documentation/atomic_t.txt > @@ -0,0 +1,200 @@ > + > +On atomic types (atomic_t atomic64_t and atomic_long_t). > + > +The atomic type provides an interface to the architecture's means of atomic > +RmW operations between CPUs (atomic operations on MMIO are not supported and > +can lead to fatal traps on some platforms). > + > +API > +--- > + > +The 'full' API consists of (atomic64_ and atomic_long_ prefixes omitted for > +brevity): > + > +Non RmW ops: Non-RmW ops: > + > + atomic_read(), atomic_set() > + atomic_read_acquire(), atomic_set_release() > + > + > +RmW atomic operations: > + > +Arithmetic: > + > + atomic_{add,sub,inc,dec}() > + atomic_{add,sub,inc,dec}_return{,_relaxed,_acquire,_release}() > + atomic_fetch_{add,sub,inc,dec}{,_relaxed,_acquire,_release}() > + > + > +Bitwise: > + > + atomic_{and,or,xor,andnot}() > + atomic_fetch_{and,or,xor,andnot}{,_relaxed,_acquire,_release}() > + > + > +Swap: > + > + atomic_xchg{,_relaxed,_acquire,_release}() > + atomic_cmpxchg{,_relaxed,_acquire,_release}() > + atomic_try_cmpxchg{,_relaxed,_acquire,_release}() > + > + > +Reference count (but please see refcount_t): > + > + atomic_add_unless(), atomic_inc_not_zero() > + atomic_sub_and_test(), atomic_dec_and_test() > + > + > +Misc: > + > + atomic_inc_and_test(), atomic_add_negative() > + atomic_dec_unless_positive(), atomic_inc_unless_negative() > + > + > +Barriers: > + > + smp_mb__{before,after}_atomic() > + > + > + > +SEMANTICS > +--------- > + > +Non RmW ops: Non-RmW ops: > + > +The non-RmW ops are (typically) regular LOADs and STOREs and are canonically > +implemented using READ_ONCE(), WRITE_ONCE(), smp_load_acquire() and > +smp_store_release() respectively. > + > +The one detail to this is that atomic_set{}() should be observable to the RmW > +ops. That is: > + > + C atomic-set > + > + { > + atomic_set(v, 1); > + } > + > + P1(atomic_t *v) > + { > + atomic_add_unless(v, 1, 0); > + } > + > + P2(atomic_t *v) > + { > + atomic_set(v, 0); > + } > + > + exists > + (v=2) > + > +In this case we would expect the atomic_set() from CPU1 to either happen > +before the atomic_add_unless(), in which case that latter one would no-op, or > +_after_ in which case we'd overwrite its result. In no case is "2" a valid > +outcome. > + > +This is typically true on 'normal' platforms, where a regular competing STORE > +will invalidate a LL/SC or fail a CMPXCHG. > + > +The obvious case where this is not so is when we need to implement atomic ops > +with a lock: > + > + CPU0 CPU1 > + > + atomic_add_unless(v, 1, 0); > + lock(); > + ret = READ_ONCE(v->counter); // == 1 > + atomic_set(v, 0); > + if (ret != u) WRITE_ONCE(v->counter, 0); > + WRITE_ONCE(v->counter, ret + 1); > + unlock(); > + > +the typical solution is to then implement atomic_set{}() with atomic_xchg(). > + > + > +RmW ops: I prefer (and have usually seen) RMW, but it's your document -- er, text file. :) > + > +These come in various forms: > + [] > --- a/Documentation/memory-barriers.txt > +++ b/Documentation/memory-barriers.txt > @@ -498,7 +498,7 @@ VARIETIES OF MEMORY BARRIER > This means that ACQUIRE acts as a minimal "acquire" operation and > RELEASE acts as a minimal "release" operation. > > -A subset of the atomic operations described in core-api/atomic_ops.rst have > +A subset of the atomic operations described in atomic_t.txt have ACQUIRE > ACQUIRE and RELEASE variants in addition to fully-ordered and relaxed (no duplicate ACQUIRE. > barrier semantics) definitions. For compound atomics performing both a load > and a store, ACQUIRE semantics apply only to the load and RELEASE semantics -- ~Randy