aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/locking/rtmutex.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2014-05-21 23:25:54 -0400
committerThomas Gleixner <tglx@linutronix.de>2014-06-21 16:05:30 -0400
commita57594a13a446d1a6ab1dcd48339f799ce586843 (patch)
treea68374df7f7de66edce42f10ba014de8a0286f73 /kernel/locking/rtmutex.c
parent2ffa5a5cd2fe792b6399c903d5172adf088d8ff7 (diff)
rtmutex: Clarify the boost/deboost part
Add a separate local variable for the boost/deboost logic to make the code more readable. Add comments where appropriate. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/locking/rtmutex.c')
-rw-r--r--kernel/locking/rtmutex.c58
1 files changed, 48 insertions, 10 deletions
diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c
index cd517091fb21..3e9a75991e83 100644
--- a/kernel/locking/rtmutex.c
+++ b/kernel/locking/rtmutex.c
@@ -345,9 +345,10 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task,
345 struct rt_mutex_waiter *orig_waiter, 345 struct rt_mutex_waiter *orig_waiter,
346 struct task_struct *top_task) 346 struct task_struct *top_task)
347{ 347{
348 struct rt_mutex *lock;
349 struct rt_mutex_waiter *waiter, *top_waiter = orig_waiter; 348 struct rt_mutex_waiter *waiter, *top_waiter = orig_waiter;
349 struct rt_mutex_waiter *prerequeue_top_waiter;
350 int detect_deadlock, ret = 0, depth = 0; 350 int detect_deadlock, ret = 0, depth = 0;
351 struct rt_mutex *lock;
351 unsigned long flags; 352 unsigned long flags;
352 353
353 detect_deadlock = debug_rt_mutex_detect_deadlock(orig_waiter, 354 detect_deadlock = debug_rt_mutex_detect_deadlock(orig_waiter,
@@ -454,9 +455,14 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task,
454 goto out_unlock_pi; 455 goto out_unlock_pi;
455 } 456 }
456 457
457 top_waiter = rt_mutex_top_waiter(lock); 458 /*
459 * Store the current top waiter before doing the requeue
460 * operation on @lock. We need it for the boost/deboost
461 * decision below.
462 */
463 prerequeue_top_waiter = rt_mutex_top_waiter(lock);
458 464
459 /* Requeue the waiter */ 465 /* Requeue the waiter in the lock waiter list. */
460 rt_mutex_dequeue(lock, waiter); 466 rt_mutex_dequeue(lock, waiter);
461 waiter->prio = task->prio; 467 waiter->prio = task->prio;
462 rt_mutex_enqueue(lock, waiter); 468 rt_mutex_enqueue(lock, waiter);
@@ -465,35 +471,58 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task,
465 raw_spin_unlock_irqrestore(&task->pi_lock, flags); 471 raw_spin_unlock_irqrestore(&task->pi_lock, flags);
466 put_task_struct(task); 472 put_task_struct(task);
467 473
474 /*
475 * We must abort the chain walk if there is no lock owner even
476 * in the dead lock detection case, as we have nothing to
477 * follow here. This is the end of the chain we are walking.
478 */
468 if (!rt_mutex_owner(lock)) { 479 if (!rt_mutex_owner(lock)) {
469 /* 480 /*
470 * If the requeue above changed the top waiter, then we need 481 * If the requeue above changed the top waiter, then we need
471 * to wake the new top waiter up to try to get the lock. 482 * to wake the new top waiter up to try to get the lock.
472 */ 483 */
473 484 if (prerequeue_top_waiter != rt_mutex_top_waiter(lock))
474 if (top_waiter != rt_mutex_top_waiter(lock))
475 wake_up_process(rt_mutex_top_waiter(lock)->task); 485 wake_up_process(rt_mutex_top_waiter(lock)->task);
476 raw_spin_unlock(&lock->wait_lock); 486 raw_spin_unlock(&lock->wait_lock);
477 return 0; 487 return 0;
478 } 488 }
479 489
480 /* Grab the next task */ 490 /* Grab the next task, i.e. the owner of @lock */
481 task = rt_mutex_owner(lock); 491 task = rt_mutex_owner(lock);
482 get_task_struct(task); 492 get_task_struct(task);
483 raw_spin_lock_irqsave(&task->pi_lock, flags); 493 raw_spin_lock_irqsave(&task->pi_lock, flags);
484 494
485 if (waiter == rt_mutex_top_waiter(lock)) { 495 if (waiter == rt_mutex_top_waiter(lock)) {
486 /* Boost the owner */ 496 /*
487 rt_mutex_dequeue_pi(task, top_waiter); 497 * The waiter became the new top (highest priority)
498 * waiter on the lock. Replace the previous top waiter
499 * in the owner tasks pi waiters list with this waiter
500 * and adjust the priority of the owner.
501 */
502 rt_mutex_dequeue_pi(task, prerequeue_top_waiter);
488 rt_mutex_enqueue_pi(task, waiter); 503 rt_mutex_enqueue_pi(task, waiter);
489 __rt_mutex_adjust_prio(task); 504 __rt_mutex_adjust_prio(task);
490 505
491 } else if (top_waiter == waiter) { 506 } else if (prerequeue_top_waiter == waiter) {
492 /* Deboost the owner */ 507 /*
508 * The waiter was the top waiter on the lock, but is
509 * no longer the top prority waiter. Replace waiter in
510 * the owner tasks pi waiters list with the new top
511 * (highest priority) waiter and adjust the priority
512 * of the owner.
513 * The new top waiter is stored in @waiter so that
514 * @waiter == @top_waiter evaluates to true below and
515 * we continue to deboost the rest of the chain.
516 */
493 rt_mutex_dequeue_pi(task, waiter); 517 rt_mutex_dequeue_pi(task, waiter);
494 waiter = rt_mutex_top_waiter(lock); 518 waiter = rt_mutex_top_waiter(lock);
495 rt_mutex_enqueue_pi(task, waiter); 519 rt_mutex_enqueue_pi(task, waiter);
496 __rt_mutex_adjust_prio(task); 520 __rt_mutex_adjust_prio(task);
521 } else {
522 /*
523 * Nothing changed. No need to do any priority
524 * adjustment.
525 */
497 } 526 }
498 527
499 /* 528 /*
@@ -506,6 +535,10 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task,
506 535
507 raw_spin_unlock_irqrestore(&task->pi_lock, flags); 536 raw_spin_unlock_irqrestore(&task->pi_lock, flags);
508 537
538 /*
539 * Store the top waiter of @lock for the end of chain walk
540 * decision below.
541 */
509 top_waiter = rt_mutex_top_waiter(lock); 542 top_waiter = rt_mutex_top_waiter(lock);
510 raw_spin_unlock(&lock->wait_lock); 543 raw_spin_unlock(&lock->wait_lock);
511 544
@@ -516,6 +549,11 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task,
516 if (!next_lock) 549 if (!next_lock)
517 goto out_put_task; 550 goto out_put_task;
518 551
552 /*
553 * If the current waiter is not the top waiter on the lock,
554 * then we can stop the chain walk here if we are not in full
555 * deadlock detection mode.
556 */
519 if (!detect_deadlock && waiter != top_waiter) 557 if (!detect_deadlock && waiter != top_waiter)
520 goto out_put_task; 558 goto out_put_task;
521 559