aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/rtmutex.c51
1 files changed, 25 insertions, 26 deletions
diff --git a/kernel/rtmutex.c b/kernel/rtmutex.c
index 3e13a1e5856f..4ab17da46fd8 100644
--- a/kernel/rtmutex.c
+++ b/kernel/rtmutex.c
@@ -251,6 +251,7 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task,
251 251
252 /* Grab the next task */ 252 /* Grab the next task */
253 task = rt_mutex_owner(lock); 253 task = rt_mutex_owner(lock);
254 get_task_struct(task);
254 spin_lock_irqsave(&task->pi_lock, flags); 255 spin_lock_irqsave(&task->pi_lock, flags);
255 256
256 if (waiter == rt_mutex_top_waiter(lock)) { 257 if (waiter == rt_mutex_top_waiter(lock)) {
@@ -269,7 +270,6 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task,
269 __rt_mutex_adjust_prio(task); 270 __rt_mutex_adjust_prio(task);
270 } 271 }
271 272
272 get_task_struct(task);
273 spin_unlock_irqrestore(&task->pi_lock, flags); 273 spin_unlock_irqrestore(&task->pi_lock, flags);
274 274
275 top_waiter = rt_mutex_top_waiter(lock); 275 top_waiter = rt_mutex_top_waiter(lock);
@@ -409,7 +409,7 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock,
409 struct task_struct *owner = rt_mutex_owner(lock); 409 struct task_struct *owner = rt_mutex_owner(lock);
410 struct rt_mutex_waiter *top_waiter = waiter; 410 struct rt_mutex_waiter *top_waiter = waiter;
411 unsigned long flags; 411 unsigned long flags;
412 int boost = 0, res; 412 int chain_walk = 0, res;
413 413
414 spin_lock_irqsave(&current->pi_lock, flags); 414 spin_lock_irqsave(&current->pi_lock, flags);
415 __rt_mutex_adjust_prio(current); 415 __rt_mutex_adjust_prio(current);
@@ -433,25 +433,23 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock,
433 plist_add(&waiter->pi_list_entry, &owner->pi_waiters); 433 plist_add(&waiter->pi_list_entry, &owner->pi_waiters);
434 434
435 __rt_mutex_adjust_prio(owner); 435 __rt_mutex_adjust_prio(owner);
436 if (owner->pi_blocked_on) { 436 if (owner->pi_blocked_on)
437 boost = 1; 437 chain_walk = 1;
438 /* gets dropped in rt_mutex_adjust_prio_chain()! */
439 get_task_struct(owner);
440 }
441 spin_unlock_irqrestore(&owner->pi_lock, flags);
442 }
443 else if (debug_rt_mutex_detect_deadlock(waiter, detect_deadlock)) {
444 spin_lock_irqsave(&owner->pi_lock, flags);
445 if (owner->pi_blocked_on) {
446 boost = 1;
447 /* gets dropped in rt_mutex_adjust_prio_chain()! */
448 get_task_struct(owner);
449 }
450 spin_unlock_irqrestore(&owner->pi_lock, flags); 438 spin_unlock_irqrestore(&owner->pi_lock, flags);
451 } 439 }
452 if (!boost) 440 else if (debug_rt_mutex_detect_deadlock(waiter, detect_deadlock))
441 chain_walk = 1;
442
443 if (!chain_walk)
453 return 0; 444 return 0;
454 445
446 /*
447 * The owner can't disappear while holding a lock,
448 * so the owner struct is protected by wait_lock.
449 * Gets dropped in rt_mutex_adjust_prio_chain()!
450 */
451 get_task_struct(owner);
452
455 spin_unlock(&lock->wait_lock); 453 spin_unlock(&lock->wait_lock);
456 454
457 res = rt_mutex_adjust_prio_chain(owner, detect_deadlock, lock, waiter, 455 res = rt_mutex_adjust_prio_chain(owner, detect_deadlock, lock, waiter,
@@ -532,7 +530,7 @@ static void remove_waiter(struct rt_mutex *lock,
532 int first = (waiter == rt_mutex_top_waiter(lock)); 530 int first = (waiter == rt_mutex_top_waiter(lock));
533 struct task_struct *owner = rt_mutex_owner(lock); 531 struct task_struct *owner = rt_mutex_owner(lock);
534 unsigned long flags; 532 unsigned long flags;
535 int boost = 0; 533 int chain_walk = 0;
536 534
537 spin_lock_irqsave(&current->pi_lock, flags); 535 spin_lock_irqsave(&current->pi_lock, flags);
538 plist_del(&waiter->list_entry, &lock->wait_list); 536 plist_del(&waiter->list_entry, &lock->wait_list);
@@ -554,19 +552,20 @@ static void remove_waiter(struct rt_mutex *lock,
554 } 552 }
555 __rt_mutex_adjust_prio(owner); 553 __rt_mutex_adjust_prio(owner);
556 554
557 if (owner->pi_blocked_on) { 555 if (owner->pi_blocked_on)
558 boost = 1; 556 chain_walk = 1;
559 /* gets dropped in rt_mutex_adjust_prio_chain()! */ 557
560 get_task_struct(owner);
561 }
562 spin_unlock_irqrestore(&owner->pi_lock, flags); 558 spin_unlock_irqrestore(&owner->pi_lock, flags);
563 } 559 }
564 560
565 WARN_ON(!plist_node_empty(&waiter->pi_list_entry)); 561 WARN_ON(!plist_node_empty(&waiter->pi_list_entry));
566 562
567 if (!boost) 563 if (!chain_walk)
568 return; 564 return;
569 565
566 /* gets dropped in rt_mutex_adjust_prio_chain()! */
567 get_task_struct(owner);
568
570 spin_unlock(&lock->wait_lock); 569 spin_unlock(&lock->wait_lock);
571 570
572 rt_mutex_adjust_prio_chain(owner, 0, lock, NULL, current); 571 rt_mutex_adjust_prio_chain(owner, 0, lock, NULL, current);
@@ -592,10 +591,10 @@ void rt_mutex_adjust_pi(struct task_struct *task)
592 return; 591 return;
593 } 592 }
594 593
595 /* gets dropped in rt_mutex_adjust_prio_chain()! */
596 get_task_struct(task);
597 spin_unlock_irqrestore(&task->pi_lock, flags); 594 spin_unlock_irqrestore(&task->pi_lock, flags);
598 595
596 /* gets dropped in rt_mutex_adjust_prio_chain()! */
597 get_task_struct(task);
599 rt_mutex_adjust_prio_chain(task, 0, NULL, NULL, task); 598 rt_mutex_adjust_prio_chain(task, 0, NULL, NULL, task);
600} 599}
601 600