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