1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * RT Mutexes: blocking mutual exclusion locks with PI support
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * started by Ingo Molnar and Thomas Gleixner:
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * Copyright (C) 2004-2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
8*4882a593Smuzhiyun * Copyright (C) 2006, Timesys Corp., Thomas Gleixner <tglx@timesys.com>
9*4882a593Smuzhiyun *
10*4882a593Smuzhiyun * This file contains the public data structure and API definitions.
11*4882a593Smuzhiyun */
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #ifndef __LINUX_RT_MUTEX_H
14*4882a593Smuzhiyun #define __LINUX_RT_MUTEX_H
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #include <linux/linkage.h>
17*4882a593Smuzhiyun #include <linux/rbtree.h>
18*4882a593Smuzhiyun #include <linux/spinlock_types.h>
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun extern int max_lock_depth; /* for sysctl */
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun /**
23*4882a593Smuzhiyun * The rt_mutex structure
24*4882a593Smuzhiyun *
25*4882a593Smuzhiyun * @wait_lock: spinlock to protect the structure
26*4882a593Smuzhiyun * @waiters: rbtree root to enqueue waiters in priority order;
27*4882a593Smuzhiyun * caches top-waiter (leftmost node).
28*4882a593Smuzhiyun * @owner: the mutex owner
29*4882a593Smuzhiyun */
30*4882a593Smuzhiyun struct rt_mutex {
31*4882a593Smuzhiyun raw_spinlock_t wait_lock;
32*4882a593Smuzhiyun struct rb_root_cached waiters;
33*4882a593Smuzhiyun struct task_struct *owner;
34*4882a593Smuzhiyun #ifdef CONFIG_DEBUG_RT_MUTEXES
35*4882a593Smuzhiyun int save_state;
36*4882a593Smuzhiyun const char *name, *file;
37*4882a593Smuzhiyun int line;
38*4882a593Smuzhiyun void *magic;
39*4882a593Smuzhiyun #endif
40*4882a593Smuzhiyun #ifdef CONFIG_DEBUG_LOCK_ALLOC
41*4882a593Smuzhiyun struct lockdep_map dep_map;
42*4882a593Smuzhiyun #endif
43*4882a593Smuzhiyun };
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun struct rt_mutex_waiter;
46*4882a593Smuzhiyun struct hrtimer_sleeper;
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun #ifdef CONFIG_DEBUG_RT_MUTEXES
49*4882a593Smuzhiyun extern int rt_mutex_debug_check_no_locks_freed(const void *from,
50*4882a593Smuzhiyun unsigned long len);
51*4882a593Smuzhiyun extern void rt_mutex_debug_check_no_locks_held(struct task_struct *task);
52*4882a593Smuzhiyun #else
rt_mutex_debug_check_no_locks_freed(const void * from,unsigned long len)53*4882a593Smuzhiyun static inline int rt_mutex_debug_check_no_locks_freed(const void *from,
54*4882a593Smuzhiyun unsigned long len)
55*4882a593Smuzhiyun {
56*4882a593Smuzhiyun return 0;
57*4882a593Smuzhiyun }
58*4882a593Smuzhiyun # define rt_mutex_debug_check_no_locks_held(task) do { } while (0)
59*4882a593Smuzhiyun #endif
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun #ifdef CONFIG_DEBUG_RT_MUTEXES
62*4882a593Smuzhiyun # define __DEBUG_RT_MUTEX_INITIALIZER(mutexname) \
63*4882a593Smuzhiyun , .name = #mutexname, .file = __FILE__, .line = __LINE__
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun # define rt_mutex_init(mutex) \
66*4882a593Smuzhiyun do { \
67*4882a593Smuzhiyun static struct lock_class_key __key; \
68*4882a593Smuzhiyun __rt_mutex_init(mutex, __func__, &__key); \
69*4882a593Smuzhiyun } while (0)
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun extern void rt_mutex_debug_task_free(struct task_struct *tsk);
72*4882a593Smuzhiyun #else
73*4882a593Smuzhiyun # define __DEBUG_RT_MUTEX_INITIALIZER(mutexname)
74*4882a593Smuzhiyun # define rt_mutex_init(mutex) __rt_mutex_init(mutex, NULL, NULL)
75*4882a593Smuzhiyun # define rt_mutex_debug_task_free(t) do { } while (0)
76*4882a593Smuzhiyun #endif
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun #ifdef CONFIG_DEBUG_LOCK_ALLOC
79*4882a593Smuzhiyun #define __DEP_MAP_RT_MUTEX_INITIALIZER(mutexname) \
80*4882a593Smuzhiyun , .dep_map = { .name = #mutexname }
81*4882a593Smuzhiyun #else
82*4882a593Smuzhiyun #define __DEP_MAP_RT_MUTEX_INITIALIZER(mutexname)
83*4882a593Smuzhiyun #endif
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun #define __RT_MUTEX_INITIALIZER(mutexname) \
86*4882a593Smuzhiyun { .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(mutexname.wait_lock) \
87*4882a593Smuzhiyun , .waiters = RB_ROOT_CACHED \
88*4882a593Smuzhiyun , .owner = NULL \
89*4882a593Smuzhiyun __DEBUG_RT_MUTEX_INITIALIZER(mutexname) \
90*4882a593Smuzhiyun __DEP_MAP_RT_MUTEX_INITIALIZER(mutexname)}
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun #define DEFINE_RT_MUTEX(mutexname) \
93*4882a593Smuzhiyun struct rt_mutex mutexname = __RT_MUTEX_INITIALIZER(mutexname)
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun /**
96*4882a593Smuzhiyun * rt_mutex_is_locked - is the mutex locked
97*4882a593Smuzhiyun * @lock: the mutex to be queried
98*4882a593Smuzhiyun *
99*4882a593Smuzhiyun * Returns 1 if the mutex is locked, 0 if unlocked.
100*4882a593Smuzhiyun */
rt_mutex_is_locked(struct rt_mutex * lock)101*4882a593Smuzhiyun static inline int rt_mutex_is_locked(struct rt_mutex *lock)
102*4882a593Smuzhiyun {
103*4882a593Smuzhiyun return lock->owner != NULL;
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun extern void __rt_mutex_init(struct rt_mutex *lock, const char *name, struct lock_class_key *key);
107*4882a593Smuzhiyun extern void rt_mutex_destroy(struct rt_mutex *lock);
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun #ifdef CONFIG_DEBUG_LOCK_ALLOC
110*4882a593Smuzhiyun extern void rt_mutex_lock_nested(struct rt_mutex *lock, unsigned int subclass);
111*4882a593Smuzhiyun #define rt_mutex_lock(lock) rt_mutex_lock_nested(lock, 0)
112*4882a593Smuzhiyun #else
113*4882a593Smuzhiyun extern void rt_mutex_lock(struct rt_mutex *lock);
114*4882a593Smuzhiyun #define rt_mutex_lock_nested(lock, subclass) rt_mutex_lock(lock)
115*4882a593Smuzhiyun #endif
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun extern int rt_mutex_lock_interruptible(struct rt_mutex *lock);
118*4882a593Smuzhiyun extern int rt_mutex_timed_lock(struct rt_mutex *lock,
119*4882a593Smuzhiyun struct hrtimer_sleeper *timeout);
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun extern int rt_mutex_trylock(struct rt_mutex *lock);
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun extern void rt_mutex_unlock(struct rt_mutex *lock);
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun #endif
126