xref: /linux-6.15/include/linux/spinlock_rt.h (revision 5c2e7736)
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