Messages in this thread | | | Date | Wed, 28 May 2014 11:43:16 +0200 (CEST) | From | Thomas Gleixner <> | Subject | Re: [patch 6/6] rtmutex: Avoid pointless requeueing in the deadlock detection chain walk |
| |
On Tue, 27 May 2014, Jason Low wrote: > On Wed, May 21, 2014 at 8:25 PM, Thomas Gleixner <tglx@linutronix.de> wrote: > > > @@ -440,32 +452,41 @@ static int rt_mutex_adjust_prio_chain(st > > get_task_struct(task); > > raw_spin_lock_irqsave(&task->pi_lock, flags); > > > > - if (waiter == rt_mutex_top_waiter(lock)) { > > - /* > > - * The waiter became the top waiter on the > > - * lock. Remove the previous top waiter from the tasks > > - * pi waiters list and add waiter to it. > > - */ > > - rt_mutex_dequeue_pi(task, prerequeue_top_waiter); > > - rt_mutex_enqueue_pi(task, waiter); > > - __rt_mutex_adjust_prio(task); > > - > > - } else if (prerequeue_top_waiter == waiter) { > > - /* > > - * The waiter was the top waiter on the lock. Remove > > - * waiter from the tasks pi waiters list and add the > > - * new top waiter to it. > > - */ > > - rt_mutex_dequeue_pi(task, waiter); > > - waiter = rt_mutex_top_waiter(lock); > > - rt_mutex_enqueue_pi(task, waiter); > > - __rt_mutex_adjust_prio(task); > > - > > - } else { > > - /* > > - * Nothing changed. No need to do any priority > > - * adjustment. > > - */ > > + /* > > + * In case we are just following the lock chain for deadlock > > + * detection we can avoid the whole requeue and priority > > + * adjustment business. > > + */ > > + if (requeue) { > > + if (waiter == rt_mutex_top_waiter(lock)) { > > + /* > > + * The waiter became the top waiter on the > > + * lock. Remove the previous top waiter from > > + * the tasks pi waiters list and add waiter to > > + * it. > > + */ > > + rt_mutex_dequeue_pi(task, prerequeue_top_waiter); > > + rt_mutex_enqueue_pi(task, waiter); > > + __rt_mutex_adjust_prio(task); > > + > > + } else if (prerequeue_top_waiter == waiter) { > > + /* > > + * The waiter was the top waiter on the > > + * lock. Remove waiter from the tasks pi > > + * waiters list and add the new top waiter to > > + * it. > > + */ > > + rt_mutex_dequeue_pi(task, waiter); > > + waiter = rt_mutex_top_waiter(lock); > > + rt_mutex_enqueue_pi(task, waiter); > > + __rt_mutex_adjust_prio(task); > > + > > + } else { > > + /* > > + * Nothing changed. No need to do any priority > > + * adjustment. > > + */ > > + } > > } > > > > raw_spin_unlock_irqrestore(&task->pi_lock, flags); > > In the above case, could we go 1 step further and avoid taking the pi > lock as well? > > if (requeue) { > raw_spin_lock_irqsave(&task->pi_lock, flags); > > if (waiter == rt_mutex_top_waiter(lock)) { > /* > * The waiter became the top waiter on the > * lock. Remove the previous top waiter from > * the tasks pi waiters list and add waiter to > * it. > */ > rt_mutex_dequeue_pi(task, prerequeue_top_waiter); > rt_mutex_enqueue_pi(task, waiter); > __rt_mutex_adjust_prio(task); > > } else if (prerequeue_top_waiter == waiter) { > /* > * The waiter was the top waiter on the > * lock. Remove waiter from the tasks pi > * waiters list and add the new top waiter to > * it. > */ > rt_mutex_dequeue_pi(task, waiter); > waiter = rt_mutex_top_waiter(lock); > rt_mutex_enqueue_pi(task, waiter); > __rt_mutex_adjust_prio(task); > > } else { > /* > * Nothing changed. No need to do any priority > * adjustment. > */ > } > > raw_spin_unlock_irqrestore(&task->pi_lock, flags); > }
Indeed.
| |