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 18void __lockfunc _raw_read_lock(rwlock_t *lock) __acquires(lock); 19void __lockfunc _raw_write_lock(rwlock_t *lock) __acquires(lock); 20void __lockfunc _raw_read_lock_bh(rwlock_t *lock) __acquires(lock); 21void __lockfunc _raw_write_lock_bh(rwlock_t *lock) __acquires(lock); 22void __lockfunc _raw_read_lock_irq(rwlock_t *lock) __acquires(lock); 23void __lockfunc _raw_write_lock_irq(rwlock_t *lock) __acquires(lock); 24unsigned long __lockfunc _raw_read_lock_irqsave(rwlock_t *lock) 25 __acquires(lock); 26unsigned long __lockfunc _raw_write_lock_irqsave(rwlock_t *lock) 27 __acquires(lock); 28int __lockfunc _raw_read_trylock(rwlock_t *lock); 29int __lockfunc _raw_write_trylock(rwlock_t *lock); 30void __lockfunc _raw_read_unlock(rwlock_t *lock) __releases(lock); 31void __lockfunc _raw_write_unlock(rwlock_t *lock) __releases(lock); 32void __lockfunc _raw_read_unlock_bh(rwlock_t *lock) __releases(lock); 33void __lockfunc _raw_write_unlock_bh(rwlock_t *lock) __releases(lock); 34void __lockfunc _raw_read_unlock_irq(rwlock_t *lock) __releases(lock); 35void __lockfunc _raw_write_unlock_irq(rwlock_t *lock) __releases(lock); 36void __lockfunc 37_raw_read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) 38 __releases(lock); 39void __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 117static 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 128static 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 146static 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 153static 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 165static 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 173static 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 180static 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 192static 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 200static 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 207static 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_PREEMPT */ 215 216static 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 preempt_enable(); 221} 222 223static inline void __raw_read_unlock(rwlock_t *lock) 224{ 225 rwlock_release(&lock->dep_map, 1, _RET_IP_); 226 do_raw_read_unlock(lock); 227 preempt_enable(); 228} 229 230static inline void 231__raw_read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) 232{ 233 rwlock_release(&lock->dep_map, 1, _RET_IP_); 234 do_raw_read_unlock(lock); 235 local_irq_restore(flags); 236 preempt_enable(); 237} 238 239static 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 247static inline void __raw_read_unlock_bh(rwlock_t *lock) 248{ 249 rwlock_release(&lock->dep_map, 1, _RET_IP_); 250 do_raw_read_unlock(lock); 251 __local_bh_enable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); 252} 253 254static 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 local_irq_restore(flags); 260 preempt_enable(); 261} 262 263static 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 local_irq_enable(); 268 preempt_enable(); 269} 270 271static 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 __local_bh_enable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET); 276} 277 278#endif /* __LINUX_RWLOCK_API_SMP_H */ 279