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 : : 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 : : struct rt_mutex_waiter *w = NULL; 57 : : 58 [ # # ]: 0 : if (leftmost) { 59 : : 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 : : 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 : : 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 : : static inline struct task_struct *rt_mutex_owner(struct rt_mutex *lock) 109 : : { 110 : : 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