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 do not 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_shared(lock); 19 void __lockfunc _raw_write_lock(rwlock_t *lock) __acquires(lock); 20 void __lockfunc _raw_write_lock_nested(rwlock_t *lock, int subclass) __acquires(lock); 21 void __lockfunc _raw_read_lock_bh(rwlock_t *lock) __acquires_shared(lock); 22 void __lockfunc _raw_write_lock_bh(rwlock_t *lock) __acquires(lock); 23 void __lockfunc _raw_read_lock_irq(rwlock_t *lock) __acquires_shared(lock); 24 void __lockfunc _raw_write_lock_irq(rwlock_t *lock) __acquires(lock); 25 unsigned long __lockfunc _raw_read_lock_irqsave(rwlock_t *lock) 26 __acquires(lock); 27 unsigned long __lockfunc _raw_write_lock_irqsave(rwlock_t *lock) 28 __acquires(lock); 29 int __lockfunc _raw_read_trylock(rwlock_t *lock) __cond_acquires_shared(true, lock); 30 int __lockfunc _raw_write_trylock(rwlock_t *lock) __cond_acquires(true, lock); 31 void __lockfunc _raw_read_unlock(rwlock_t *lock) __releases_shared(lock); 32 void __lockfunc _raw_write_unlock(rwlock_t *lock) __releases(lock); 33 void __lockfunc _raw_read_unlock_bh(rwlock_t *lock) __releases_shared(lock); 34 void __lockfunc _raw_write_unlock_bh(rwlock_t *lock) __releases(lock); 35 void __lockfunc _raw_read_unlock_irq(rwlock_t *lock) __releases_shared(lock); 36 void __lockfunc _raw_write_unlock_irq(rwlock_t *lock) __releases(lock); 37 void __lockfunc 38 _raw_read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) 39 __releases(lock); 40 void __lockfunc 41 _raw_write_unlock_irqrestore(rwlock_t *lock, unsigned long flags) 42 __releases(lock); 43 44 #ifdef CONFIG_INLINE_READ_LOCK 45 #define _raw_read_lock(lock) __raw_read_lock(lock) 46 #endif 47 48 #ifdef CONFIG_INLINE_WRITE_LOCK 49 #define _raw_write_lock(lock) __raw_write_lock(lock) 50 #endif 51 52 #ifdef CONFIG_INLINE_READ_LOCK_BH 53 #define _raw_read_lock_bh(lock) __raw_read_lock_bh(lock) 54 #endif 55 56 #ifdef CONFIG_INLINE_WRITE_LOCK_BH 57 #define _raw_write_lock_bh(lock) __raw_write_lock_bh(lock) 58 #endif 59 60 #ifdef CONFIG_INLINE_READ_LOCK_IRQ 61 #define _raw_read_lock_irq(lock) __raw_read_lock_irq(lock) 62 #endif 63 64 #ifdef CONFIG_INLINE_WRITE_LOCK_IRQ 65 #define _raw_write_lock_irq(lock) __raw_write_lock_irq(lock) 66 #endif 67 68 #ifdef CONFIG_INLINE_READ_LOCK_IRQSAVE 69 #define _raw_read_lock_irqsave(lock) __raw_read_lock_irqsave(lock) 70 #endif 71 72 #ifdef CONFIG_INLINE_WRITE_LOCK_IRQSAVE 73 #define _raw_write_lock_irqsave(lock) __raw_write_lock_irqsave(lock) 74 #endif 75 76 #ifdef CONFIG_INLINE_READ_TRYLOCK 77 #define _raw_read_trylock(lock) __raw_read_trylock(lock) 78 #endif 79 80 #ifdef CONFIG_INLINE_WRITE_TRYLOCK 81 #define _raw_write_trylock(lock) __raw_write_trylock(lock) 82 #endif 83 84 #ifdef CONFIG_INLINE_READ_UNLOCK 85 #define _raw_read_unlock(lock) __raw_read_unlock(lock) 86 #endif 87 88 #ifdef CONFIG_INLINE_WRITE_UNLOCK 89 #define _raw_write_unlock(lock) __raw_write_unlock(lock) 90 #endif 91 92 #ifdef CONFIG_INLINE_READ_UNLOCK_BH 93 #define _raw_read_unlock_bh(lock) __raw_read_unlock_bh(lock) 94 #endif 95 96 #ifdef CONFIG_INLINE_WRITE_UNLOCK_BH 97 #define _raw_write_unlock_bh(lock) __raw_write_unlock_bh(lock) 98 #endif 99 100 #ifdef CONFIG_INLINE_READ_UNLOCK_IRQ 101 #define _raw_read_unlock_irq(lock) __raw_read_unlock_irq(lock) 102 #endif 103 104 #ifdef CONFIG_INLINE_WRITE_UNLOCK_IRQ 105 #define _raw_write_unlock_irq(lock) __raw_write_unlock_irq(lock) 106 #endif 107 108 #ifdef CONFIG_INLINE_READ_UNLOCK_IRQRESTORE 109 #define _raw_read_unlock_irqrestore(lock, flags) \ 110 __raw_read_unlock_irqrestore(lock, flags) 111 #endif 112 113 #ifdef CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE 114 #define _raw_write_unlock_irqrestore(lock, flags) \ 115 __raw_write_unlock_irqrestore(lock, flags) 116 #endif 117 118 static inline int __raw_read_trylock(rwlock_t *lock) 119 { 120 preempt_disable(); 121 if (do_raw_read_trylock(lock)) { 122 rwlock_acquire_read(&lock->dep_map, 0, 1, _RET_IP_); 123 return 1; 124 } 125 preempt_enable(); 126 return 0; 127 } 128 129 static inline int __raw_write_trylock(rwlock_t *lock) 130 { 131 preempt_disable(); 132 if (do_raw_write_trylock(lock)) { 133 rwlock_acquire(&lock->dep_map, 0, 1, _RET_IP_); 134 return 1; 135 } 136 preempt_enable(); 137 return 0; 138 } 139 140 static inline bool _raw_write_trylock_irqsave(rwlock_t *lock, unsigned long *flags) 141 __cond_acquires(true, lock) __no_context_analysis 142 { 143 local_irq_save(*flags); 144 if (_raw_write_trylock(lock)) 145 return true; 146 local_irq_restore(*flags); 147 return false; 148 } 149 150 /* 151 * If lockdep is enabled then we use the non-preemption spin-ops 152 * even on CONFIG_PREEMPT, because lockdep assumes that interrupts are 153 * not re-enabled during lock-acquire (which the preempt-spin-ops do): 154 */ 155 #if !defined(CONFIG_GENERIC_LOCKBREAK) || defined(CONFIG_DEBUG_LOCK_ALLOC) 156 157 static inline void __raw_read_lock(rwlock_t *lock) 158 __acquires_shared(lock) __no_context_analysis 159 { 160 preempt_disable(); 161 rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); 162 LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock); 163 } 164 165 static inline unsigned long __raw_read_lock_irqsave(rwlock_t *lock) 166 __acquires_shared(lock) __no_context_analysis 167 { 168 unsigned long flags; 169 170 local_irq_save(flags); 171 preempt_disable(); 172 rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); 173 LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock); 174 return flags; 175 } 176 177 static inline void __raw_read_lock_irq(rwlock_t *lock) 178 __acquires_shared(lock) __no_context_analysis 179 { 180 local_irq_disable(); 181 preempt_disable(); 182 rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); 183 LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock); 184 } 185 186 static inline void __raw_read_lock_bh(rwlock_t *lock) 187 __acquires_shared(lock) __no_context_analysis 188 { 189 __local_bh_disable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); 190 rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); 191 LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock); 192 } 193 194 static inline unsigned long __raw_write_lock_irqsave(rwlock_t *lock) 195 __acquires(lock) __no_context_analysis 196 { 197 unsigned long flags; 198 199 local_irq_save(flags); 200 preempt_disable(); 201 rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); 202 LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock); 203 return flags; 204 } 205 206 static inline void __raw_write_lock_irq(rwlock_t *lock) 207 __acquires(lock) __no_context_analysis 208 { 209 local_irq_disable(); 210 preempt_disable(); 211 rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); 212 LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock); 213 } 214 215 static inline void __raw_write_lock_bh(rwlock_t *lock) 216 __acquires(lock) __no_context_analysis 217 { 218 __local_bh_disable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); 219 rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); 220 LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock); 221 } 222 223 static inline void __raw_write_lock(rwlock_t *lock) 224 __acquires(lock) __no_context_analysis 225 { 226 preempt_disable(); 227 rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); 228 LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock); 229 } 230 231 static inline void __raw_write_lock_nested(rwlock_t *lock, int subclass) 232 __acquires(lock) __no_context_analysis 233 { 234 preempt_disable(); 235 rwlock_acquire(&lock->dep_map, subclass, 0, _RET_IP_); 236 LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock); 237 } 238 239 #endif /* !CONFIG_GENERIC_LOCKBREAK || CONFIG_DEBUG_LOCK_ALLOC */ 240 241 static inline void __raw_write_unlock(rwlock_t *lock) 242 __releases(lock) 243 { 244 rwlock_release(&lock->dep_map, _RET_IP_); 245 do_raw_write_unlock(lock); 246 preempt_enable(); 247 } 248 249 static inline void __raw_read_unlock(rwlock_t *lock) 250 __releases_shared(lock) 251 { 252 rwlock_release(&lock->dep_map, _RET_IP_); 253 do_raw_read_unlock(lock); 254 preempt_enable(); 255 } 256 257 static inline void 258 __raw_read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) 259 __releases_shared(lock) 260 { 261 rwlock_release(&lock->dep_map, _RET_IP_); 262 do_raw_read_unlock(lock); 263 local_irq_restore(flags); 264 preempt_enable(); 265 } 266 267 static inline void __raw_read_unlock_irq(rwlock_t *lock) 268 __releases_shared(lock) 269 { 270 rwlock_release(&lock->dep_map, _RET_IP_); 271 do_raw_read_unlock(lock); 272 local_irq_enable(); 273 preempt_enable(); 274 } 275 276 static inline void __raw_read_unlock_bh(rwlock_t *lock) 277 __releases_shared(lock) 278 { 279 rwlock_release(&lock->dep_map, _RET_IP_); 280 do_raw_read_unlock(lock); 281 __local_bh_enable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); 282 } 283 284 static inline void __raw_write_unlock_irqrestore(rwlock_t *lock, 285 unsigned long flags) 286 __releases(lock) 287 { 288 rwlock_release(&lock->dep_map, _RET_IP_); 289 do_raw_write_unlock(lock); 290 local_irq_restore(flags); 291 preempt_enable(); 292 } 293 294 static inline void __raw_write_unlock_irq(rwlock_t *lock) 295 __releases(lock) 296 { 297 rwlock_release(&lock->dep_map, _RET_IP_); 298 do_raw_write_unlock(lock); 299 local_irq_enable(); 300 preempt_enable(); 301 } 302 303 static inline void __raw_write_unlock_bh(rwlock_t *lock) 304 __releases(lock) 305 { 306 rwlock_release(&lock->dep_map, _RET_IP_); 307 do_raw_write_unlock(lock); 308 __local_bh_enable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); 309 } 310 311 #endif /* __LINUX_RWLOCK_API_SMP_H */ 312