XenevaOS
Loading...
Searching...
No Matches
barrier.h
Go to the documentation of this file.
1#ifndef __ASM_BARRIER_H__
2#define __ASM_BARRIER_H__
3
4/*
5 * DCL <asm/barrier.h> -- memory-barrier primitives.
6 *
7 * DCL keeps the ordering primitives in <linux/kernel.h> (READ_ONCE,
8 * WRITE_ONCE, smp_load_acquire, smp_store_release, smp_{mb,rmb,wmb}) because
9 * that is where the tty/serial ports pick them up, and every one of them is
10 * guarded. This header exists so that a mainline source can include it the
11 * way mainline does -- virtio-rng.c:7 is `#include <asm/barrier.h>` and it is
12 * the first include in the file -- without needing to know which of the two
13 * places a given primitive happens to live in.
14 *
15 * What kernel.h does NOT have is the compiler-only barrier and the plain
16 * {mb,rmb,wmb} family, so those are defined here.
17 *
18 * `barrier()` is deliberately a *compiler* fence and not a hardware one.
19 * mainline's asm-generic version is an empty asm with a "memory" clobber: its
20 * job is to stop the compiler from moving a load or store across the point in
21 * the source, and it must not cost an instruction. __atomic_signal_fence()
22 * states exactly that -- signal-scope, i.e. compiler-only -- and works on a
23 * target where an empty `__asm__` template would be a question mark. A
24 * hardware ordering guarantee is smp_mb()'s job, in kernel.h.
25 */
26
27#include <linux/kernel.h>
28
29#ifndef barrier
30#define barrier() __atomic_signal_fence(__ATOMIC_SEQ_CST)
31#endif
32
33/*
34 * mb/rmb/wmb are the plain, unconditional hardware barriers. DCL is a
35 * UP-ish kernel with a strong ordering habit: everything that needs one of
36 * these is on the device-facing side (the virtio used-ring read below is the
37 * current user), and getting a relaxed fence wrong there costs a torn
38 * descriptor, so all three map to the sequential-consistency fence rather
39 * than to a cheaper acquire/release pair. If a port ever needs the weaker
40 * form, it should say so at the call site.
41 */
42#ifndef mb
43#define mb() __atomic_thread_fence(__ATOMIC_SEQ_CST)
44#endif
45#ifndef rmb
46#define rmb() __atomic_thread_fence(__ATOMIC_ACQUIRE)
47#endif
48#ifndef wmb
49#define wmb() __atomic_thread_fence(__ATOMIC_RELEASE)
50#endif
51
52/*
53 * dma_rmb()/dma_wmb() order DMA-visible memory. Xeneva's virtio rings are
54 * ordinary memory in the linear map (AuVirtioPCISetupQueue hands back
55 * pointers, not bus addresses needing an explicit sync), so these are the
56 * same fences -- the name is kept so a ported driver reads the way it does
57 * upstream.
58 */
59#ifndef dma_rmb
60#define dma_rmb() __atomic_thread_fence(__ATOMIC_ACQUIRE)
61#endif
62#ifndef dma_wmb
63#define dma_wmb() __atomic_thread_fence(__ATOMIC_RELEASE)
64#endif
65
66#endif /* __ASM_BARRIER_H__ */