aboutsummaryrefslogtreecommitdiff
path: root/docs/devel/atomics.rst
AgeCommit message (Collapse)Author
2023-06-06atomics: eliminate mb_read/mb_setPaolo Bonzini
qatomic_mb_read and qatomic_mb_set were the very first atomic primitives introduced for QEMU; their semantics are unclear and they provide a false sense of safety. The last use of qatomic_mb_read() has been removed, so delete it. qatomic_mb_set() instead can survive as an optimized qatomic_set()+smp_mb(), similar to Linux's smp_store_mb(), but rename it to qatomic_set_mb() to match the order of the two operations. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2023-04-20docs: explain effect of smp_read_barrier_depends() on modern architecturesPaolo Bonzini
The documentation for smp_read_barrier_depends() does not mention the architectures for which it is an optimization, for example ARM and PPC. As a result, it is not clear to the reader why one would use it. Relegate Alpha to a footnote together with other architectures where it is equivalent to smp_rmb(). Suggested-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2023-03-15docs/devel: clarify further the semantics of RMW operationsPaolo Bonzini
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2023-03-07qatomic: add smp_mb__before/after_rmw()Paolo Bonzini
On ARM, seqcst loads and stores (which QEMU does not use) are compiled respectively as LDAR and STLR instructions. Even though LDAR is also used for load-acquire operations, it also waits for all STLRs to leave the store buffer. Thus, LDAR and STLR alone are load-acquire and store-release operations, but LDAR also provides store-against-load ordering as long as the previous store is a STLR. Compare this to ARMv7, where store-release is DMB+STR and load-acquire is LDR+DMB, but an additional DMB is needed between store-seqcst and load-seqcst (e.g. DMB+STR+DMB+LDR+DMB); or with x86, where MOV provides load-acquire and store-release semantics and the two can be reordered. Likewise, on ARM sequentially consistent read-modify-write operations only need to use LDAXR and STLXR respectively for the load and the store, while on x86 they need to use the stronger LOCK prefix. In a strange twist of events, however, the _stronger_ semantics of the ARM instructions can end up causing bugs on ARM, not on x86. The problems occur when seqcst atomics are mixed with relaxed atomics. QEMU's atomics try to bridge the Linux API (that most of the developers are familiar with) and the C11 API, and the two have a substantial difference: - in Linux, strongly-ordered atomics such as atomic_add_return() affect the global ordering of _all_ memory operations, including for example READ_ONCE()/WRITE_ONCE() - in C11, sequentially consistent atomics (except for seq-cst fences) only affect the ordering of sequentially consistent operations. In particular, since relaxed loads are done with LDR on ARM, they are not ordered against seqcst stores (which are done with STLR). QEMU implements high-level synchronization primitives with the idea that the primitives contain the necessary memory barriers, and the callers can use relaxed atomics (qatomic_read/qatomic_set) or even regular accesses. This is very much incompatible with the C11 view that seqcst accesses are only ordered against other seqcst accesses, and requires using seqcst fences as in the following example: qatomic_set(&y, 1); qatomic_set(&x, 1); smp_mb(); smp_mb(); ... qatomic_read(&x) ... ... qatomic_read(&y) ... When a qatomic_*() read-modify write operation is used instead of one or both stores, developers that are more familiar with the Linux API may be tempted to omit the smp_mb(), which will work on x86 but not on ARM. This nasty difference between Linux and C11 read-modify-write operations has already caused issues in util/async.c and more are being found. Provide something similar to Linux smp_mb__before/after_atomic(); this has the double function of documenting clearly why there is a memory barrier, and avoiding a double barrier on x86 and s390x systems. The new macro can already be put to use in qatomic_mb_set(). Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: David Hildenbrand <david@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2023-01-04tcg: convert tcg/README to rstMark Cave-Ayland
Convert tcg/README to rst and move it to docs/devel as a new "TCG Intermediate Representation" page. There are a few minor changes to improve the aesthetic of the final output which are as follows: - Rename the title from "Tiny Code Generator - Fabrice Bellard" to "TCG Intermediate Representation" - Remove the section numbering - Add the missing parameters to the ssadd_vec operations in the "Host vector operations" section - Change the path to the Atomic Operations document to use a proper reference - Replace tcg/README in tcg.rst with a proper reference to the new document Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Fabiano Rosas <farosas@suse.de> Message-Id: <20221130100434.64207-2-mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2020-09-23qemu/atomic.h: rename atomic_ to qatomic_Stefan Hajnoczi
clang's C11 atomic_fetch_*() functions only take a C11 atomic type pointer argument. QEMU uses direct types (int, etc) and this causes a compiler error when a QEMU code calls these functions in a source file that also included <stdatomic.h> via a system header file: $ CC=clang CXX=clang++ ./configure ... && make ../util/async.c:79:17: error: address argument to atomic operation must be a pointer to _Atomic type ('unsigned int *' invalid) Avoid using atomic_*() names in QEMU's atomic.h since that namespace is used by <stdatomic.h>. Prefix QEMU's APIs with 'q' so that atomic.h and <stdatomic.h> can co-exist. I checked /usr/include on my machine and searched GitHub for existing "qatomic_" users but there seem to be none. This patch was generated using: $ git grep -h -o '\<atomic\(64\)\?_[a-z0-9_]\+' include/qemu/atomic.h | \ sort -u >/tmp/changed_identifiers $ for identifier in $(</tmp/changed_identifiers); do sed -i "s%\<$identifier\>%q$identifier%g" \ $(git grep -I -l "\<$identifier\>") done I manually fixed line-wrap issues and misaligned rST tables. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Acked-by: Paolo Bonzini <pbonzini@redhat.com> Message-Id: <20200923105646.47864-1-stefanha@redhat.com>
2020-04-13atomics: update documentationPaolo Bonzini
Some of the constraints on operand sizes have been relaxed, so adjust the documentation. Deprecate atomic_mb_read and atomic_mb_set; it is not really possible to use them correctly because they do not interoperate with sequentially-consistent RMW operations. Finally, extend the memory barrier pairing section to cover acquire and release semantics in general, roughly based on the KVM Forum 2016 talk, "<atomic.h> weapons". Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2020-04-11atomics: convert to reStructuredTextPaolo Bonzini
No attempts to fix or update the text; these are left for the next patch in the series. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>