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_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 local_irq_disable(); 168 preempt_disable(); 169 rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); 170 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 __local_bh_disable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); 176 rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); 177 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 local_irq_save(flags); 185 preempt_disable(); 186 rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); 187 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 local_irq_disable(); 195 preempt_disable(); 196 rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); 197 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 __local_bh_disable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); 203 rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); 204 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 preempt_disable(); 210 rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); 211 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, _RET_IP_); 219 do_raw_write_unlock(lock); 220 preempt_enable(); 221 } 222 223 static inline void __raw_read_unlock(rwlock_t *lock) 224 { 225 rwlock_release(&lock->dep_map, _RET_IP_); 226 do_raw_read_unlock(lock); 227 preempt_enable(); 228 } 229 230 static inline void 231 __raw_read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) 232 { 233 rwlock_release(&lock->dep_map, _RET_IP_); 234 do_raw_read_unlock(lock); 235 local_irq_restore(flags); 236 preempt_enable(); 237 } 238 239 static inline void __raw_read_unlock_irq(rwlock_t *lock) 240 { 241 rwlock_release(&lock->dep_map, _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, _RET_IP_); 250 do_raw_read_unlock(lock); 251 __local_bh_enable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); 252 } 253 254 static inline void __raw_write_unlock_irqrestore(rwlock_t *lock, 255 unsigned long flags) 256 { 257 rwlock_release(&lock->dep_map, _RET_IP_); 258 do_raw_write_unlock(lock); 259 local_irq_restore(flags); 260 preempt_enable(); 261 } 262 263 static inline void __raw_write_unlock_irq(rwlock_t *lock) 264 { 265 rwlock_release(&lock->dep_map, _RET_IP_); 266 do_raw_write_unlock(lock); 267 local_irq_enable(); 268 preempt_enable(); 269 } 270 271 static inline void __raw_write_unlock_bh(rwlock_t *lock) 272 { 273 rwlock_release(&lock->dep_map, _RET_IP_); 274 do_raw_write_unlock(lock); 275 __local_bh_enable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); 276 } 277 278 #endif /* __LINUX_RWLOCK_API_SMP_H */ 279