The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kernel/rtmutex-debug.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * RT-Mutexes: blocking mutual exclusion locks with PI support
    3  *
    4  * started by Ingo Molnar and Thomas Gleixner:
    5  *
    6  *  Copyright (C) 2004-2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
    7  *  Copyright (C) 2006 Timesys Corp., Thomas Gleixner <tglx@timesys.com>
    8  *
    9  * This code is based on the rt.c implementation in the preempt-rt tree.
   10  * Portions of said code are
   11  *
   12  *  Copyright (C) 2004  LynuxWorks, Inc., Igor Manyilov, Bill Huey
   13  *  Copyright (C) 2006  Esben Nielsen
   14  *  Copyright (C) 2006  Kihon Technologies Inc.,
   15  *                      Steven Rostedt <rostedt@goodmis.org>
   16  *
   17  * See rt.c in preempt-rt for proper credits and further information
   18  */
   19 #include <linux/sched.h>
   20 #include <linux/delay.h>
   21 #include <linux/export.h>
   22 #include <linux/spinlock.h>
   23 #include <linux/kallsyms.h>
   24 #include <linux/syscalls.h>
   25 #include <linux/interrupt.h>
   26 #include <linux/plist.h>
   27 #include <linux/fs.h>
   28 #include <linux/debug_locks.h>
   29 
   30 #include "rtmutex_common.h"
   31 
   32 static void printk_task(struct task_struct *p)
   33 {
   34         if (p)
   35                 printk("%16s:%5d [%p, %3d]", p->comm, task_pid_nr(p), p, p->prio);
   36         else
   37                 printk("<none>");
   38 }
   39 
   40 static void printk_lock(struct rt_mutex *lock, int print_owner)
   41 {
   42         if (lock->name)
   43                 printk(" [%p] {%s}\n",
   44                         lock, lock->name);
   45         else
   46                 printk(" [%p] {%s:%d}\n",
   47                         lock, lock->file, lock->line);
   48 
   49         if (print_owner && rt_mutex_owner(lock)) {
   50                 printk(".. ->owner: %p\n", lock->owner);
   51                 printk(".. held by:  ");
   52                 printk_task(rt_mutex_owner(lock));
   53                 printk("\n");
   54         }
   55 }
   56 
   57 void rt_mutex_debug_task_free(struct task_struct *task)
   58 {
   59         DEBUG_LOCKS_WARN_ON(!plist_head_empty(&task->pi_waiters));
   60         DEBUG_LOCKS_WARN_ON(task->pi_blocked_on);
   61 }
   62 
   63 /*
   64  * We fill out the fields in the waiter to store the information about
   65  * the deadlock. We print when we return. act_waiter can be NULL in
   66  * case of a remove waiter operation.
   67  */
   68 void debug_rt_mutex_deadlock(int detect, struct rt_mutex_waiter *act_waiter,
   69                              struct rt_mutex *lock)
   70 {
   71         struct task_struct *task;
   72 
   73         if (!debug_locks || detect || !act_waiter)
   74                 return;
   75 
   76         task = rt_mutex_owner(act_waiter->lock);
   77         if (task && task != current) {
   78                 act_waiter->deadlock_task_pid = get_pid(task_pid(task));
   79                 act_waiter->deadlock_lock = lock;
   80         }
   81 }
   82 
   83 void debug_rt_mutex_print_deadlock(struct rt_mutex_waiter *waiter)
   84 {
   85         struct task_struct *task;
   86 
   87         if (!waiter->deadlock_lock || !debug_locks)
   88                 return;
   89 
   90         rcu_read_lock();
   91         task = pid_task(waiter->deadlock_task_pid, PIDTYPE_PID);
   92         if (!task) {
   93                 rcu_read_unlock();
   94                 return;
   95         }
   96 
   97         if (!debug_locks_off()) {
   98                 rcu_read_unlock();
   99                 return;
  100         }
  101 
  102         printk("\n============================================\n");
  103         printk(  "[ BUG: circular locking deadlock detected! ]\n");
  104         printk("%s\n", print_tainted());
  105         printk(  "--------------------------------------------\n");
  106         printk("%s/%d is deadlocking current task %s/%d\n\n",
  107                task->comm, task_pid_nr(task),
  108                current->comm, task_pid_nr(current));
  109 
  110         printk("\n1) %s/%d is trying to acquire this lock:\n",
  111                current->comm, task_pid_nr(current));
  112         printk_lock(waiter->lock, 1);
  113 
  114         printk("\n2) %s/%d is blocked on this lock:\n",
  115                 task->comm, task_pid_nr(task));
  116         printk_lock(waiter->deadlock_lock, 1);
  117 
  118         debug_show_held_locks(current);
  119         debug_show_held_locks(task);
  120 
  121         printk("\n%s/%d's [blocked] stackdump:\n\n",
  122                 task->comm, task_pid_nr(task));
  123         show_stack(task, NULL);
  124         printk("\n%s/%d's [current] stackdump:\n\n",
  125                 current->comm, task_pid_nr(current));
  126         dump_stack();
  127         debug_show_all_locks();
  128         rcu_read_unlock();
  129 
  130         printk("[ turning off deadlock detection."
  131                "Please report this trace. ]\n\n");
  132 }
  133 
  134 void debug_rt_mutex_lock(struct rt_mutex *lock)
  135 {
  136 }
  137 
  138 void debug_rt_mutex_unlock(struct rt_mutex *lock)
  139 {
  140         DEBUG_LOCKS_WARN_ON(rt_mutex_owner(lock) != current);
  141 }
  142 
  143 void
  144 debug_rt_mutex_proxy_lock(struct rt_mutex *lock, struct task_struct *powner)
  145 {
  146 }
  147 
  148 void debug_rt_mutex_proxy_unlock(struct rt_mutex *lock)
  149 {
  150         DEBUG_LOCKS_WARN_ON(!rt_mutex_owner(lock));
  151 }
  152 
  153 void debug_rt_mutex_init_waiter(struct rt_mutex_waiter *waiter)
  154 {
  155         memset(waiter, 0x11, sizeof(*waiter));
  156         plist_node_init(&waiter->list_entry, MAX_PRIO);
  157         plist_node_init(&waiter->pi_list_entry, MAX_PRIO);
  158         waiter->deadlock_task_pid = NULL;
  159 }
  160 
  161 void debug_rt_mutex_free_waiter(struct rt_mutex_waiter *waiter)
  162 {
  163         put_pid(waiter->deadlock_task_pid);
  164         DEBUG_LOCKS_WARN_ON(!plist_node_empty(&waiter->list_entry));
  165         DEBUG_LOCKS_WARN_ON(!plist_node_empty(&waiter->pi_list_entry));
  166         memset(waiter, 0x22, sizeof(*waiter));
  167 }
  168 
  169 void debug_rt_mutex_init(struct rt_mutex *lock, const char *name)
  170 {
  171         /*
  172          * Make sure we are not reinitializing a held lock:
  173          */
  174         debug_check_no_locks_freed((void *)lock, sizeof(*lock));
  175         lock->name = name;
  176 }
  177 
  178 void
  179 rt_mutex_deadlock_account_lock(struct rt_mutex *lock, struct task_struct *task)
  180 {
  181 }
  182 
  183 void rt_mutex_deadlock_account_unlock(struct task_struct *task)
  184 {
  185 }
  186 

Cache object: ca950ed3fcab2c37c5f99a05701f481f


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.