Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tools/memory-model: Switch to softcoded herd7 tags

A new version of herd7 provides a -lkmmv2 switch which overrides the old herd7
behavior of simply ignoring any softcoded tags in the .def and .bell files. We
port LKMM to this version of herd7 by providing the switch in linux-kernel.cfg
and reporting an error if the LKMM is used without this switch.

To preserve the semantics of LKMM, we also softcode the Noreturn tag on atomic
RMW which do not return a value and define atomic_add_unless with an Mb tag in
linux-kernel.def.

We update the herd-representation.txt accordingly and clarify some of the
resulting combinations.

Co-developed-by: Hernan Ponce de Leon <hernan.poncedeleon@huaweicloud.com>
Signed-off-by: Hernan Ponce de Leon <hernan.poncedeleon@huaweicloud.com>
Signed-off-by: Jonas Oberhauser <jonas.oberhauser@huaweicloud.com>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
Tested-by: Boqun Feng <boqun.feng@gmail.com>
Tested-by: Akira Yokosawa <akiyks@gmail.com> # herdtools7.7.58

authored by

Jonas Oberhauser and committed by
Paul E. McKenney
fafa1806 29279349

+30 -21
+15 -12
tools/memory-model/Documentation/herd-representation.txt
··· 18 18 # 19 19 # By convention, a blank line in a cell means "same as the preceding line". 20 20 # 21 + # Note that the syntactic representation does not always match the sets and 22 + # relations in linux-kernel.cat, due to redefinitions in linux-kernel.bell and 23 + # lock.cat. For example, the po link between LKR and LKW is upgraded to an rmw 24 + # link, and W[acquire] are not included in the Acquire set. 25 + # 21 26 # Disclaimer. The table includes representations of "add" and "and" operations; 22 27 # corresponding/identical representations of "sub", "inc", "dec" and "or", "xor", 23 28 # "andnot" operations are omitted. ··· 65 60 ------------------------------------------------------------------------------ 66 61 | RMW ops w/o return value | | 67 62 ------------------------------------------------------------------------------ 68 - | atomic_add | R*[noreturn] ->rmw W*[once] | 63 + | atomic_add | R*[noreturn] ->rmw W*[noreturn] | 69 64 | atomic_and | | 70 65 | spin_lock | LKR ->po LKW | 71 66 ------------------------------------------------------------------------------ 72 67 | RMW ops w/ return value | | 73 68 ------------------------------------------------------------------------------ 74 - | atomic_add_return | F[mb] ->po R*[once] | 75 - | | ->rmw W*[once] ->po F[mb] | 69 + | atomic_add_return | R*[mb] ->rmw W*[mb] | 76 70 | atomic_fetch_add | | 77 71 | atomic_fetch_and | | 78 72 | atomic_xchg | | ··· 83 79 | atomic_xchg_relaxed | | 84 80 | xchg_relaxed | | 85 81 | atomic_add_negative_relaxed | | 86 - | atomic_add_return_acquire | R*[acquire] ->rmw W*[once] | 82 + | atomic_add_return_acquire | R*[acquire] ->rmw W*[acquire] | 87 83 | atomic_fetch_add_acquire | | 88 84 | atomic_fetch_and_acquire | | 89 85 | atomic_xchg_acquire | | 90 86 | xchg_acquire | | 91 87 | atomic_add_negative_acquire | | 92 - | atomic_add_return_release | R*[once] ->rmw W*[release] | 88 + | atomic_add_return_release | R*[release] ->rmw W*[release] | 93 89 | atomic_fetch_add_release | | 94 90 | atomic_fetch_and_release | | 95 91 | atomic_xchg_release | | ··· 98 94 ------------------------------------------------------------------------------ 99 95 | Conditional RMW ops | | 100 96 ------------------------------------------------------------------------------ 101 - | atomic_cmpxchg | On success: F[mb] ->po R*[once] | 102 - | | ->rmw W*[once] ->po F[mb] | 103 - | | On failure: R*[once] | 97 + | atomic_cmpxchg | On success: R*[mb] ->rmw W*[mb] | 98 + | | On failure: R*[mb] | 104 99 | cmpxchg | | 105 100 | atomic_add_unless | | 106 101 | atomic_cmpxchg_relaxed | On success: R*[once] ->rmw W*[once] | 107 102 | | On failure: R*[once] | 108 - | atomic_cmpxchg_acquire | On success: R*[acquire] ->rmw W*[once] | 109 - | | On failure: R*[once] | 110 - | atomic_cmpxchg_release | On success: R*[once] ->rmw W*[release] | 111 - | | On failure: R*[once] | 103 + | atomic_cmpxchg_acquire | On success: R*[acquire] ->rmw W*[acquire] | 104 + | | On failure: R*[acquire] | 105 + | atomic_cmpxchg_release | On success: R*[release] ->rmw W*[release] | 106 + | | On failure: R*[release] | 112 107 | spin_trylock | On success: LKR ->po LKW | 113 108 | | On failure: LF | 114 109 ------------------------------------------------------------------------------
+1 -1
tools/memory-model/README
··· 20 20 REQUIREMENTS 21 21 ============ 22 22 23 - Version 7.52 or higher of the "herd7" and "klitmus7" tools must be 23 + Version 7.58 or higher of the "herd7" and "klitmus7" tools must be 24 24 downloaded separately: 25 25 26 26 https://github.com/herd/herdtools7
+3
tools/memory-model/linux-kernel.bell
··· 94 94 let addr = carry-dep ; addr 95 95 let ctrl = carry-dep ; ctrl 96 96 let data = carry-dep ; data 97 + 98 + flag ~empty (if "lkmmv2" then 0 else _) 99 + as this-model-requires-variant-higher-than-lkmmv1
+1
tools/memory-model/linux-kernel.cfg
··· 1 1 macros linux-kernel.def 2 2 bell linux-kernel.bell 3 3 model linux-kernel.cat 4 + variant lkmmv2 4 5 graph columns 5 6 squished true 6 7 showevents noregs
+10 -8
tools/memory-model/linux-kernel.def
··· 63 63 atomic_read_acquire(X) smp_load_acquire(X) 64 64 atomic_set_release(X,V) { smp_store_release(X,V); } 65 65 66 - atomic_add(V,X) { __atomic_op(X,+,V); } 67 - atomic_sub(V,X) { __atomic_op(X,-,V); } 68 - atomic_and(V,X) { __atomic_op(X,&,V); } 69 - atomic_or(V,X) { __atomic_op(X,|,V); } 70 - atomic_xor(V,X) { __atomic_op(X,^,V); } 71 - atomic_inc(X) { __atomic_op(X,+,1); } 72 - atomic_dec(X) { __atomic_op(X,-,1); } 73 - atomic_andnot(V,X) { __atomic_op(X,&~,V); } 66 + atomic_add(V,X) { __atomic_op{noreturn}(X,+,V); } 67 + atomic_sub(V,X) { __atomic_op{noreturn}(X,-,V); } 68 + atomic_and(V,X) { __atomic_op{noreturn}(X,&,V); } 69 + atomic_or(V,X) { __atomic_op{noreturn}(X,|,V); } 70 + atomic_xor(V,X) { __atomic_op{noreturn}(X,^,V); } 71 + atomic_inc(X) { __atomic_op{noreturn}(X,+,1); } 72 + atomic_dec(X) { __atomic_op{noreturn}(X,-,1); } 73 + atomic_andnot(V,X) { __atomic_op{noreturn}(X,&~,V); } 74 74 75 75 atomic_add_return(V,X) __atomic_op_return{mb}(X,+,V) 76 76 atomic_add_return_relaxed(V,X) __atomic_op_return{once}(X,+,V) ··· 144 144 atomic_fetch_andnot_acquire(V,X) __atomic_fetch_op{acquire}(X,&~,V) 145 145 atomic_fetch_andnot_release(V,X) __atomic_fetch_op{release}(X,&~,V) 146 146 atomic_fetch_andnot_relaxed(V,X) __atomic_fetch_op{once}(X,&~,V) 147 + 148 + atomic_add_unless(X,V,W) __atomic_add_unless{mb}(X,V,W)