xref: /openbmc/linux/include/linux/rtmutex.h (revision a3642021)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
223f78d4aSIngo Molnar /*
323f78d4aSIngo Molnar  * RT Mutexes: blocking mutual exclusion locks with PI support
423f78d4aSIngo Molnar  *
523f78d4aSIngo Molnar  * started by Ingo Molnar and Thomas Gleixner:
623f78d4aSIngo Molnar  *
723f78d4aSIngo Molnar  *  Copyright (C) 2004-2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
823f78d4aSIngo Molnar  *  Copyright (C) 2006, Timesys Corp., Thomas Gleixner <tglx@timesys.com>
923f78d4aSIngo Molnar  *
1023f78d4aSIngo Molnar  * This file contains the public data structure and API definitions.
1123f78d4aSIngo Molnar  */
1223f78d4aSIngo Molnar 
1323f78d4aSIngo Molnar #ifndef __LINUX_RT_MUTEX_H
1423f78d4aSIngo Molnar #define __LINUX_RT_MUTEX_H
1523f78d4aSIngo Molnar 
166bc8996aSThomas Gleixner #include <linux/compiler.h>
1723f78d4aSIngo Molnar #include <linux/linkage.h>
18e4e17af3SSebastian Andrzej Siewior #include <linux/rbtree_types.h>
19a403abbdSSebastian Andrzej Siewior #include <linux/spinlock_types_raw.h>
2023f78d4aSIngo Molnar 
214f0e056fSDave Young extern int max_lock_depth; /* for sysctl */
224f0e056fSDave Young 
23830e6accSPeter Zijlstra struct rt_mutex_base {
24830e6accSPeter Zijlstra 	raw_spinlock_t		wait_lock;
25830e6accSPeter Zijlstra 	struct rb_root_cached   waiters;
26830e6accSPeter Zijlstra 	struct task_struct	*owner;
27830e6accSPeter Zijlstra };
28830e6accSPeter Zijlstra 
29830e6accSPeter Zijlstra #define __RT_MUTEX_BASE_INITIALIZER(rtbasename)				\
30830e6accSPeter Zijlstra {									\
31830e6accSPeter Zijlstra 	.wait_lock = __RAW_SPIN_LOCK_UNLOCKED(rtbasename.wait_lock),	\
32830e6accSPeter Zijlstra 	.waiters = RB_ROOT_CACHED,					\
33830e6accSPeter Zijlstra 	.owner = NULL							\
34830e6accSPeter Zijlstra }
35830e6accSPeter Zijlstra 
366bc8996aSThomas Gleixner /**
376bc8996aSThomas Gleixner  * rt_mutex_base_is_locked - is the rtmutex locked
386bc8996aSThomas Gleixner  * @lock: the mutex to be queried
396bc8996aSThomas Gleixner  *
406bc8996aSThomas Gleixner  * Returns true if the mutex is locked, false if unlocked.
416bc8996aSThomas Gleixner  */
rt_mutex_base_is_locked(struct rt_mutex_base * lock)426bc8996aSThomas Gleixner static inline bool rt_mutex_base_is_locked(struct rt_mutex_base *lock)
436bc8996aSThomas Gleixner {
446bc8996aSThomas Gleixner 	return READ_ONCE(lock->owner) != NULL;
456bc8996aSThomas Gleixner }
466bc8996aSThomas Gleixner 
47830e6accSPeter Zijlstra extern void rt_mutex_base_init(struct rt_mutex_base *rtb);
48830e6accSPeter Zijlstra 
4945f8bde0SRobert P. J. Day /**
5023f78d4aSIngo Molnar  * The rt_mutex structure
5123f78d4aSIngo Molnar  *
5223f78d4aSIngo Molnar  * @wait_lock:	spinlock to protect the structure
53a23ba907SDavidlohr Bueso  * @waiters:	rbtree root to enqueue waiters in priority order;
54a23ba907SDavidlohr Bueso  *              caches top-waiter (leftmost node).
5523f78d4aSIngo Molnar  * @owner:	the mutex owner
5623f78d4aSIngo Molnar  */
5723f78d4aSIngo Molnar struct rt_mutex {
58830e6accSPeter Zijlstra 	struct rt_mutex_base	rtmutex;
59f5694788SPeter Zijlstra #ifdef CONFIG_DEBUG_LOCK_ALLOC
60f5694788SPeter Zijlstra 	struct lockdep_map	dep_map;
61f5694788SPeter Zijlstra #endif
6223f78d4aSIngo Molnar };
6323f78d4aSIngo Molnar 
6423f78d4aSIngo Molnar struct rt_mutex_waiter;
6523f78d4aSIngo Molnar struct hrtimer_sleeper;
6623f78d4aSIngo Molnar 
6723f78d4aSIngo Molnar #ifdef CONFIG_DEBUG_RT_MUTEXES
68199cacd1SSebastian Andrzej Siewior extern void rt_mutex_debug_task_free(struct task_struct *tsk);
69e7eebaf6SIngo Molnar #else
rt_mutex_debug_task_free(struct task_struct * tsk)708188d74eSThomas Gleixner static inline void rt_mutex_debug_task_free(struct task_struct *tsk) { }
71e7eebaf6SIngo Molnar #endif
72e7eebaf6SIngo Molnar 
73f5694788SPeter Zijlstra #define rt_mutex_init(mutex) \
74f5694788SPeter Zijlstra do { \
75f5694788SPeter Zijlstra 	static struct lock_class_key __key; \
76f5694788SPeter Zijlstra 	__rt_mutex_init(mutex, __func__, &__key); \
77f5694788SPeter Zijlstra } while (0)
78f5694788SPeter Zijlstra 
79f5694788SPeter Zijlstra #ifdef CONFIG_DEBUG_LOCK_ALLOC
80f5694788SPeter Zijlstra #define __DEP_MAP_RT_MUTEX_INITIALIZER(mutexname)	\
81b41cda03SThomas Gleixner 	.dep_map = {					\
82b41cda03SThomas Gleixner 		.name = #mutexname,			\
83b41cda03SThomas Gleixner 		.wait_type_inner = LD_WAIT_SLEEP,	\
84b41cda03SThomas Gleixner 	}
85f5694788SPeter Zijlstra #else
86f5694788SPeter Zijlstra #define __DEP_MAP_RT_MUTEX_INITIALIZER(mutexname)
87f5694788SPeter Zijlstra #endif
88f5694788SPeter Zijlstra 
8923f78d4aSIngo Molnar #define __RT_MUTEX_INITIALIZER(mutexname)				\
90b41cda03SThomas Gleixner {									\
91830e6accSPeter Zijlstra 	.rtmutex = __RT_MUTEX_BASE_INITIALIZER(mutexname.rtmutex),	\
92b41cda03SThomas Gleixner 	__DEP_MAP_RT_MUTEX_INITIALIZER(mutexname)			\
93b41cda03SThomas Gleixner }
9423f78d4aSIngo Molnar 
9523f78d4aSIngo Molnar #define DEFINE_RT_MUTEX(mutexname) \
9623f78d4aSIngo Molnar 	struct rt_mutex mutexname = __RT_MUTEX_INITIALIZER(mutexname)
9723f78d4aSIngo Molnar 
98f5694788SPeter Zijlstra extern void __rt_mutex_init(struct rt_mutex *lock, const char *name, struct lock_class_key *key);
9923f78d4aSIngo Molnar 
10062cedf3eSPeter Rosin #ifdef CONFIG_DEBUG_LOCK_ALLOC
10162cedf3eSPeter Rosin extern void rt_mutex_lock_nested(struct rt_mutex *lock, unsigned int subclass);
102*a3642021SSebastian Andrzej Siewior extern void _rt_mutex_lock_nest_lock(struct rt_mutex *lock, struct lockdep_map *nest_lock);
10362cedf3eSPeter Rosin #define rt_mutex_lock(lock) rt_mutex_lock_nested(lock, 0)
104*a3642021SSebastian Andrzej Siewior #define rt_mutex_lock_nest_lock(lock, nest_lock)			\
105*a3642021SSebastian Andrzej Siewior 	do {								\
106*a3642021SSebastian Andrzej Siewior 		typecheck(struct lockdep_map *, &(nest_lock)->dep_map);	\
107*a3642021SSebastian Andrzej Siewior 		_rt_mutex_lock_nest_lock(lock, &(nest_lock)->dep_map);	\
108*a3642021SSebastian Andrzej Siewior 	} while (0)
109*a3642021SSebastian Andrzej Siewior 
11062cedf3eSPeter Rosin #else
11123f78d4aSIngo Molnar extern void rt_mutex_lock(struct rt_mutex *lock);
11262cedf3eSPeter Rosin #define rt_mutex_lock_nested(lock, subclass) rt_mutex_lock(lock)
113*a3642021SSebastian Andrzej Siewior #define rt_mutex_lock_nest_lock(lock, nest_lock) rt_mutex_lock(lock)
11462cedf3eSPeter Rosin #endif
11562cedf3eSPeter Rosin 
116c051b21fSThomas Gleixner extern int rt_mutex_lock_interruptible(struct rt_mutex *lock);
117*a3642021SSebastian Andrzej Siewior extern int rt_mutex_lock_killable(struct rt_mutex *lock);
11823f78d4aSIngo Molnar extern int rt_mutex_trylock(struct rt_mutex *lock);
11923f78d4aSIngo Molnar 
12023f78d4aSIngo Molnar extern void rt_mutex_unlock(struct rt_mutex *lock);
12123f78d4aSIngo Molnar 
12223f78d4aSIngo Molnar #endif
123