Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0 2 : /* 3 : * Copyright (2004) Linus Torvalds 4 : * 5 : * Author: Zwane Mwaikambo <zwane@fsmlabs.com> 6 : * 7 : * Copyright (2004, 2005) Ingo Molnar 8 : * 9 : * This file contains the spinlock/rwlock implementations for the 10 : * SMP and the DEBUG_SPINLOCK cases. (UP-nondebug inlines them) 11 : * 12 : * Note that some architectures have special knowledge about the 13 : * stack frames of these functions in their profile_pc. If you 14 : * change anything significant here that could change the stack 15 : * frame contact the architecture maintainers. 16 : */ 17 : 18 : #include <linux/linkage.h> 19 : #include <linux/preempt.h> 20 : #include <linux/spinlock.h> 21 : #include <linux/interrupt.h> 22 : #include <linux/debug_locks.h> 23 : #include <linux/export.h> 24 : 25 : #ifdef CONFIG_MMIOWB 26 : #ifndef arch_mmiowb_state 27 : DEFINE_PER_CPU(struct mmiowb_state, __mmiowb_state); 28 : EXPORT_PER_CPU_SYMBOL(__mmiowb_state); 29 : #endif 30 : #endif 31 : 32 : /* 33 : * If lockdep is enabled then we use the non-preemption spin-ops 34 : * even on CONFIG_PREEMPT, because lockdep assumes that interrupts are 35 : * not re-enabled during lock-acquire (which the preempt-spin-ops do): 36 : */ 37 : #if !defined(CONFIG_GENERIC_LOCKBREAK) || defined(CONFIG_DEBUG_LOCK_ALLOC) 38 : /* 39 : * The __lock_function inlines are taken from 40 : * spinlock : include/linux/spinlock_api_smp.h 41 : * rwlock : include/linux/rwlock_api_smp.h 42 : */ 43 : #else 44 : 45 : /* 46 : * Some architectures can relax in favour of the CPU owning the lock. 47 : */ 48 : #ifndef arch_read_relax 49 : # define arch_read_relax(l) cpu_relax() 50 : #endif 51 : #ifndef arch_write_relax 52 : # define arch_write_relax(l) cpu_relax() 53 : #endif 54 : #ifndef arch_spin_relax 55 : # define arch_spin_relax(l) cpu_relax() 56 : #endif 57 : 58 : /* 59 : * We build the __lock_function inlines here. They are too large for 60 : * inlining all over the place, but here is only one user per function 61 : * which embedds them into the calling _lock_function below. 62 : * 63 : * This could be a long-held lock. We both prepare to spin for a long 64 : * time (making _this_ CPU preemptable if possible), and we also signal 65 : * towards that other CPU that it should break the lock ASAP. 66 : */ 67 : #define BUILD_LOCK_OPS(op, locktype) \ 68 : void __lockfunc __raw_##op##_lock(locktype##_t *lock) \ 69 : { \ 70 : for (;;) { \ 71 : preempt_disable(); \ 72 : if (likely(do_raw_##op##_trylock(lock))) \ 73 : break; \ 74 : preempt_enable(); \ 75 : \ 76 : arch_##op##_relax(&lock->raw_lock); \ 77 : } \ 78 : } \ 79 : \ 80 : unsigned long __lockfunc __raw_##op##_lock_irqsave(locktype##_t *lock) \ 81 : { \ 82 : unsigned long flags; \ 83 : \ 84 : for (;;) { \ 85 : preempt_disable(); \ 86 : local_irq_save(flags); \ 87 : if (likely(do_raw_##op##_trylock(lock))) \ 88 : break; \ 89 : local_irq_restore(flags); \ 90 : preempt_enable(); \ 91 : \ 92 : arch_##op##_relax(&lock->raw_lock); \ 93 : } \ 94 : \ 95 : return flags; \ 96 : } \ 97 : \ 98 : void __lockfunc __raw_##op##_lock_irq(locktype##_t *lock) \ 99 : { \ 100 : _raw_##op##_lock_irqsave(lock); \ 101 : } \ 102 : \ 103 : void __lockfunc __raw_##op##_lock_bh(locktype##_t *lock) \ 104 : { \ 105 : unsigned long flags; \ 106 : \ 107 : /* */ \ 108 : /* Careful: we must exclude softirqs too, hence the */ \ 109 : /* irq-disabling. We use the generic preemption-aware */ \ 110 : /* function: */ \ 111 : /**/ \ 112 : flags = _raw_##op##_lock_irqsave(lock); \ 113 : local_bh_disable(); \ 114 : local_irq_restore(flags); \ 115 : } \ 116 : 117 : /* 118 : * Build preemption-friendly versions of the following 119 : * lock-spinning functions: 120 : * 121 : * __[spin|read|write]_lock() 122 : * __[spin|read|write]_lock_irq() 123 : * __[spin|read|write]_lock_irqsave() 124 : * __[spin|read|write]_lock_bh() 125 : */ 126 : BUILD_LOCK_OPS(spin, raw_spinlock); 127 : BUILD_LOCK_OPS(read, rwlock); 128 : BUILD_LOCK_OPS(write, rwlock); 129 : 130 : #endif 131 : 132 : #ifndef CONFIG_INLINE_SPIN_TRYLOCK 133 26610 : int __lockfunc _raw_spin_trylock(raw_spinlock_t *lock) 134 : { 135 26610 : return __raw_spin_trylock(lock); 136 : } 137 : EXPORT_SYMBOL(_raw_spin_trylock); 138 : #endif 139 : 140 : #ifndef CONFIG_INLINE_SPIN_TRYLOCK_BH 141 0 : int __lockfunc _raw_spin_trylock_bh(raw_spinlock_t *lock) 142 : { 143 0 : return __raw_spin_trylock_bh(lock); 144 : } 145 : EXPORT_SYMBOL(_raw_spin_trylock_bh); 146 : #endif 147 : 148 : #ifndef CONFIG_INLINE_SPIN_LOCK 149 1565977 : void __lockfunc _raw_spin_lock(raw_spinlock_t *lock) 150 : { 151 1565977 : __raw_spin_lock(lock); 152 1568539 : } 153 : EXPORT_SYMBOL(_raw_spin_lock); 154 : #endif 155 : 156 : #ifndef CONFIG_INLINE_SPIN_LOCK_IRQSAVE 157 7244413 : unsigned long __lockfunc _raw_spin_lock_irqsave(raw_spinlock_t *lock) 158 : { 159 7244413 : return __raw_spin_lock_irqsave(lock); 160 : } 161 : EXPORT_SYMBOL(_raw_spin_lock_irqsave); 162 : #endif 163 : 164 : #ifndef CONFIG_INLINE_SPIN_LOCK_IRQ 165 141197 : void __lockfunc _raw_spin_lock_irq(raw_spinlock_t *lock) 166 : { 167 141197 : __raw_spin_lock_irq(lock); 168 141224 : } 169 : EXPORT_SYMBOL(_raw_spin_lock_irq); 170 : #endif 171 : 172 : #ifndef CONFIG_INLINE_SPIN_LOCK_BH 173 2497 : void __lockfunc _raw_spin_lock_bh(raw_spinlock_t *lock) 174 : { 175 2497 : __raw_spin_lock_bh(lock); 176 2497 : } 177 : EXPORT_SYMBOL(_raw_spin_lock_bh); 178 : #endif 179 : 180 : #ifdef CONFIG_UNINLINE_SPIN_UNLOCK 181 1615001 : void __lockfunc _raw_spin_unlock(raw_spinlock_t *lock) 182 : { 183 1615001 : __raw_spin_unlock(lock); 184 1616869 : } 185 : EXPORT_SYMBOL(_raw_spin_unlock); 186 : #endif 187 : 188 : #ifndef CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE 189 7246339 : void __lockfunc _raw_spin_unlock_irqrestore(raw_spinlock_t *lock, unsigned long flags) 190 : { 191 7246339 : __raw_spin_unlock_irqrestore(lock, flags); 192 7241722 : } 193 : EXPORT_SYMBOL(_raw_spin_unlock_irqrestore); 194 : #endif 195 : 196 : #ifndef CONFIG_INLINE_SPIN_UNLOCK_IRQ 197 171784 : void __lockfunc _raw_spin_unlock_irq(raw_spinlock_t *lock) 198 : { 199 171784 : __raw_spin_unlock_irq(lock); 200 171771 : } 201 : EXPORT_SYMBOL(_raw_spin_unlock_irq); 202 : #endif 203 : 204 : #ifndef CONFIG_INLINE_SPIN_UNLOCK_BH 205 1416 : void __lockfunc _raw_spin_unlock_bh(raw_spinlock_t *lock) 206 : { 207 1416 : __raw_spin_unlock_bh(lock); 208 1416 : } 209 : EXPORT_SYMBOL(_raw_spin_unlock_bh); 210 : #endif 211 : 212 : #ifndef CONFIG_INLINE_READ_TRYLOCK 213 0 : int __lockfunc _raw_read_trylock(rwlock_t *lock) 214 : { 215 0 : return __raw_read_trylock(lock); 216 : } 217 : EXPORT_SYMBOL(_raw_read_trylock); 218 : #endif 219 : 220 : #ifndef CONFIG_INLINE_READ_LOCK 221 36691 : void __lockfunc _raw_read_lock(rwlock_t *lock) 222 : { 223 36691 : __raw_read_lock(lock); 224 36691 : } 225 : EXPORT_SYMBOL(_raw_read_lock); 226 : #endif 227 : 228 : #ifndef CONFIG_INLINE_READ_LOCK_IRQSAVE 229 5028 : unsigned long __lockfunc _raw_read_lock_irqsave(rwlock_t *lock) 230 : { 231 5028 : return __raw_read_lock_irqsave(lock); 232 : } 233 : EXPORT_SYMBOL(_raw_read_lock_irqsave); 234 : #endif 235 : 236 : #ifndef CONFIG_INLINE_READ_LOCK_IRQ 237 0 : void __lockfunc _raw_read_lock_irq(rwlock_t *lock) 238 : { 239 0 : __raw_read_lock_irq(lock); 240 0 : } 241 : EXPORT_SYMBOL(_raw_read_lock_irq); 242 : #endif 243 : 244 : #ifndef CONFIG_INLINE_READ_LOCK_BH 245 41 : void __lockfunc _raw_read_lock_bh(rwlock_t *lock) 246 : { 247 41 : __raw_read_lock_bh(lock); 248 41 : } 249 : EXPORT_SYMBOL(_raw_read_lock_bh); 250 : #endif 251 : 252 : #ifndef CONFIG_INLINE_READ_UNLOCK 253 36691 : void __lockfunc _raw_read_unlock(rwlock_t *lock) 254 : { 255 36691 : __raw_read_unlock(lock); 256 36691 : } 257 : EXPORT_SYMBOL(_raw_read_unlock); 258 : #endif 259 : 260 : #ifndef CONFIG_INLINE_READ_UNLOCK_IRQRESTORE 261 5029 : void __lockfunc _raw_read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) 262 : { 263 5029 : __raw_read_unlock_irqrestore(lock, flags); 264 5028 : } 265 : EXPORT_SYMBOL(_raw_read_unlock_irqrestore); 266 : #endif 267 : 268 : #ifndef CONFIG_INLINE_READ_UNLOCK_IRQ 269 0 : void __lockfunc _raw_read_unlock_irq(rwlock_t *lock) 270 : { 271 0 : __raw_read_unlock_irq(lock); 272 0 : } 273 : EXPORT_SYMBOL(_raw_read_unlock_irq); 274 : #endif 275 : 276 : #ifndef CONFIG_INLINE_READ_UNLOCK_BH 277 41 : void __lockfunc _raw_read_unlock_bh(rwlock_t *lock) 278 : { 279 41 : __raw_read_unlock_bh(lock); 280 41 : } 281 : EXPORT_SYMBOL(_raw_read_unlock_bh); 282 : #endif 283 : 284 : #ifndef CONFIG_INLINE_WRITE_TRYLOCK 285 0 : int __lockfunc _raw_write_trylock(rwlock_t *lock) 286 : { 287 0 : return __raw_write_trylock(lock); 288 : } 289 : EXPORT_SYMBOL(_raw_write_trylock); 290 : #endif 291 : 292 : #ifndef CONFIG_INLINE_WRITE_LOCK 293 7479 : void __lockfunc _raw_write_lock(rwlock_t *lock) 294 : { 295 7479 : __raw_write_lock(lock); 296 7479 : } 297 : EXPORT_SYMBOL(_raw_write_lock); 298 : #endif 299 : 300 : #ifndef CONFIG_INLINE_WRITE_LOCK_IRQSAVE 301 0 : unsigned long __lockfunc _raw_write_lock_irqsave(rwlock_t *lock) 302 : { 303 0 : return __raw_write_lock_irqsave(lock); 304 : } 305 : EXPORT_SYMBOL(_raw_write_lock_irqsave); 306 : #endif 307 : 308 : #ifndef CONFIG_INLINE_WRITE_LOCK_IRQ 309 14258 : void __lockfunc _raw_write_lock_irq(rwlock_t *lock) 310 : { 311 14258 : __raw_write_lock_irq(lock); 312 14261 : } 313 : EXPORT_SYMBOL(_raw_write_lock_irq); 314 : #endif 315 : 316 : #ifndef CONFIG_INLINE_WRITE_LOCK_BH 317 827 : void __lockfunc _raw_write_lock_bh(rwlock_t *lock) 318 : { 319 827 : __raw_write_lock_bh(lock); 320 827 : } 321 : EXPORT_SYMBOL(_raw_write_lock_bh); 322 : #endif 323 : 324 : #ifndef CONFIG_INLINE_WRITE_UNLOCK 325 7481 : void __lockfunc _raw_write_unlock(rwlock_t *lock) 326 : { 327 7481 : __raw_write_unlock(lock); 328 7481 : } 329 : EXPORT_SYMBOL(_raw_write_unlock); 330 : #endif 331 : 332 : #ifndef CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE 333 0 : void __lockfunc _raw_write_unlock_irqrestore(rwlock_t *lock, unsigned long flags) 334 : { 335 0 : __raw_write_unlock_irqrestore(lock, flags); 336 0 : } 337 : EXPORT_SYMBOL(_raw_write_unlock_irqrestore); 338 : #endif 339 : 340 : #ifndef CONFIG_INLINE_WRITE_UNLOCK_IRQ 341 14259 : void __lockfunc _raw_write_unlock_irq(rwlock_t *lock) 342 : { 343 14259 : __raw_write_unlock_irq(lock); 344 14260 : } 345 : EXPORT_SYMBOL(_raw_write_unlock_irq); 346 : #endif 347 : 348 : #ifndef CONFIG_INLINE_WRITE_UNLOCK_BH 349 825 : void __lockfunc _raw_write_unlock_bh(rwlock_t *lock) 350 : { 351 825 : __raw_write_unlock_bh(lock); 352 825 : } 353 : EXPORT_SYMBOL(_raw_write_unlock_bh); 354 : #endif 355 : 356 : #ifdef CONFIG_DEBUG_LOCK_ALLOC 357 : 358 31113 : void __lockfunc _raw_spin_lock_nested(raw_spinlock_t *lock, int subclass) 359 : { 360 31113 : preempt_disable(); 361 31113 : spin_acquire(&lock->dep_map, subclass, 0, _RET_IP_); 362 31113 : LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); 363 31113 : } 364 : EXPORT_SYMBOL(_raw_spin_lock_nested); 365 : 366 193 : unsigned long __lockfunc _raw_spin_lock_irqsave_nested(raw_spinlock_t *lock, 367 : int subclass) 368 : { 369 193 : unsigned long flags; 370 : 371 386 : local_irq_save(flags); 372 193 : preempt_disable(); 373 193 : spin_acquire(&lock->dep_map, subclass, 0, _RET_IP_); 374 193 : LOCK_CONTENDED_FLAGS(lock, do_raw_spin_trylock, do_raw_spin_lock, 375 : do_raw_spin_lock_flags, &flags); 376 193 : return flags; 377 : } 378 : EXPORT_SYMBOL(_raw_spin_lock_irqsave_nested); 379 : 380 0 : void __lockfunc _raw_spin_lock_nest_lock(raw_spinlock_t *lock, 381 : struct lockdep_map *nest_lock) 382 : { 383 0 : preempt_disable(); 384 0 : spin_acquire_nest(&lock->dep_map, 0, 0, nest_lock, _RET_IP_); 385 0 : LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); 386 0 : } 387 : EXPORT_SYMBOL(_raw_spin_lock_nest_lock); 388 : 389 : #endif 390 : 391 117 : notrace int in_lock_functions(unsigned long addr) 392 : { 393 : /* Linker adds these: start and end of __lockfunc functions */ 394 117 : extern char __lock_text_start[], __lock_text_end[]; 395 : 396 117 : return addr >= (unsigned long)__lock_text_start 397 117 : && addr < (unsigned long)__lock_text_end; 398 : } 399 : EXPORT_SYMBOL(in_lock_functions);