1342a9324SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2342a9324SThomas Gleixner #ifndef __LINUX_SPINLOCK_RT_H
3342a9324SThomas Gleixner #define __LINUX_SPINLOCK_RT_H
4342a9324SThomas Gleixner
52747b93eSSebastian Andrzej Siewior #ifndef __LINUX_INSIDE_SPINLOCK_H
6342a9324SThomas Gleixner #error Do not include directly. Use spinlock.h
7342a9324SThomas Gleixner #endif
8342a9324SThomas Gleixner
9342a9324SThomas Gleixner #ifdef CONFIG_DEBUG_LOCK_ALLOC
10342a9324SThomas Gleixner extern void __rt_spin_lock_init(spinlock_t *lock, const char *name,
1131552385SThomas Gleixner struct lock_class_key *key, bool percpu);
12342a9324SThomas Gleixner #else
__rt_spin_lock_init(spinlock_t * lock,const char * name,struct lock_class_key * key,bool percpu)13342a9324SThomas Gleixner static inline void __rt_spin_lock_init(spinlock_t *lock, const char *name,
1431552385SThomas Gleixner struct lock_class_key *key, bool percpu)
15342a9324SThomas Gleixner {
16342a9324SThomas Gleixner }
17342a9324SThomas Gleixner #endif
18342a9324SThomas Gleixner
19*5c2e7736SEder Zulian #define __spin_lock_init(slock, name, key, percpu) \
20342a9324SThomas Gleixner do { \
21342a9324SThomas Gleixner rt_mutex_base_init(&(slock)->lock); \
22*5c2e7736SEder Zulian __rt_spin_lock_init(slock, name, key, percpu); \
2331552385SThomas Gleixner } while (0)
2431552385SThomas Gleixner
25*5c2e7736SEder Zulian #define _spin_lock_init(slock, percpu) \
2631552385SThomas Gleixner do { \
2731552385SThomas Gleixner static struct lock_class_key __key; \
28*5c2e7736SEder Zulian __spin_lock_init(slock, #slock, &__key, percpu); \
29342a9324SThomas Gleixner } while (0)
30342a9324SThomas Gleixner
31*5c2e7736SEder Zulian #define spin_lock_init(slock) _spin_lock_init(slock, false)
32*5c2e7736SEder Zulian #define local_spin_lock_init(slock) _spin_lock_init(slock, true)
33*5c2e7736SEder Zulian
3452e0874fSSebastian Andrzej Siewior extern void rt_spin_lock(spinlock_t *lock) __acquires(lock);
3552e0874fSSebastian Andrzej Siewior extern void rt_spin_lock_nested(spinlock_t *lock, int subclass) __acquires(lock);
3652e0874fSSebastian Andrzej Siewior extern void rt_spin_lock_nest_lock(spinlock_t *lock, struct lockdep_map *nest_lock) __acquires(lock);
3752e0874fSSebastian Andrzej Siewior extern void rt_spin_unlock(spinlock_t *lock) __releases(lock);
38342a9324SThomas Gleixner extern void rt_spin_lock_unlock(spinlock_t *lock);
39342a9324SThomas Gleixner extern int rt_spin_trylock_bh(spinlock_t *lock);
40342a9324SThomas Gleixner extern int rt_spin_trylock(spinlock_t *lock);
41342a9324SThomas Gleixner
spin_lock(spinlock_t * lock)42342a9324SThomas Gleixner static __always_inline void spin_lock(spinlock_t *lock)
43342a9324SThomas Gleixner {
44342a9324SThomas Gleixner rt_spin_lock(lock);
45342a9324SThomas Gleixner }
46342a9324SThomas Gleixner
47342a9324SThomas Gleixner #ifdef CONFIG_LOCKDEP
48342a9324SThomas Gleixner # define __spin_lock_nested(lock, subclass) \
49342a9324SThomas Gleixner rt_spin_lock_nested(lock, subclass)
50342a9324SThomas Gleixner
51342a9324SThomas Gleixner # define __spin_lock_nest_lock(lock, nest_lock) \
52342a9324SThomas Gleixner do { \
53342a9324SThomas Gleixner typecheck(struct lockdep_map *, &(nest_lock)->dep_map); \
54342a9324SThomas Gleixner rt_spin_lock_nest_lock(lock, &(nest_lock)->dep_map); \
55342a9324SThomas Gleixner } while (0)
56342a9324SThomas Gleixner # define __spin_lock_irqsave_nested(lock, flags, subclass) \
57342a9324SThomas Gleixner do { \
58342a9324SThomas Gleixner typecheck(unsigned long, flags); \
59342a9324SThomas Gleixner flags = 0; \
60342a9324SThomas Gleixner __spin_lock_nested(lock, subclass); \
61342a9324SThomas Gleixner } while (0)
62342a9324SThomas Gleixner
63342a9324SThomas Gleixner #else
64342a9324SThomas Gleixner /*
65342a9324SThomas Gleixner * Always evaluate the 'subclass' argument to avoid that the compiler
66342a9324SThomas Gleixner * warns about set-but-not-used variables when building with
67342a9324SThomas Gleixner * CONFIG_DEBUG_LOCK_ALLOC=n and with W=1.
68342a9324SThomas Gleixner */
69342a9324SThomas Gleixner # define __spin_lock_nested(lock, subclass) spin_lock(((void)(subclass), (lock)))
70342a9324SThomas Gleixner # define __spin_lock_nest_lock(lock, subclass) spin_lock(((void)(subclass), (lock)))
71342a9324SThomas Gleixner # define __spin_lock_irqsave_nested(lock, flags, subclass) \
72342a9324SThomas Gleixner spin_lock_irqsave(((void)(subclass), (lock)), flags)
73342a9324SThomas Gleixner #endif
74342a9324SThomas Gleixner
75342a9324SThomas Gleixner #define spin_lock_nested(lock, subclass) \
76342a9324SThomas Gleixner __spin_lock_nested(lock, subclass)
77342a9324SThomas Gleixner
78342a9324SThomas Gleixner #define spin_lock_nest_lock(lock, nest_lock) \
79342a9324SThomas Gleixner __spin_lock_nest_lock(lock, nest_lock)
80342a9324SThomas Gleixner
81342a9324SThomas Gleixner #define spin_lock_irqsave_nested(lock, flags, subclass) \
82342a9324SThomas Gleixner __spin_lock_irqsave_nested(lock, flags, subclass)
83342a9324SThomas Gleixner
spin_lock_bh(spinlock_t * lock)84342a9324SThomas Gleixner static __always_inline void spin_lock_bh(spinlock_t *lock)
85342a9324SThomas Gleixner {
86342a9324SThomas Gleixner /* Investigate: Drop bh when blocking ? */
87342a9324SThomas Gleixner local_bh_disable();
88342a9324SThomas Gleixner rt_spin_lock(lock);
89342a9324SThomas Gleixner }
90342a9324SThomas Gleixner
spin_lock_irq(spinlock_t * lock)91342a9324SThomas Gleixner static __always_inline void spin_lock_irq(spinlock_t *lock)
92342a9324SThomas Gleixner {
93342a9324SThomas Gleixner rt_spin_lock(lock);
94342a9324SThomas Gleixner }
95342a9324SThomas Gleixner
96342a9324SThomas Gleixner #define spin_lock_irqsave(lock, flags) \
97342a9324SThomas Gleixner do { \
98342a9324SThomas Gleixner typecheck(unsigned long, flags); \
99342a9324SThomas Gleixner flags = 0; \
100342a9324SThomas Gleixner spin_lock(lock); \
101342a9324SThomas Gleixner } while (0)
102342a9324SThomas Gleixner
spin_unlock(spinlock_t * lock)103342a9324SThomas Gleixner static __always_inline void spin_unlock(spinlock_t *lock)
104342a9324SThomas Gleixner {
105342a9324SThomas Gleixner rt_spin_unlock(lock);
106342a9324SThomas Gleixner }
107342a9324SThomas Gleixner
spin_unlock_bh(spinlock_t * lock)108342a9324SThomas Gleixner static __always_inline void spin_unlock_bh(spinlock_t *lock)
109342a9324SThomas Gleixner {
110342a9324SThomas Gleixner rt_spin_unlock(lock);
111342a9324SThomas Gleixner local_bh_enable();
112342a9324SThomas Gleixner }
113342a9324SThomas Gleixner
spin_unlock_irq(spinlock_t * lock)114342a9324SThomas Gleixner static __always_inline void spin_unlock_irq(spinlock_t *lock)
115342a9324SThomas Gleixner {
116342a9324SThomas Gleixner rt_spin_unlock(lock);
117342a9324SThomas Gleixner }
118342a9324SThomas Gleixner
spin_unlock_irqrestore(spinlock_t * lock,unsigned long flags)119342a9324SThomas Gleixner static __always_inline void spin_unlock_irqrestore(spinlock_t *lock,
120342a9324SThomas Gleixner unsigned long flags)
121342a9324SThomas Gleixner {
122342a9324SThomas Gleixner rt_spin_unlock(lock);
123342a9324SThomas Gleixner }
124342a9324SThomas Gleixner
125342a9324SThomas Gleixner #define spin_trylock(lock) \
126342a9324SThomas Gleixner __cond_lock(lock, rt_spin_trylock(lock))
127342a9324SThomas Gleixner
128342a9324SThomas Gleixner #define spin_trylock_bh(lock) \
129342a9324SThomas Gleixner __cond_lock(lock, rt_spin_trylock_bh(lock))
130342a9324SThomas Gleixner
131342a9324SThomas Gleixner #define spin_trylock_irq(lock) \
132342a9324SThomas Gleixner __cond_lock(lock, rt_spin_trylock(lock))
133342a9324SThomas Gleixner
134b1f01f9eSSebastian Andrzej Siewior #define spin_trylock_irqsave(lock, flags) \
135342a9324SThomas Gleixner ({ \
136342a9324SThomas Gleixner int __locked; \
137342a9324SThomas Gleixner \
138342a9324SThomas Gleixner typecheck(unsigned long, flags); \
139342a9324SThomas Gleixner flags = 0; \
140342a9324SThomas Gleixner __locked = spin_trylock(lock); \
141342a9324SThomas Gleixner __locked; \
142342a9324SThomas Gleixner })
143342a9324SThomas Gleixner
144342a9324SThomas Gleixner #define spin_is_contended(lock) (((void)(lock), 0))
145342a9324SThomas Gleixner
spin_is_locked(spinlock_t * lock)146342a9324SThomas Gleixner static inline int spin_is_locked(spinlock_t *lock)
147342a9324SThomas Gleixner {
148342a9324SThomas Gleixner return rt_mutex_base_is_locked(&lock->lock);
149342a9324SThomas Gleixner }
150342a9324SThomas Gleixner
151342a9324SThomas Gleixner #define assert_spin_locked(lock) BUG_ON(!spin_is_locked(lock))
152342a9324SThomas Gleixner
1538282947fSThomas Gleixner #include <linux/rwlock_rt.h>
1548282947fSThomas Gleixner
155342a9324SThomas Gleixner #endif
156