[PATCH] hrtimers: namespace and enum cleanup
[safe/jmp/linux-2.6] / kernel / rtmutex.c
index 91b699a..180978c 100644 (file)
@@ -7,6 +7,8 @@
  *  Copyright (C) 2005-2006 Timesys Corp., Thomas Gleixner <tglx@timesys.com>
  *  Copyright (C) 2005 Kihon Technologies Inc., Steven Rostedt
  *  Copyright (C) 2006 Esben Nielsen
+ *
+ *  See Documentation/rt-mutex-design.txt for details.
  */
 #include <linux/spinlock.h>
 #include <linux/module.h>
@@ -157,7 +159,7 @@ int max_lock_depth = 1024;
  * Decreases task's usage by one - may thus free the task.
  * Returns 0 or -EDEADLK.
  */
-static int rt_mutex_adjust_prio_chain(task_t *task,
+static int rt_mutex_adjust_prio_chain(struct task_struct *task,
                                      int deadlock_detect,
                                      struct rt_mutex *orig_lock,
                                      struct rt_mutex_waiter *orig_waiter,
@@ -249,6 +251,7 @@ static int rt_mutex_adjust_prio_chain(task_t *task,
 
        /* Grab the next task */
        task = rt_mutex_owner(lock);
+       get_task_struct(task);
        spin_lock_irqsave(&task->pi_lock, flags);
 
        if (waiter == rt_mutex_top_waiter(lock)) {
@@ -267,7 +270,6 @@ static int rt_mutex_adjust_prio_chain(task_t *task,
                __rt_mutex_adjust_prio(task);
        }
 
-       get_task_struct(task);
        spin_unlock_irqrestore(&task->pi_lock, flags);
 
        top_waiter = rt_mutex_top_waiter(lock);
@@ -282,6 +284,7 @@ static int rt_mutex_adjust_prio_chain(task_t *task,
        spin_unlock_irqrestore(&task->pi_lock, flags);
  out_put_task:
        put_task_struct(task);
+
        return ret;
 }
 
@@ -403,10 +406,10 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock,
                                   struct rt_mutex_waiter *waiter,
                                   int detect_deadlock)
 {
+       struct task_struct *owner = rt_mutex_owner(lock);
        struct rt_mutex_waiter *top_waiter = waiter;
-       task_t *owner = rt_mutex_owner(lock);
-       int boost = 0, res;
        unsigned long flags;
+       int chain_walk = 0, res;
 
        spin_lock_irqsave(&current->pi_lock, flags);
        __rt_mutex_adjust_prio(current);
@@ -430,25 +433,23 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock,
                plist_add(&waiter->pi_list_entry, &owner->pi_waiters);
 
                __rt_mutex_adjust_prio(owner);
-               if (owner->pi_blocked_on) {
-                       boost = 1;
-                       /* gets dropped in rt_mutex_adjust_prio_chain()! */
-                       get_task_struct(owner);
-               }
+               if (owner->pi_blocked_on)
+                       chain_walk = 1;
                spin_unlock_irqrestore(&owner->pi_lock, flags);
        }
-       else if (debug_rt_mutex_detect_deadlock(waiter, detect_deadlock)) {
-               spin_lock_irqsave(&owner->pi_lock, flags);
-               if (owner->pi_blocked_on) {
-                       boost = 1;
-                       /* gets dropped in rt_mutex_adjust_prio_chain()! */
-                       get_task_struct(owner);
-               }
-               spin_unlock_irqrestore(&owner->pi_lock, flags);
-       }
-       if (!boost)
+       else if (debug_rt_mutex_detect_deadlock(waiter, detect_deadlock))
+               chain_walk = 1;
+
+       if (!chain_walk)
                return 0;
 
+       /*
+        * The owner can't disappear while holding a lock,
+        * so the owner struct is protected by wait_lock.
+        * Gets dropped in rt_mutex_adjust_prio_chain()!
+        */
+       get_task_struct(owner);
+
        spin_unlock(&lock->wait_lock);
 
        res = rt_mutex_adjust_prio_chain(owner, detect_deadlock, lock, waiter,
@@ -527,9 +528,9 @@ static void remove_waiter(struct rt_mutex *lock,
                          struct rt_mutex_waiter *waiter)
 {
        int first = (waiter == rt_mutex_top_waiter(lock));
-       int boost = 0;
-       task_t *owner = rt_mutex_owner(lock);
+       struct task_struct *owner = rt_mutex_owner(lock);
        unsigned long flags;
+       int chain_walk = 0;
 
        spin_lock_irqsave(&current->pi_lock, flags);
        plist_del(&waiter->list_entry, &lock->wait_list);
@@ -551,19 +552,20 @@ static void remove_waiter(struct rt_mutex *lock,
                }
                __rt_mutex_adjust_prio(owner);
 
-               if (owner->pi_blocked_on) {
-                       boost = 1;
-                       /* gets dropped in rt_mutex_adjust_prio_chain()! */
-                       get_task_struct(owner);
-               }
+               if (owner->pi_blocked_on)
+                       chain_walk = 1;
+
                spin_unlock_irqrestore(&owner->pi_lock, flags);
        }
 
        WARN_ON(!plist_node_empty(&waiter->pi_list_entry));
 
-       if (!boost)
+       if (!chain_walk)
                return;
 
+       /* gets dropped in rt_mutex_adjust_prio_chain()! */
+       get_task_struct(owner);
+
        spin_unlock(&lock->wait_lock);
 
        rt_mutex_adjust_prio_chain(owner, 0, lock, NULL, current);
@@ -589,10 +591,10 @@ void rt_mutex_adjust_pi(struct task_struct *task)
                return;
        }
 
-       /* gets dropped in rt_mutex_adjust_prio_chain()! */
-       get_task_struct(task);
        spin_unlock_irqrestore(&task->pi_lock, flags);
 
+       /* gets dropped in rt_mutex_adjust_prio_chain()! */
+       get_task_struct(task);
        rt_mutex_adjust_prio_chain(task, 0, NULL, NULL, task);
 }
 
@@ -623,7 +625,7 @@ rt_mutex_slowlock(struct rt_mutex *lock, int state,
        /* Setup the timer, when timeout != NULL */
        if (unlikely(timeout))
                hrtimer_start(&timeout->timer, timeout->timer.expires,
-                             HRTIMER_ABS);
+                             HRTIMER_MODE_ABS);
 
        for (;;) {
                /* Try to acquire the lock: */