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

Configure Feed

Select the types of activity you want to include in your feed.

at v5.5-rc7 261 lines 5.9 kB view raw
1/* SPDX-License-Identifier: GPL-2.0-or-later */ 2/* 3 * Generic barrier definitions. 4 * 5 * It should be possible to use these on really simple architectures, 6 * but it serves more as a starting point for new ports. 7 * 8 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 9 * Written by David Howells (dhowells@redhat.com) 10 */ 11#ifndef __ASM_GENERIC_BARRIER_H 12#define __ASM_GENERIC_BARRIER_H 13 14#ifndef __ASSEMBLY__ 15 16#include <linux/compiler.h> 17 18#ifndef nop 19#define nop() asm volatile ("nop") 20#endif 21 22/* 23 * Force strict CPU ordering. And yes, this is required on UP too when we're 24 * talking to devices. 25 * 26 * Fall back to compiler barriers if nothing better is provided. 27 */ 28 29#ifndef mb 30#define mb() barrier() 31#endif 32 33#ifndef rmb 34#define rmb() mb() 35#endif 36 37#ifndef wmb 38#define wmb() mb() 39#endif 40 41#ifndef dma_rmb 42#define dma_rmb() rmb() 43#endif 44 45#ifndef dma_wmb 46#define dma_wmb() wmb() 47#endif 48 49#ifndef read_barrier_depends 50#define read_barrier_depends() do { } while (0) 51#endif 52 53#ifndef __smp_mb 54#define __smp_mb() mb() 55#endif 56 57#ifndef __smp_rmb 58#define __smp_rmb() rmb() 59#endif 60 61#ifndef __smp_wmb 62#define __smp_wmb() wmb() 63#endif 64 65#ifndef __smp_read_barrier_depends 66#define __smp_read_barrier_depends() read_barrier_depends() 67#endif 68 69#ifdef CONFIG_SMP 70 71#ifndef smp_mb 72#define smp_mb() __smp_mb() 73#endif 74 75#ifndef smp_rmb 76#define smp_rmb() __smp_rmb() 77#endif 78 79#ifndef smp_wmb 80#define smp_wmb() __smp_wmb() 81#endif 82 83#ifndef smp_read_barrier_depends 84#define smp_read_barrier_depends() __smp_read_barrier_depends() 85#endif 86 87#else /* !CONFIG_SMP */ 88 89#ifndef smp_mb 90#define smp_mb() barrier() 91#endif 92 93#ifndef smp_rmb 94#define smp_rmb() barrier() 95#endif 96 97#ifndef smp_wmb 98#define smp_wmb() barrier() 99#endif 100 101#ifndef smp_read_barrier_depends 102#define smp_read_barrier_depends() do { } while (0) 103#endif 104 105#endif /* CONFIG_SMP */ 106 107#ifndef __smp_store_mb 108#define __smp_store_mb(var, value) do { WRITE_ONCE(var, value); __smp_mb(); } while (0) 109#endif 110 111#ifndef __smp_mb__before_atomic 112#define __smp_mb__before_atomic() __smp_mb() 113#endif 114 115#ifndef __smp_mb__after_atomic 116#define __smp_mb__after_atomic() __smp_mb() 117#endif 118 119#ifndef __smp_store_release 120#define __smp_store_release(p, v) \ 121do { \ 122 compiletime_assert_atomic_type(*p); \ 123 __smp_mb(); \ 124 WRITE_ONCE(*p, v); \ 125} while (0) 126#endif 127 128#ifndef __smp_load_acquire 129#define __smp_load_acquire(p) \ 130({ \ 131 typeof(*p) ___p1 = READ_ONCE(*p); \ 132 compiletime_assert_atomic_type(*p); \ 133 __smp_mb(); \ 134 ___p1; \ 135}) 136#endif 137 138#ifdef CONFIG_SMP 139 140#ifndef smp_store_mb 141#define smp_store_mb(var, value) __smp_store_mb(var, value) 142#endif 143 144#ifndef smp_mb__before_atomic 145#define smp_mb__before_atomic() __smp_mb__before_atomic() 146#endif 147 148#ifndef smp_mb__after_atomic 149#define smp_mb__after_atomic() __smp_mb__after_atomic() 150#endif 151 152#ifndef smp_store_release 153#define smp_store_release(p, v) __smp_store_release(p, v) 154#endif 155 156#ifndef smp_load_acquire 157#define smp_load_acquire(p) __smp_load_acquire(p) 158#endif 159 160#else /* !CONFIG_SMP */ 161 162#ifndef smp_store_mb 163#define smp_store_mb(var, value) do { WRITE_ONCE(var, value); barrier(); } while (0) 164#endif 165 166#ifndef smp_mb__before_atomic 167#define smp_mb__before_atomic() barrier() 168#endif 169 170#ifndef smp_mb__after_atomic 171#define smp_mb__after_atomic() barrier() 172#endif 173 174#ifndef smp_store_release 175#define smp_store_release(p, v) \ 176do { \ 177 compiletime_assert_atomic_type(*p); \ 178 barrier(); \ 179 WRITE_ONCE(*p, v); \ 180} while (0) 181#endif 182 183#ifndef smp_load_acquire 184#define smp_load_acquire(p) \ 185({ \ 186 typeof(*p) ___p1 = READ_ONCE(*p); \ 187 compiletime_assert_atomic_type(*p); \ 188 barrier(); \ 189 ___p1; \ 190}) 191#endif 192 193#endif /* CONFIG_SMP */ 194 195/* Barriers for virtual machine guests when talking to an SMP host */ 196#define virt_mb() __smp_mb() 197#define virt_rmb() __smp_rmb() 198#define virt_wmb() __smp_wmb() 199#define virt_read_barrier_depends() __smp_read_barrier_depends() 200#define virt_store_mb(var, value) __smp_store_mb(var, value) 201#define virt_mb__before_atomic() __smp_mb__before_atomic() 202#define virt_mb__after_atomic() __smp_mb__after_atomic() 203#define virt_store_release(p, v) __smp_store_release(p, v) 204#define virt_load_acquire(p) __smp_load_acquire(p) 205 206/** 207 * smp_acquire__after_ctrl_dep() - Provide ACQUIRE ordering after a control dependency 208 * 209 * A control dependency provides a LOAD->STORE order, the additional RMB 210 * provides LOAD->LOAD order, together they provide LOAD->{LOAD,STORE} order, 211 * aka. (load)-ACQUIRE. 212 * 213 * Architectures that do not do load speculation can have this be barrier(). 214 */ 215#ifndef smp_acquire__after_ctrl_dep 216#define smp_acquire__after_ctrl_dep() smp_rmb() 217#endif 218 219/** 220 * smp_cond_load_relaxed() - (Spin) wait for cond with no ordering guarantees 221 * @ptr: pointer to the variable to wait on 222 * @cond: boolean expression to wait for 223 * 224 * Equivalent to using READ_ONCE() on the condition variable. 225 * 226 * Due to C lacking lambda expressions we load the value of *ptr into a 227 * pre-named variable @VAL to be used in @cond. 228 */ 229#ifndef smp_cond_load_relaxed 230#define smp_cond_load_relaxed(ptr, cond_expr) ({ \ 231 typeof(ptr) __PTR = (ptr); \ 232 typeof(*ptr) VAL; \ 233 for (;;) { \ 234 VAL = READ_ONCE(*__PTR); \ 235 if (cond_expr) \ 236 break; \ 237 cpu_relax(); \ 238 } \ 239 VAL; \ 240}) 241#endif 242 243/** 244 * smp_cond_load_acquire() - (Spin) wait for cond with ACQUIRE ordering 245 * @ptr: pointer to the variable to wait on 246 * @cond: boolean expression to wait for 247 * 248 * Equivalent to using smp_load_acquire() on the condition variable but employs 249 * the control dependency of the wait to reduce the barrier on many platforms. 250 */ 251#ifndef smp_cond_load_acquire 252#define smp_cond_load_acquire(ptr, cond_expr) ({ \ 253 typeof(*ptr) _val; \ 254 _val = smp_cond_load_relaxed(ptr, cond_expr); \ 255 smp_acquire__after_ctrl_dep(); \ 256 _val; \ 257}) 258#endif 259 260#endif /* !__ASSEMBLY__ */ 261#endif /* __ASM_GENERIC_BARRIER_H */