2015-11-08 2:09 GMT+08:00 Thomas Gleixner <tglx@xxxxxxxxxxxxx>: > On Fri, 6 Nov 2015, Thomas Gleixner wrote: > Btw, please update to 3.12.48-rt66. It contains quite some bugfixes in > the area of futex/rtmutex. > > Thanks, > > tglx On Fri, 6 Nov 2015, Thomas Gleixner wrote: >> diff --git a/kernel/rtmutex.c b/kernel/rtmutex.c >> index 7601c1332a88..0e6505d5ce4a 100644 >> --- a/kernel/rtmutex.c >> +++ b/kernel/rtmutex.c >> @@ -1003,11 +1003,18 @@ static void wakeup_next_waiter(struct rt_mutex *lock) >> static void remove_waiter(struct rt_mutex *lock, >> struct rt_mutex_waiter *waiter) >> { >> - bool is_top_waiter = (waiter == rt_mutex_top_waiter(lock)); >> struct task_struct *owner = rt_mutex_owner(lock); >> struct rt_mutex *next_lock = NULL; >> + bool is_top_waiter = false; >> unsigned long flags; >> >> + /* >> + * @waiter might be not queued when task_blocks_on_rt_mutex() >> + * returned early so @lock might not have any waiters. >> + */ >> + if (rt_mutex_has_waiters()) >> + is_top_waiter = (waiter == rt_mutex_top_waiter(lock)); >> + >> raw_spin_lock_irqsave(¤t->pi_lock, flags); >> rt_mutex_dequeue(lock, waiter); >> current->pi_blocked_on = NULL; Sincerely appreciate for your answers! Could it be modified as below? It seems not necessary to call rt_mutex_dequeue() and clear the current->pi_blocked_on if there's no waiter on the lock. And the waiter->task is not the 'current' when the remove_waiter() is called in the function rt_mutex_start_proxy_lock(). static void remove_waiter(struct rt_mutex *lock, struct rt_mutex_waiter *waiter) { - bool is_top_waiter = (waiter == rt_mutex_top_waiter(lock)); struct task_struct *owner = rt_mutex_owner(lock); struct rt_mutex *next_lock = NULL; + bool is_top_waiter; + struct task_struct *task = waiter->task; unsigned long flags; + /* + * @waiter might be not queued when task_blocks_on_rt_mutex() + * returned early so @lock might not have any waiters. + */ + if (unlikely(!rt_mutex_has_waiters())) + return; + + is_top_waiter = (waiter == rt_mutex_top_waiter(lock)); + - raw_spin_lock_irqsave(¤t->pi_lock, flags); - rt_mutex_dequeue(lock, waiter); - current->pi_blocked_on = NULL; - raw_spin_unlock_irqrestore(¤t->pi_lock, flags); + raw_spin_lock_irqsave(&task->pi_lock, flags); + rt_mutex_dequeue(lock, waiter); + task->pi_blocked_on = NULL; + __rt_mutex_adjust_prio(task); <-- I'm not sure if it is necessary. + raw_spin_unlock_irqrestore(&task->pi_lock, flags); ...... - rt_mutex_adjust_prio_chain(owner, 0, lock, next_lock, NULL, current); + rt_mutex_adjust_prio_chain(owner, 0, lock, next_lock, NULL, task); ...... } I'm sorry for so many questions. Thanks ahead! B.R. Yimin Deng -- To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html