Branch data Line data Source code
1 : : #ifndef __LINUX_RWLOCK_API_SMP_H 2 : : #define __LINUX_RWLOCK_API_SMP_H 3 : : 4 : : #ifndef __LINUX_SPINLOCK_API_SMP_H 5 : : # error "please don't include this file directly" 6 : : #endif 7 : : 8 : : /* 9 : : * include/linux/rwlock_api_smp.h 10 : : * 11 : : * spinlock API declarations on SMP (and debug) 12 : : * (implemented in kernel/spinlock.c) 13 : : * 14 : : * portions Copyright 2005, Red Hat, Inc., Ingo Molnar 15 : : * Released under the General Public License (GPL). 16 : : */ 17 : : 18 : : void __lockfunc _raw_read_lock(rwlock_t *lock) __acquires(lock); 19 : : void __lockfunc _raw_write_lock(rwlock_t *lock) __acquires(lock); 20 : : void __lockfunc _raw_read_lock_bh(rwlock_t *lock) __acquires(lock); 21 : : void __lockfunc _raw_write_lock_bh(rwlock_t *lock) __acquires(lock); 22 : : void __lockfunc _raw_read_lock_irq(rwlock_t *lock) __acquires(lock); 23 : : void __lockfunc _raw_write_lock_irq(rwlock_t *lock) __acquires(lock); 24 : : unsigned long __lockfunc _raw_read_lock_irqsave(rwlock_t *lock) 25 : : __acquires(lock); 26 : : unsigned long __lockfunc _raw_write_lock_irqsave(rwlock_t *lock) 27 : : __acquires(lock); 28 : : int __lockfunc _raw_read_trylock(rwlock_t *lock); 29 : : int __lockfunc _raw_write_trylock(rwlock_t *lock); 30 : : void __lockfunc _raw_read_unlock(rwlock_t *lock) __releases(lock); 31 : : void __lockfunc _raw_write_unlock(rwlock_t *lock) __releases(lock); 32 : : void __lockfunc _raw_read_unlock_bh(rwlock_t *lock) __releases(lock); 33 : : void __lockfunc _raw_write_unlock_bh(rwlock_t *lock) __releases(lock); 34 : : void __lockfunc _raw_read_unlock_irq(rwlock_t *lock) __releases(lock); 35 : : void __lockfunc _raw_write_unlock_irq(rwlock_t *lock) __releases(lock); 36 : : void __lockfunc 37 : : _raw_read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) 38 : : __releases(lock); 39 : : void __lockfunc 40 : : _raw_write_unlock_irqrestore(rwlock_t *lock, unsigned long flags) 41 : : __releases(lock); 42 : : 43 : : #ifdef CONFIG_INLINE_READ_LOCK 44 : : #define _raw_read_lock(lock) __raw_read_lock(lock) 45 : : #endif 46 : : 47 : : #ifdef CONFIG_INLINE_WRITE_LOCK 48 : : #define _raw_write_lock(lock) __raw_write_lock(lock) 49 : : #endif 50 : : 51 : : #ifdef CONFIG_INLINE_READ_LOCK_BH 52 : : #define _raw_read_lock_bh(lock) __raw_read_lock_bh(lock) 53 : : #endif 54 : : 55 : : #ifdef CONFIG_INLINE_WRITE_LOCK_BH 56 : : #define _raw_write_lock_bh(lock) __raw_write_lock_bh(lock) 57 : : #endif 58 : : 59 : : #ifdef CONFIG_INLINE_READ_LOCK_IRQ 60 : : #define _raw_read_lock_irq(lock) __raw_read_lock_irq(lock) 61 : : #endif 62 : : 63 : : #ifdef CONFIG_INLINE_WRITE_LOCK_IRQ 64 : : #define _raw_write_lock_irq(lock) __raw_write_lock_irq(lock) 65 : : #endif 66 : : 67 : : #ifdef CONFIG_INLINE_READ_LOCK_IRQSAVE 68 : : #define _raw_read_lock_irqsave(lock) __raw_read_lock_irqsave(lock) 69 : : #endif 70 : : 71 : : #ifdef CONFIG_INLINE_WRITE_LOCK_IRQSAVE 72 : : #define _raw_write_lock_irqsave(lock) __raw_write_lock_irqsave(lock) 73 : : #endif 74 : : 75 : : #ifdef CONFIG_INLINE_READ_TRYLOCK 76 : : #define _raw_read_trylock(lock) __raw_read_trylock(lock) 77 : : #endif 78 : : 79 : : #ifdef CONFIG_INLINE_WRITE_TRYLOCK 80 : : #define _raw_write_trylock(lock) __raw_write_trylock(lock) 81 : : #endif 82 : : 83 : : #ifdef CONFIG_INLINE_READ_UNLOCK 84 : : #define _raw_read_unlock(lock) __raw_read_unlock(lock) 85 : : #endif 86 : : 87 : : #ifdef CONFIG_INLINE_WRITE_UNLOCK 88 : : #define _raw_write_unlock(lock) __raw_write_unlock(lock) 89 : : #endif 90 : : 91 : : #ifdef CONFIG_INLINE_READ_UNLOCK_BH 92 : : #define _raw_read_unlock_bh(lock) __raw_read_unlock_bh(lock) 93 : : #endif 94 : : 95 : : #ifdef CONFIG_INLINE_WRITE_UNLOCK_BH 96 : : #define _raw_write_unlock_bh(lock) __raw_write_unlock_bh(lock) 97 : : #endif 98 : : 99 : : #ifdef CONFIG_INLINE_READ_UNLOCK_IRQ 100 : : #define _raw_read_unlock_irq(lock) __raw_read_unlock_irq(lock) 101 : : #endif 102 : : 103 : : #ifdef CONFIG_INLINE_WRITE_UNLOCK_IRQ 104 : : #define _raw_write_unlock_irq(lock) __raw_write_unlock_irq(lock) 105 : : #endif 106 : : 107 : : #ifdef CONFIG_INLINE_READ_UNLOCK_IRQRESTORE 108 : : #define _raw_read_unlock_irqrestore(lock, flags) \ 109 : : __raw_read_unlock_irqrestore(lock, flags) 110 : : #endif 111 : : 112 : : #ifdef CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE 113 : : #define _raw_write_unlock_irqrestore(lock, flags) \ 114 : : __raw_write_unlock_irqrestore(lock, flags) 115 : : #endif 116 : : 117 : : static inline int __raw_read_trylock(rwlock_t *lock) 118 : : { 119 : 0 : preempt_disable(); 120 : 0 : if (do_raw_read_trylock(lock)) { 121 : : rwlock_acquire_read(&lock->dep_map, 0, 1, _RET_IP_); 122 : : return 1; 123 : : } 124 : 0 : preempt_enable(); 125 : : return 0; 126 : : } 127 : : 128 : : static inline int __raw_write_trylock(rwlock_t *lock) 129 : : { 130 : 0 : preempt_disable(); 131 : 0 : if (do_raw_write_trylock(lock)) { 132 : : rwlock_acquire(&lock->dep_map, 0, 1, _RET_IP_); 133 : : return 1; 134 : : } 135 : 0 : preempt_enable(); 136 : : return 0; 137 : : } 138 : : 139 : : /* 140 : : * If lockdep is enabled then we use the non-preemption spin-ops 141 : : * even on CONFIG_PREEMPT, because lockdep assumes that interrupts are 142 : : * not re-enabled during lock-acquire (which the preempt-spin-ops do): 143 : : */ 144 : : #if !defined(CONFIG_GENERIC_LOCKBREAK) || defined(CONFIG_DEBUG_LOCK_ALLOC) 145 : : 146 : : static inline void __raw_read_lock(rwlock_t *lock) 147 : : { 148 : 3 : preempt_disable(); 149 : : rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); 150 : 3 : LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock); 151 : : } 152 : : 153 : : static inline unsigned long __raw_read_lock_irqsave(rwlock_t *lock) 154 : : { 155 : : unsigned long flags; 156 : : 157 : 3 : local_irq_save(flags); 158 : 3 : preempt_disable(); 159 : : rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); 160 : 3 : LOCK_CONTENDED_FLAGS(lock, do_raw_read_trylock, do_raw_read_lock, 161 : : do_raw_read_lock_flags, &flags); 162 : : return flags; 163 : : } 164 : : 165 : : static inline void __raw_read_lock_irq(rwlock_t *lock) 166 : : { 167 : 0 : local_irq_disable(); 168 : 0 : preempt_disable(); 169 : : rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); 170 : 0 : LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock); 171 : : } 172 : : 173 : : static inline void __raw_read_lock_bh(rwlock_t *lock) 174 : : { 175 : 3 : __local_bh_disable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); 176 : : rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); 177 : 3 : LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock); 178 : : } 179 : : 180 : : static inline unsigned long __raw_write_lock_irqsave(rwlock_t *lock) 181 : : { 182 : : unsigned long flags; 183 : : 184 : 3 : local_irq_save(flags); 185 : 3 : preempt_disable(); 186 : : rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); 187 : 3 : LOCK_CONTENDED_FLAGS(lock, do_raw_write_trylock, do_raw_write_lock, 188 : : do_raw_write_lock_flags, &flags); 189 : : return flags; 190 : : } 191 : : 192 : : static inline void __raw_write_lock_irq(rwlock_t *lock) 193 : : { 194 : 3 : local_irq_disable(); 195 : 3 : preempt_disable(); 196 : : rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); 197 : 3 : LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock); 198 : : } 199 : : 200 : : static inline void __raw_write_lock_bh(rwlock_t *lock) 201 : : { 202 : 3 : __local_bh_disable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); 203 : : rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); 204 : 3 : LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock); 205 : : } 206 : : 207 : : static inline void __raw_write_lock(rwlock_t *lock) 208 : : { 209 : 3 : preempt_disable(); 210 : : rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); 211 : 3 : LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock); 212 : : } 213 : : 214 : : #endif /* !CONFIG_GENERIC_LOCKBREAK || CONFIG_DEBUG_LOCK_ALLOC */ 215 : : 216 : : static inline void __raw_write_unlock(rwlock_t *lock) 217 : : { 218 : : rwlock_release(&lock->dep_map, 1, _RET_IP_); 219 : : do_raw_write_unlock(lock); 220 : 3 : preempt_enable(); 221 : : } 222 : : 223 : : static inline void __raw_read_unlock(rwlock_t *lock) 224 : : { 225 : : rwlock_release(&lock->dep_map, 1, _RET_IP_); 226 : 3 : do_raw_read_unlock(lock); 227 : 3 : preempt_enable(); 228 : : } 229 : : 230 : : static inline void 231 : 3 : __raw_read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) 232 : : { 233 : : rwlock_release(&lock->dep_map, 1, _RET_IP_); 234 : 3 : do_raw_read_unlock(lock); 235 : 3 : local_irq_restore(flags); 236 : 3 : preempt_enable(); 237 : 3 : } 238 : : 239 : : static inline void __raw_read_unlock_irq(rwlock_t *lock) 240 : : { 241 : : rwlock_release(&lock->dep_map, 1, _RET_IP_); 242 : : do_raw_read_unlock(lock); 243 : : local_irq_enable(); 244 : : preempt_enable(); 245 : : } 246 : : 247 : : static inline void __raw_read_unlock_bh(rwlock_t *lock) 248 : : { 249 : : rwlock_release(&lock->dep_map, 1, _RET_IP_); 250 : 3 : do_raw_read_unlock(lock); 251 : 3 : __local_bh_enable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); 252 : : } 253 : : 254 : 3 : static inline void __raw_write_unlock_irqrestore(rwlock_t *lock, 255 : : unsigned long flags) 256 : : { 257 : : rwlock_release(&lock->dep_map, 1, _RET_IP_); 258 : : do_raw_write_unlock(lock); 259 : 3 : local_irq_restore(flags); 260 : 3 : preempt_enable(); 261 : 3 : } 262 : : 263 : 3 : static inline void __raw_write_unlock_irq(rwlock_t *lock) 264 : : { 265 : : rwlock_release(&lock->dep_map, 1, _RET_IP_); 266 : : do_raw_write_unlock(lock); 267 : 3 : local_irq_enable(); 268 : 3 : preempt_enable(); 269 : 3 : } 270 : : 271 : 3 : static inline void __raw_write_unlock_bh(rwlock_t *lock) 272 : : { 273 : : rwlock_release(&lock->dep_map, 1, _RET_IP_); 274 : : do_raw_write_unlock(lock); 275 : 3 : __local_bh_enable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); 276 : 3 : } 277 : : 278 : : #endif /* __LINUX_RWLOCK_API_SMP_H */