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 rt_mutex_waiter *w;
  56
  57        w = rb_entry(lock->waiters.rb_leftmost,
  58                     struct rt_mutex_waiter, tree_entry);
  59        BUG_ON(w->lock != lock);
  60
  61        return w;
  62}
  63
  64static inline int task_has_pi_waiters(struct task_struct *p)
  65{
  66        return !RB_EMPTY_ROOT(&p->pi_waiters.rb_root);
  67}
  68
  69static inline struct rt_mutex_waiter *
  70task_top_pi_waiter(struct task_struct *p)
  71{
  72        return rb_entry(p->pi_waiters.rb_leftmost,
  73                        struct rt_mutex_waiter, pi_tree_entry);
  74}
  75
  76#else
  77
  78static inline int rt_mutex_has_waiters(struct rt_mutex *lock)
  79{
  80        return false;
  81}
  82
  83static inline struct rt_mutex_waiter *
  84rt_mutex_top_waiter(struct rt_mutex *lock)
  85{
  86        return NULL;
  87}
  88
  89static inline int task_has_pi_waiters(struct task_struct *p)
  90{
  91        return false;
  92}
  93
  94static inline struct rt_mutex_waiter *
  95task_top_pi_waiter(struct task_struct *p)
  96{
  97        return NULL;
  98}
  99
 100#endif
 101
 102/*
 103 * lock->owner state tracking:
 104 */
 105#define RT_MUTEX_HAS_WAITERS    1UL
 106
 107static inline struct task_struct *rt_mutex_owner(struct rt_mutex *lock)
 108{
 109        unsigned long owner = (unsigned long) READ_ONCE(lock->owner);
 110
 111        return (struct task_struct *) (owner & ~RT_MUTEX_HAS_WAITERS);
 112}
 113
 114/*
 115 * Constants for rt mutex functions which have a selectable deadlock
 116 * detection.
 117 *
 118 * RT_MUTEX_MIN_CHAINWALK:      Stops the lock chain walk when there are
 119 *                              no further PI adjustments to be made.
 120 *
 121 * RT_MUTEX_FULL_CHAINWALK:     Invoke deadlock detection with a full
 122 *                              walk of the lock chain.
 123 */
 124enum rtmutex_chainwalk {
 125        RT_MUTEX_MIN_CHAINWALK,
 126        RT_MUTEX_FULL_CHAINWALK,
 127};
 128
 129/*
 130 * PI-futex support (proxy locking functions, etc.):
 131 */
 132extern struct task_struct *rt_mutex_next_owner(struct rt_mutex *lock);
 133extern void rt_mutex_init_proxy_locked(struct rt_mutex *lock,
 134                                       struct task_struct *proxy_owner);
 135extern void rt_mutex_proxy_unlock(struct rt_mutex *lock,
 136                                  struct task_struct *proxy_owner);
 137extern void rt_mutex_init_waiter(struct rt_mutex_waiter *waiter);
 138extern int __rt_mutex_start_proxy_lock(struct rt_mutex *lock,
 139                                     struct rt_mutex_waiter *waiter,
 140                                     struct task_struct *task);
 141extern int rt_mutex_start_proxy_lock(struct rt_mutex *lock,
 142                                     struct rt_mutex_waiter *waiter,
 143                                     struct task_struct *task);
 144extern int rt_mutex_wait_proxy_lock(struct rt_mutex *lock,
 145                               struct hrtimer_sleeper *to,
 146                               struct rt_mutex_waiter *waiter);
 147extern bool rt_mutex_cleanup_proxy_lock(struct rt_mutex *lock,
 148                                 struct rt_mutex_waiter *waiter);
 149
 150extern int rt_mutex_futex_trylock(struct rt_mutex *l);
 151extern int __rt_mutex_futex_trylock(struct rt_mutex *l);
 152
 153extern void rt_mutex_futex_unlock(struct rt_mutex *lock);
 154extern bool __rt_mutex_futex_unlock(struct rt_mutex *lock,
 155                                 struct wake_q_head *wqh);
 156
 157extern void rt_mutex_postunlock(struct wake_q_head *wake_q);
 158
 159#ifdef CONFIG_DEBUG_RT_MUTEXES
 160# include "rtmutex-debug.h"
 161#else
 162# include "rtmutex.h"
 163#endif
 164
 165#endif
 166