diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2014-06-09 13:40:34 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2014-06-21 16:05:30 -0400 |
commit | 3eb65aeadf701976b084e9171e16bb7d1e83fbb0 (patch) | |
tree | 705c76a9057f352a84e0d4b0d367e80ffc691e66 /kernel/locking | |
parent | a57594a13a446d1a6ab1dcd48339f799ce586843 (diff) |
rtmutex: Document pi chain walk
Add commentry to document the chain walk and the protection mechanisms
and their scope.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/locking')
-rw-r--r-- | kernel/locking/rtmutex.c | 100 |
1 files changed, 91 insertions, 9 deletions
diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c index 3e9a75991e83..ed88021953df 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c | |||
@@ -337,6 +337,48 @@ static inline struct rt_mutex *task_blocked_on_lock(struct task_struct *p) | |||
337 | * @top_task: the current top waiter | 337 | * @top_task: the current top waiter |
338 | * | 338 | * |
339 | * Returns 0 or -EDEADLK. | 339 | * Returns 0 or -EDEADLK. |
340 | * | ||
341 | * Chain walk basics and protection scope | ||
342 | * | ||
343 | * [R] refcount on task | ||
344 | * [P] task->pi_lock held | ||
345 | * [L] rtmutex->wait_lock held | ||
346 | * | ||
347 | * Step Description Protected by | ||
348 | * function arguments: | ||
349 | * @task [R] | ||
350 | * @orig_lock if != NULL @top_task is blocked on it | ||
351 | * @next_lock Unprotected. Cannot be | ||
352 | * dereferenced. Only used for | ||
353 | * comparison. | ||
354 | * @orig_waiter if != NULL @top_task is blocked on it | ||
355 | * @top_task current, or in case of proxy | ||
356 | * locking protected by calling | ||
357 | * code | ||
358 | * again: | ||
359 | * loop_sanity_check(); | ||
360 | * retry: | ||
361 | * [1] lock(task->pi_lock); [R] acquire [P] | ||
362 | * [2] waiter = task->pi_blocked_on; [P] | ||
363 | * [3] check_exit_conditions_1(); [P] | ||
364 | * [4] lock = waiter->lock; [P] | ||
365 | * [5] if (!try_lock(lock->wait_lock)) { [P] try to acquire [L] | ||
366 | * unlock(task->pi_lock); release [P] | ||
367 | * goto retry; | ||
368 | * } | ||
369 | * [6] check_exit_conditions_2(); [P] + [L] | ||
370 | * [7] requeue_lock_waiter(lock, waiter); [P] + [L] | ||
371 | * [8] unlock(task->pi_lock); release [P] | ||
372 | * put_task_struct(task); release [R] | ||
373 | * [9] check_exit_conditions_3(); [L] | ||
374 | * [10] task = owner(lock); [L] | ||
375 | * get_task_struct(task); [L] acquire [R] | ||
376 | * lock(task->pi_lock); [L] acquire [P] | ||
377 | * [11] requeue_pi_waiter(tsk, waiters(lock));[P] + [L] | ||
378 | * [12] check_exit_conditions_4(); [P] + [L] | ||
379 | * [13] unlock(task->pi_lock); release [P] | ||
380 | * unlock(lock->wait_lock); release [L] | ||
381 | * goto again; | ||
340 | */ | 382 | */ |
341 | static int rt_mutex_adjust_prio_chain(struct task_struct *task, | 383 | static int rt_mutex_adjust_prio_chain(struct task_struct *task, |
342 | int deadlock_detect, | 384 | int deadlock_detect, |
@@ -361,6 +403,9 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task, | |||
361 | * carefully whether things change under us. | 403 | * carefully whether things change under us. |
362 | */ | 404 | */ |
363 | again: | 405 | again: |
406 | /* | ||
407 | * We limit the lock chain length for each invocation. | ||
408 | */ | ||
364 | if (++depth > max_lock_depth) { | 409 | if (++depth > max_lock_depth) { |
365 | static int prev_max; | 410 | static int prev_max; |
366 | 411 | ||
@@ -378,13 +423,28 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task, | |||
378 | 423 | ||
379 | return -EDEADLK; | 424 | return -EDEADLK; |
380 | } | 425 | } |
426 | |||
427 | /* | ||
428 | * We are fully preemptible here and only hold the refcount on | ||
429 | * @task. So everything can have changed under us since the | ||
430 | * caller or our own code below (goto retry/again) dropped all | ||
431 | * locks. | ||
432 | */ | ||
381 | retry: | 433 | retry: |
382 | /* | 434 | /* |
383 | * Task can not go away as we did a get_task() before ! | 435 | * [1] Task cannot go away as we did a get_task() before ! |
384 | */ | 436 | */ |
385 | raw_spin_lock_irqsave(&task->pi_lock, flags); | 437 | raw_spin_lock_irqsave(&task->pi_lock, flags); |
386 | 438 | ||
439 | /* | ||
440 | * [2] Get the waiter on which @task is blocked on. | ||
441 | */ | ||
387 | waiter = task->pi_blocked_on; | 442 | waiter = task->pi_blocked_on; |
443 | |||
444 | /* | ||
445 | * [3] check_exit_conditions_1() protected by task->pi_lock. | ||
446 | */ | ||
447 | |||
388 | /* | 448 | /* |
389 | * Check whether the end of the boosting chain has been | 449 | * Check whether the end of the boosting chain has been |
390 | * reached or the state of the chain has changed while we | 450 | * reached or the state of the chain has changed while we |
@@ -435,7 +495,15 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task, | |||
435 | if (!detect_deadlock && waiter->prio == task->prio) | 495 | if (!detect_deadlock && waiter->prio == task->prio) |
436 | goto out_unlock_pi; | 496 | goto out_unlock_pi; |
437 | 497 | ||
498 | /* | ||
499 | * [4] Get the next lock | ||
500 | */ | ||
438 | lock = waiter->lock; | 501 | lock = waiter->lock; |
502 | /* | ||
503 | * [5] We need to trylock here as we are holding task->pi_lock, | ||
504 | * which is the reverse lock order versus the other rtmutex | ||
505 | * operations. | ||
506 | */ | ||
439 | if (!raw_spin_trylock(&lock->wait_lock)) { | 507 | if (!raw_spin_trylock(&lock->wait_lock)) { |
440 | raw_spin_unlock_irqrestore(&task->pi_lock, flags); | 508 | raw_spin_unlock_irqrestore(&task->pi_lock, flags); |
441 | cpu_relax(); | 509 | cpu_relax(); |
@@ -443,6 +511,9 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task, | |||
443 | } | 511 | } |
444 | 512 | ||
445 | /* | 513 | /* |
514 | * [6] check_exit_conditions_2() protected by task->pi_lock and | ||
515 | * lock->wait_lock. | ||
516 | * | ||
446 | * Deadlock detection. If the lock is the same as the original | 517 | * Deadlock detection. If the lock is the same as the original |
447 | * lock which caused us to walk the lock chain or if the | 518 | * lock which caused us to walk the lock chain or if the |
448 | * current lock is owned by the task which initiated the chain | 519 | * current lock is owned by the task which initiated the chain |
@@ -462,24 +533,27 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task, | |||
462 | */ | 533 | */ |
463 | prerequeue_top_waiter = rt_mutex_top_waiter(lock); | 534 | prerequeue_top_waiter = rt_mutex_top_waiter(lock); |
464 | 535 | ||
465 | /* Requeue the waiter in the lock waiter list. */ | 536 | /* [7] Requeue the waiter in the lock waiter list. */ |
466 | rt_mutex_dequeue(lock, waiter); | 537 | rt_mutex_dequeue(lock, waiter); |
467 | waiter->prio = task->prio; | 538 | waiter->prio = task->prio; |
468 | rt_mutex_enqueue(lock, waiter); | 539 | rt_mutex_enqueue(lock, waiter); |
469 | 540 | ||
470 | /* Release the task */ | 541 | /* [8] Release the task */ |
471 | raw_spin_unlock_irqrestore(&task->pi_lock, flags); | 542 | raw_spin_unlock_irqrestore(&task->pi_lock, flags); |
472 | put_task_struct(task); | 543 | put_task_struct(task); |
473 | 544 | ||
474 | /* | 545 | /* |
546 | * [9] check_exit_conditions_3 protected by lock->wait_lock. | ||
547 | * | ||
475 | * We must abort the chain walk if there is no lock owner even | 548 | * 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 | 549 | * in the dead lock detection case, as we have nothing to |
477 | * follow here. This is the end of the chain we are walking. | 550 | * follow here. This is the end of the chain we are walking. |
478 | */ | 551 | */ |
479 | if (!rt_mutex_owner(lock)) { | 552 | if (!rt_mutex_owner(lock)) { |
480 | /* | 553 | /* |
481 | * If the requeue above changed the top waiter, then we need | 554 | * If the requeue [7] above changed the top waiter, |
482 | * to wake the new top waiter up to try to get the lock. | 555 | * then we need to wake the new top waiter up to try |
556 | * to get the lock. | ||
483 | */ | 557 | */ |
484 | if (prerequeue_top_waiter != rt_mutex_top_waiter(lock)) | 558 | if (prerequeue_top_waiter != rt_mutex_top_waiter(lock)) |
485 | wake_up_process(rt_mutex_top_waiter(lock)->task); | 559 | wake_up_process(rt_mutex_top_waiter(lock)->task); |
@@ -487,11 +561,12 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task, | |||
487 | return 0; | 561 | return 0; |
488 | } | 562 | } |
489 | 563 | ||
490 | /* Grab the next task, i.e. the owner of @lock */ | 564 | /* [10] Grab the next task, i.e. the owner of @lock */ |
491 | task = rt_mutex_owner(lock); | 565 | task = rt_mutex_owner(lock); |
492 | get_task_struct(task); | 566 | get_task_struct(task); |
493 | raw_spin_lock_irqsave(&task->pi_lock, flags); | 567 | raw_spin_lock_irqsave(&task->pi_lock, flags); |
494 | 568 | ||
569 | /* [11] requeue the pi waiters if necessary */ | ||
495 | if (waiter == rt_mutex_top_waiter(lock)) { | 570 | if (waiter == rt_mutex_top_waiter(lock)) { |
496 | /* | 571 | /* |
497 | * The waiter became the new top (highest priority) | 572 | * The waiter became the new top (highest priority) |
@@ -526,23 +601,30 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task, | |||
526 | } | 601 | } |
527 | 602 | ||
528 | /* | 603 | /* |
604 | * [12] check_exit_conditions_4() protected by task->pi_lock | ||
605 | * and lock->wait_lock. The actual decisions are made after we | ||
606 | * dropped the locks. | ||
607 | * | ||
529 | * Check whether the task which owns the current lock is pi | 608 | * Check whether the task which owns the current lock is pi |
530 | * blocked itself. If yes we store a pointer to the lock for | 609 | * blocked itself. If yes we store a pointer to the lock for |
531 | * the lock chain change detection above. After we dropped | 610 | * the lock chain change detection above. After we dropped |
532 | * task->pi_lock next_lock cannot be dereferenced anymore. | 611 | * task->pi_lock next_lock cannot be dereferenced anymore. |
533 | */ | 612 | */ |
534 | next_lock = task_blocked_on_lock(task); | 613 | next_lock = task_blocked_on_lock(task); |
535 | |||
536 | raw_spin_unlock_irqrestore(&task->pi_lock, flags); | ||
537 | |||
538 | /* | 614 | /* |
539 | * Store the top waiter of @lock for the end of chain walk | 615 | * Store the top waiter of @lock for the end of chain walk |
540 | * decision below. | 616 | * decision below. |
541 | */ | 617 | */ |
542 | top_waiter = rt_mutex_top_waiter(lock); | 618 | top_waiter = rt_mutex_top_waiter(lock); |
619 | |||
620 | /* [13] Drop the locks */ | ||
621 | raw_spin_unlock_irqrestore(&task->pi_lock, flags); | ||
543 | raw_spin_unlock(&lock->wait_lock); | 622 | raw_spin_unlock(&lock->wait_lock); |
544 | 623 | ||
545 | /* | 624 | /* |
625 | * Make the actual exit decisions [12], based on the stored | ||
626 | * values. | ||
627 | * | ||
546 | * We reached the end of the lock chain. Stop right here. No | 628 | * We reached the end of the lock chain. Stop right here. No |
547 | * point to go back just to figure that out. | 629 | * point to go back just to figure that out. |
548 | */ | 630 | */ |