Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0 */
2 : : /*
3 : : * RT Mutexes: blocking mutual exclusion locks with PI support
4 : : *
5 : : * started by Ingo Molnar and Thomas Gleixner:
6 : : *
7 : : * Copyright (C) 2004-2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
8 : : * Copyright (C) 2006, Timesys Corp., Thomas Gleixner <tglx@timesys.com>
9 : : *
10 : : * This file contains the private data structure and API definitions.
11 : : */
12 : :
13 : : #ifndef __KERNEL_RTMUTEX_COMMON_H
14 : : #define __KERNEL_RTMUTEX_COMMON_H
15 : :
16 : : #include <linux/rtmutex.h>
17 : : #include <linux/sched/wake_q.h>
18 : :
19 : : /*
20 : : * This is the control structure for tasks blocked on a rt_mutex,
21 : : * which is allocated on the kernel stack on of the blocked task.
22 : : *
23 : : * @tree_entry: pi node to enqueue into the mutex waiters tree
24 : : * @pi_tree_entry: pi node to enqueue into the mutex owner waiters tree
25 : : * @task: task reference to the blocked task
26 : : */
27 : : struct rt_mutex_waiter {
28 : : struct rb_node tree_entry;
29 : : struct rb_node pi_tree_entry;
30 : : struct task_struct *task;
31 : : struct rt_mutex *lock;
32 : : #ifdef CONFIG_DEBUG_RT_MUTEXES
33 : : unsigned long ip;
34 : : struct pid *deadlock_task_pid;
35 : : struct rt_mutex *deadlock_lock;
36 : : #endif
37 : : int prio;
38 : : u64 deadline;
39 : : };
40 : :
41 : : /*
42 : : * Various helpers to access the waiters-tree:
43 : : */
44 : :
45 : : #ifdef CONFIG_RT_MUTEXES
46 : :
47 : 0 : static inline int rt_mutex_has_waiters(struct rt_mutex *lock)
48 : : {
49 [ # # # # : 0 : return !RB_EMPTY_ROOT(&lock->waiters.rb_root);
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
50 : : }
51 : :
52 : : static inline struct rt_mutex_waiter *
53 : 0 : rt_mutex_top_waiter(struct rt_mutex *lock)
54 : : {
55 : 0 : struct rb_node *leftmost = rb_first_cached(&lock->waiters);
56 : 0 : struct rt_mutex_waiter *w = NULL;
57 : :
58 [ # # # # : 0 : if (leftmost) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ]
59 : 0 : w = rb_entry(leftmost, struct rt_mutex_waiter, tree_entry);
60 [ # # # # : 0 : BUG_ON(w->lock != lock);
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ]
61 : : }
62 [ # # # # : 0 : return w;
# # # # #
# # # #
# ]
63 : : }
64 : :
65 : 0 : static inline int task_has_pi_waiters(struct task_struct *p)
66 : : {
67 [ # # # # : 0 : return !RB_EMPTY_ROOT(&p->pi_waiters.rb_root);
# # # # #
# # # ]
68 : : }
69 : :
70 : : static inline struct rt_mutex_waiter *
71 : 0 : task_top_pi_waiter(struct task_struct *p)
72 : : {
73 [ # # ]: 0 : return rb_entry(p->pi_waiters.rb_leftmost,
74 : : struct rt_mutex_waiter, pi_tree_entry);
75 : : }
76 : :
77 : : #else
78 : :
79 : : static inline int rt_mutex_has_waiters(struct rt_mutex *lock)
80 : : {
81 : : return false;
82 : : }
83 : :
84 : : static inline struct rt_mutex_waiter *
85 : : rt_mutex_top_waiter(struct rt_mutex *lock)
86 : : {
87 : : return NULL;
88 : : }
89 : :
90 : : static inline int task_has_pi_waiters(struct task_struct *p)
91 : : {
92 : : return false;
93 : : }
94 : :
95 : : static inline struct rt_mutex_waiter *
96 : : task_top_pi_waiter(struct task_struct *p)
97 : : {
98 : : return NULL;
99 : : }
100 : :
101 : : #endif
102 : :
103 : : /*
104 : : * lock->owner state tracking:
105 : : */
106 : : #define RT_MUTEX_HAS_WAITERS 1UL
107 : :
108 : 0 : static inline struct task_struct *rt_mutex_owner(struct rt_mutex *lock)
109 : : {
110 [ # # # # : 0 : unsigned long owner = (unsigned long) READ_ONCE(lock->owner);
# # # # #
# # # # #
# # # # ]
111 : :
112 [ # # # # : 0 : return (struct task_struct *) (owner & ~RT_MUTEX_HAS_WAITERS);
# # # # #
# # # # #
# # # # ]
113 : : }
114 : :
115 : : /*
116 : : * Constants for rt mutex functions which have a selectable deadlock
117 : : * detection.
118 : : *
119 : : * RT_MUTEX_MIN_CHAINWALK: Stops the lock chain walk when there are
120 : : * no further PI adjustments to be made.
121 : : *
122 : : * RT_MUTEX_FULL_CHAINWALK: Invoke deadlock detection with a full
123 : : * walk of the lock chain.
124 : : */
125 : : enum rtmutex_chainwalk {
126 : : RT_MUTEX_MIN_CHAINWALK,
127 : : RT_MUTEX_FULL_CHAINWALK,
128 : : };
129 : :
130 : : /*
131 : : * PI-futex support (proxy locking functions, etc.):
132 : : */
133 : : extern struct task_struct *rt_mutex_next_owner(struct rt_mutex *lock);
134 : : extern void rt_mutex_init_proxy_locked(struct rt_mutex *lock,
135 : : struct task_struct *proxy_owner);
136 : : extern void rt_mutex_proxy_unlock(struct rt_mutex *lock,
137 : : struct task_struct *proxy_owner);
138 : : extern void rt_mutex_init_waiter(struct rt_mutex_waiter *waiter);
139 : : extern int __rt_mutex_start_proxy_lock(struct rt_mutex *lock,
140 : : struct rt_mutex_waiter *waiter,
141 : : struct task_struct *task);
142 : : extern int rt_mutex_start_proxy_lock(struct rt_mutex *lock,
143 : : struct rt_mutex_waiter *waiter,
144 : : struct task_struct *task);
145 : : extern int rt_mutex_wait_proxy_lock(struct rt_mutex *lock,
146 : : struct hrtimer_sleeper *to,
147 : : struct rt_mutex_waiter *waiter);
148 : : extern bool rt_mutex_cleanup_proxy_lock(struct rt_mutex *lock,
149 : : struct rt_mutex_waiter *waiter);
150 : :
151 : : extern int rt_mutex_futex_trylock(struct rt_mutex *l);
152 : : extern int __rt_mutex_futex_trylock(struct rt_mutex *l);
153 : :
154 : : extern void rt_mutex_futex_unlock(struct rt_mutex *lock);
155 : : extern bool __rt_mutex_futex_unlock(struct rt_mutex *lock,
156 : : struct wake_q_head *wqh);
157 : :
158 : : extern void rt_mutex_postunlock(struct wake_q_head *wake_q);
159 : :
160 : : #ifdef CONFIG_DEBUG_RT_MUTEXES
161 : : # include "rtmutex-debug.h"
162 : : #else
163 : : # include "rtmutex.h"
164 : : #endif
165 : :
166 : : #endif
|