aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/locking/rtmutex.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/locking/rtmutex.c')
-rw-r--r--kernel/locking/rtmutex.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c
index 00b49cdbb4e0..c6eda049ef9f 100644
--- a/kernel/locking/rtmutex.c
+++ b/kernel/locking/rtmutex.c
@@ -238,8 +238,7 @@ rt_mutex_waiter_less(struct rt_mutex_waiter *left,
238 * then right waiter has a dl_prio() too. 238 * then right waiter has a dl_prio() too.
239 */ 239 */
240 if (dl_prio(left->prio)) 240 if (dl_prio(left->prio))
241 return dl_time_before(left->task->dl.deadline, 241 return dl_time_before(left->deadline, right->deadline);
242 right->task->dl.deadline);
243 242
244 return 0; 243 return 0;
245} 244}
@@ -650,7 +649,26 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task,
650 649
651 /* [7] Requeue the waiter in the lock waiter tree. */ 650 /* [7] Requeue the waiter in the lock waiter tree. */
652 rt_mutex_dequeue(lock, waiter); 651 rt_mutex_dequeue(lock, waiter);
652
653 /*
654 * Update the waiter prio fields now that we're dequeued.
655 *
656 * These values can have changed through either:
657 *
658 * sys_sched_set_scheduler() / sys_sched_setattr()
659 *
660 * or
661 *
662 * DL CBS enforcement advancing the effective deadline.
663 *
664 * Even though pi_waiters also uses these fields, and that tree is only
665 * updated in [11], we can do this here, since we hold [L], which
666 * serializes all pi_waiters access and rb_erase() does not care about
667 * the values of the node being removed.
668 */
653 waiter->prio = task->prio; 669 waiter->prio = task->prio;
670 waiter->deadline = task->dl.deadline;
671
654 rt_mutex_enqueue(lock, waiter); 672 rt_mutex_enqueue(lock, waiter);
655 673
656 /* [8] Release the task */ 674 /* [8] Release the task */
@@ -777,6 +795,8 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task,
777static int try_to_take_rt_mutex(struct rt_mutex *lock, struct task_struct *task, 795static int try_to_take_rt_mutex(struct rt_mutex *lock, struct task_struct *task,
778 struct rt_mutex_waiter *waiter) 796 struct rt_mutex_waiter *waiter)
779{ 797{
798 lockdep_assert_held(&lock->wait_lock);
799
780 /* 800 /*
781 * Before testing whether we can acquire @lock, we set the 801 * Before testing whether we can acquire @lock, we set the
782 * RT_MUTEX_HAS_WAITERS bit in @lock->owner. This forces all 802 * RT_MUTEX_HAS_WAITERS bit in @lock->owner. This forces all
@@ -902,6 +922,8 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock,
902 struct rt_mutex *next_lock; 922 struct rt_mutex *next_lock;
903 int chain_walk = 0, res; 923 int chain_walk = 0, res;
904 924
925 lockdep_assert_held(&lock->wait_lock);
926
905 /* 927 /*
906 * Early deadlock detection. We really don't want the task to 928 * Early deadlock detection. We really don't want the task to
907 * enqueue on itself just to untangle the mess later. It's not 929 * enqueue on itself just to untangle the mess later. It's not
@@ -919,6 +941,7 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock,
919 waiter->task = task; 941 waiter->task = task;
920 waiter->lock = lock; 942 waiter->lock = lock;
921 waiter->prio = task->prio; 943 waiter->prio = task->prio;
944 waiter->deadline = task->dl.deadline;
922 945
923 /* Get the top priority waiter on the lock */ 946 /* Get the top priority waiter on the lock */
924 if (rt_mutex_has_waiters(lock)) 947 if (rt_mutex_has_waiters(lock))
@@ -1036,6 +1059,8 @@ static void remove_waiter(struct rt_mutex *lock,
1036 struct task_struct *owner = rt_mutex_owner(lock); 1059 struct task_struct *owner = rt_mutex_owner(lock);
1037 struct rt_mutex *next_lock; 1060 struct rt_mutex *next_lock;
1038 1061
1062 lockdep_assert_held(&lock->wait_lock);
1063
1039 raw_spin_lock(&current->pi_lock); 1064 raw_spin_lock(&current->pi_lock);
1040 rt_mutex_dequeue(lock, waiter); 1065 rt_mutex_dequeue(lock, waiter);
1041 current->pi_blocked_on = NULL; 1066 current->pi_blocked_on = NULL;