linux/kernel/locking/rtmutex_common.h
<<
>>
Prefs
   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 */
  27struct 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
  47static inline int rt_mutex_has_waiters(struct rt_mutex *lock)
  48{
  49        return !RB_EMPTY_ROOT(&lock->waiters.rb_root);
  50}
  51
  52static inline struct rt_mutex_waiter *
  53rt_mutex_top_waiter(struct rt_mutex *lock)
  54{
  55        struct rb_node *leftmost = rb_first_cached(&lock->waiters);
  56        struct rt_mutex_waiter *w = NULL;
  57
  58        if (leftmost) {
  59                w = rb_entry(leftmost, struct rt_mutex_waiter, tree_entry);
  60                BUG_ON(w->lock != lock);
  61        }
  62        return w;
  63}
  64
  65static inline int task_has_pi_waiters(struct task_struct *p)
  66{
  67        return !RB_EMPTY_ROOT(&p->pi_waiters.rb_root);
  68}
  69
  70static inline struct rt_mutex_waiter *
  71task_top_pi_waiter(struct task_struct *p)
  72{
  73        return rb_entry(p->pi_waiters.rb_leftmost,
  74                        struct rt_mutex_waiter, pi_tree_entry);
  75}
  76
  77#else
  78
  79static inline int rt_mutex_has_waiters(struct rt_mutex *lock)
  80{
  81        return false;
  82}
  83
  84static inline struct rt_mutex_waiter *
  85rt_mutex_top_waiter(struct rt_mutex *lock)
  86{
  87        return NULL;
  88}
  89
  90static inline int task_has_pi_waiters(struct task_struct *p)
  91{
  92        return false;
  93}
  94
  95static inline struct rt_mutex_waiter *
  96task_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
 108static inline struct task_struct *rt_mutex_owner(struct rt_mutex *lock)
 109{
 110        unsigned long owner = (unsigned long) READ_ONCE(lock->owner);
 111
 112        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 */
 125enum rtmutex_chainwalk {
 126        RT_MUTEX_MIN_CHAINWALK,
 127        RT_MUTEX_FULL_CHAINWALK,
 128};
 129
 130/*
 131 * PI-futex support (proxy locking functions, etc.):
 132 */
 133extern struct task_struct *rt_mutex_next_owner(struct rt_mutex *lock);
 134extern void rt_mutex_init_proxy_locked(struct rt_mutex *lock,
 135                                       struct task_struct *proxy_owner);
 136extern void rt_mutex_proxy_unlock(struct rt_mutex *lock,
 137                                  struct task_struct *proxy_owner);
 138extern void rt_mutex_init_waiter(struct rt_mutex_waiter *waiter);
 139extern int __rt_mutex_start_proxy_lock(struct rt_mutex *lock,
 140                                     struct rt_mutex_waiter *waiter,
 141                                     struct task_struct *task);
 142extern int rt_mutex_start_proxy_lock(struct rt_mutex *lock,
 143                                     struct rt_mutex_waiter *waiter,
 144                                     struct task_struct *task);
 145extern int rt_mutex_wait_proxy_lock(struct rt_mutex *lock,
 146                               struct hrtimer_sleeper *to,
 147                               struct rt_mutex_waiter *waiter);
 148extern bool rt_mutex_cleanup_proxy_lock(struct rt_mutex *lock,
 149                                 struct rt_mutex_waiter *waiter);
 150
 151extern int rt_mutex_futex_trylock(struct rt_mutex *l);
 152extern int __rt_mutex_futex_trylock(struct rt_mutex *l);
 153
 154extern void rt_mutex_futex_unlock(struct rt_mutex *lock);
 155extern bool __rt_mutex_futex_unlock(struct rt_mutex *lock,
 156                                 struct wake_q_head *wqh);
 157
 158extern 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
 167