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 preempt_disable(); 120 if (do_raw_read_trylock(lock)) { 121 rwlock_acquire_read(&lock->dep_map, 0, 1, _RET_IP_); 122 return 1; 123 } 124 preempt_enable(); 125 return 0; 126 } 127 128 static inline int __raw_write_trylock(rwlock_t *lock) 129 { 130 preempt_disable(); 131 if (do_raw_write_trylock(lock)) { 132 rwlock_acquire(&lock->dep_map, 0, 1, _RET_IP_); 133 return 1; 134 } 135 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 preempt_disable(); 149 rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); 150 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 local_irq_save(flags); 158 preempt_disable(); 159 rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); 160 LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock); 161 return flags; 162 } 163 164 static inline void __raw_read_lock_irq(rwlock_t *lock) 165 { 166 local_irq_disable(); 167 preempt_disable(); 168 rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); 169 LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock); 170 } 171 172 static inline void __raw_read_lock_bh(rwlock_t *lock) 173 { 174 __local_bh_disable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); 175 rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); 176 LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock); 177 } 178 179 static inline unsigned long __raw_write_lock_irqsave(rwlock_t *lock) 180 { 181 unsigned long flags; 182 183 local_irq_save(flags); 184 preempt_disable(); 185 rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); 186 LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock); 187 return flags; 188 } 189 190 static inline void __raw_write_lock_irq(rwlock_t *lock) 191 { 192 local_irq_disable(); 193 preempt_disable(); 194 rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); 195 LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock); 196 } 197 198 static inline void __raw_write_lock_bh(rwlock_t *lock) 199 { 200 __local_bh_disable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); 201 rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); 202 LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock); 203 } 204 205 static inline void __raw_write_lock(rwlock_t *lock) 206 { 207 preempt_disable(); 208 rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); 209 LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock); 210 } 211 212 #endif /* !CONFIG_GENERIC_LOCKBREAK || CONFIG_DEBUG_LOCK_ALLOC */ 213 214 static inline void __raw_write_unlock(rwlock_t *lock) 215 { 216 rwlock_release(&lock->dep_map, _RET_IP_); 217 do_raw_write_unlock(lock); 218 preempt_enable(); 219 } 220 221 static inline void __raw_read_unlock(rwlock_t *lock) 222 { 223 rwlock_release(&lock->dep_map, _RET_IP_); 224 do_raw_read_unlock(lock); 225 preempt_enable(); 226 } 227 228 static inline void 229 __raw_read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) 230 { 231 rwlock_release(&lock->dep_map, _RET_IP_); 232 do_raw_read_unlock(lock); 233 local_irq_restore(flags); 234 preempt_enable(); 235 } 236 237 static inline void __raw_read_unlock_irq(rwlock_t *lock) 238 { 239 rwlock_release(&lock->dep_map, _RET_IP_); 240 do_raw_read_unlock(lock); 241 local_irq_enable(); 242 preempt_enable(); 243 } 244 245 static inline void __raw_read_unlock_bh(rwlock_t *lock) 246 { 247 rwlock_release(&lock->dep_map, _RET_IP_); 248 do_raw_read_unlock(lock); 249 __local_bh_enable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); 250 } 251 252 static inline void __raw_write_unlock_irqrestore(rwlock_t *lock, 253 unsigned long flags) 254 { 255 rwlock_release(&lock->dep_map, _RET_IP_); 256 do_raw_write_unlock(lock); 257 local_irq_restore(flags); 258 preempt_enable(); 259 } 260 261 static inline void __raw_write_unlock_irq(rwlock_t *lock) 262 { 263 rwlock_release(&lock->dep_map, _RET_IP_); 264 do_raw_write_unlock(lock); 265 local_irq_enable(); 266 preempt_enable(); 267 } 268 269 static inline void __raw_write_unlock_bh(rwlock_t *lock) 270 { 271 rwlock_release(&lock->dep_map, _RET_IP_); 272 do_raw_write_unlock(lock); 273 __local_bh_enable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); 274 } 275 276 #endif /* __LINUX_RWLOCK_API_SMP_H */ 277