18282947fSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
28282947fSThomas Gleixner #ifndef __LINUX_RWLOCK_RT_H
38282947fSThomas Gleixner #define __LINUX_RWLOCK_RT_H
48282947fSThomas Gleixner
58282947fSThomas Gleixner #ifndef __LINUX_SPINLOCK_RT_H
68282947fSThomas Gleixner #error Do not #include directly. Use <linux/spinlock.h>.
78282947fSThomas Gleixner #endif
88282947fSThomas Gleixner
98282947fSThomas Gleixner #ifdef CONFIG_DEBUG_LOCK_ALLOC
108282947fSThomas Gleixner extern void __rt_rwlock_init(rwlock_t *rwlock, const char *name,
118282947fSThomas Gleixner struct lock_class_key *key);
128282947fSThomas Gleixner #else
__rt_rwlock_init(rwlock_t * rwlock,char * name,struct lock_class_key * key)138282947fSThomas Gleixner static inline void __rt_rwlock_init(rwlock_t *rwlock, char *name,
148282947fSThomas Gleixner struct lock_class_key *key)
158282947fSThomas Gleixner {
168282947fSThomas Gleixner }
178282947fSThomas Gleixner #endif
188282947fSThomas Gleixner
198282947fSThomas Gleixner #define rwlock_init(rwl) \
208282947fSThomas Gleixner do { \
218282947fSThomas Gleixner static struct lock_class_key __key; \
228282947fSThomas Gleixner \
238282947fSThomas Gleixner init_rwbase_rt(&(rwl)->rwbase); \
248282947fSThomas Gleixner __rt_rwlock_init(rwl, #rwl, &__key); \
258282947fSThomas Gleixner } while (0)
268282947fSThomas Gleixner
278282947fSThomas Gleixner extern void rt_read_lock(rwlock_t *rwlock);
288282947fSThomas Gleixner extern int rt_read_trylock(rwlock_t *rwlock);
298282947fSThomas Gleixner extern void rt_read_unlock(rwlock_t *rwlock);
308282947fSThomas Gleixner extern void rt_write_lock(rwlock_t *rwlock);
31*4a57d6bbSMinchan Kim extern void rt_write_lock_nested(rwlock_t *rwlock, int subclass);
328282947fSThomas Gleixner extern int rt_write_trylock(rwlock_t *rwlock);
338282947fSThomas Gleixner extern void rt_write_unlock(rwlock_t *rwlock);
348282947fSThomas Gleixner
read_lock(rwlock_t * rwlock)358282947fSThomas Gleixner static __always_inline void read_lock(rwlock_t *rwlock)
368282947fSThomas Gleixner {
378282947fSThomas Gleixner rt_read_lock(rwlock);
388282947fSThomas Gleixner }
398282947fSThomas Gleixner
read_lock_bh(rwlock_t * rwlock)408282947fSThomas Gleixner static __always_inline void read_lock_bh(rwlock_t *rwlock)
418282947fSThomas Gleixner {
428282947fSThomas Gleixner local_bh_disable();
438282947fSThomas Gleixner rt_read_lock(rwlock);
448282947fSThomas Gleixner }
458282947fSThomas Gleixner
read_lock_irq(rwlock_t * rwlock)468282947fSThomas Gleixner static __always_inline void read_lock_irq(rwlock_t *rwlock)
478282947fSThomas Gleixner {
488282947fSThomas Gleixner rt_read_lock(rwlock);
498282947fSThomas Gleixner }
508282947fSThomas Gleixner
518282947fSThomas Gleixner #define read_lock_irqsave(lock, flags) \
528282947fSThomas Gleixner do { \
538282947fSThomas Gleixner typecheck(unsigned long, flags); \
548282947fSThomas Gleixner rt_read_lock(lock); \
558282947fSThomas Gleixner flags = 0; \
568282947fSThomas Gleixner } while (0)
578282947fSThomas Gleixner
588282947fSThomas Gleixner #define read_trylock(lock) __cond_lock(lock, rt_read_trylock(lock))
598282947fSThomas Gleixner
read_unlock(rwlock_t * rwlock)608282947fSThomas Gleixner static __always_inline void read_unlock(rwlock_t *rwlock)
618282947fSThomas Gleixner {
628282947fSThomas Gleixner rt_read_unlock(rwlock);
638282947fSThomas Gleixner }
648282947fSThomas Gleixner
read_unlock_bh(rwlock_t * rwlock)658282947fSThomas Gleixner static __always_inline void read_unlock_bh(rwlock_t *rwlock)
668282947fSThomas Gleixner {
678282947fSThomas Gleixner rt_read_unlock(rwlock);
688282947fSThomas Gleixner local_bh_enable();
698282947fSThomas Gleixner }
708282947fSThomas Gleixner
read_unlock_irq(rwlock_t * rwlock)718282947fSThomas Gleixner static __always_inline void read_unlock_irq(rwlock_t *rwlock)
728282947fSThomas Gleixner {
738282947fSThomas Gleixner rt_read_unlock(rwlock);
748282947fSThomas Gleixner }
758282947fSThomas Gleixner
read_unlock_irqrestore(rwlock_t * rwlock,unsigned long flags)768282947fSThomas Gleixner static __always_inline void read_unlock_irqrestore(rwlock_t *rwlock,
778282947fSThomas Gleixner unsigned long flags)
788282947fSThomas Gleixner {
798282947fSThomas Gleixner rt_read_unlock(rwlock);
808282947fSThomas Gleixner }
818282947fSThomas Gleixner
write_lock(rwlock_t * rwlock)828282947fSThomas Gleixner static __always_inline void write_lock(rwlock_t *rwlock)
838282947fSThomas Gleixner {
848282947fSThomas Gleixner rt_write_lock(rwlock);
858282947fSThomas Gleixner }
868282947fSThomas Gleixner
87*4a57d6bbSMinchan Kim #ifdef CONFIG_DEBUG_LOCK_ALLOC
write_lock_nested(rwlock_t * rwlock,int subclass)88*4a57d6bbSMinchan Kim static __always_inline void write_lock_nested(rwlock_t *rwlock, int subclass)
89*4a57d6bbSMinchan Kim {
90*4a57d6bbSMinchan Kim rt_write_lock_nested(rwlock, subclass);
91*4a57d6bbSMinchan Kim }
92*4a57d6bbSMinchan Kim #else
93*4a57d6bbSMinchan Kim #define write_lock_nested(lock, subclass) rt_write_lock(((void)(subclass), (lock)))
94*4a57d6bbSMinchan Kim #endif
95*4a57d6bbSMinchan Kim
write_lock_bh(rwlock_t * rwlock)968282947fSThomas Gleixner static __always_inline void write_lock_bh(rwlock_t *rwlock)
978282947fSThomas Gleixner {
988282947fSThomas Gleixner local_bh_disable();
998282947fSThomas Gleixner rt_write_lock(rwlock);
1008282947fSThomas Gleixner }
1018282947fSThomas Gleixner
write_lock_irq(rwlock_t * rwlock)1028282947fSThomas Gleixner static __always_inline void write_lock_irq(rwlock_t *rwlock)
1038282947fSThomas Gleixner {
1048282947fSThomas Gleixner rt_write_lock(rwlock);
1058282947fSThomas Gleixner }
1068282947fSThomas Gleixner
1078282947fSThomas Gleixner #define write_lock_irqsave(lock, flags) \
1088282947fSThomas Gleixner do { \
1098282947fSThomas Gleixner typecheck(unsigned long, flags); \
1108282947fSThomas Gleixner rt_write_lock(lock); \
1118282947fSThomas Gleixner flags = 0; \
1128282947fSThomas Gleixner } while (0)
1138282947fSThomas Gleixner
1148282947fSThomas Gleixner #define write_trylock(lock) __cond_lock(lock, rt_write_trylock(lock))
1158282947fSThomas Gleixner
1168282947fSThomas Gleixner #define write_trylock_irqsave(lock, flags) \
1178282947fSThomas Gleixner ({ \
1188282947fSThomas Gleixner int __locked; \
1198282947fSThomas Gleixner \
1208282947fSThomas Gleixner typecheck(unsigned long, flags); \
1218282947fSThomas Gleixner flags = 0; \
1228282947fSThomas Gleixner __locked = write_trylock(lock); \
1238282947fSThomas Gleixner __locked; \
1248282947fSThomas Gleixner })
1258282947fSThomas Gleixner
write_unlock(rwlock_t * rwlock)1268282947fSThomas Gleixner static __always_inline void write_unlock(rwlock_t *rwlock)
1278282947fSThomas Gleixner {
1288282947fSThomas Gleixner rt_write_unlock(rwlock);
1298282947fSThomas Gleixner }
1308282947fSThomas Gleixner
write_unlock_bh(rwlock_t * rwlock)1318282947fSThomas Gleixner static __always_inline void write_unlock_bh(rwlock_t *rwlock)
1328282947fSThomas Gleixner {
1338282947fSThomas Gleixner rt_write_unlock(rwlock);
1348282947fSThomas Gleixner local_bh_enable();
1358282947fSThomas Gleixner }
1368282947fSThomas Gleixner
write_unlock_irq(rwlock_t * rwlock)1378282947fSThomas Gleixner static __always_inline void write_unlock_irq(rwlock_t *rwlock)
1388282947fSThomas Gleixner {
1398282947fSThomas Gleixner rt_write_unlock(rwlock);
1408282947fSThomas Gleixner }
1418282947fSThomas Gleixner
write_unlock_irqrestore(rwlock_t * rwlock,unsigned long flags)1428282947fSThomas Gleixner static __always_inline void write_unlock_irqrestore(rwlock_t *rwlock,
1438282947fSThomas Gleixner unsigned long flags)
1448282947fSThomas Gleixner {
1458282947fSThomas Gleixner rt_write_unlock(rwlock);
1468282947fSThomas Gleixner }
1478282947fSThomas Gleixner
1488282947fSThomas Gleixner #define rwlock_is_contended(lock) (((void)(lock), 0))
1498282947fSThomas Gleixner
1508282947fSThomas Gleixner #endif /* __LINUX_RWLOCK_RT_H */
151