From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1162154AbcFGUUX (ORCPT ); Tue, 7 Jun 2016 16:20:23 -0400 Received: from merlin.infradead.org ([205.233.59.134]:56956 "EHLO merlin.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1422978AbcFGUTi (ORCPT ); Tue, 7 Jun 2016 16:19:38 -0400 Message-Id: <20160607200216.117270606@infradead.org> User-Agent: quilt/0.63-1 Date: Tue, 07 Jun 2016 21:56:43 +0200 From: Peter Zijlstra To: mingo@kernel.org, tglx@linutronix.de, juri.lelli@arm.com, rostedt@goodmis.org, xlpang@redhat.com Cc: linux-kernel@vger.kernel.org, mathieu.desnoyers@efficios.com, jdesfossez@efficios.com, bristot@redhat.com, peterz@infradead.org Subject: [RFC][PATCH 8/8] rtmutex: Fix PI chain order integrity References: <20160607195635.710022345@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline; filename=peterz-cleanup-rt-mutex-5.patch Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org rt_mutex_waiter::prio is a copy of task_struct::prio which is updated during the PI chain walk, such that the PI chain order isn't messed up by (asynchronous) task state updates. Currently rt_mutex_waiter_less() uses task state for deadline tasks; this is broken, since the task state can, as said above, change asynchronously, causing the RB tree order to change without actual tree update -> FAIL. Fix this by also copying the deadline into the rt_mutex_waiter state and updating it along with its prio field. Ideally we would also force PI chain updates whenever DL tasks update their deadline parameter, but for first approximation this is less broken than it was. Signed-off-by: Peter Zijlstra (Intel) --- kernel/locking/rtmutex.c | 5 +++-- kernel/locking/rtmutex_common.h | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c @@ -172,8 +172,7 @@ rt_mutex_waiter_less(struct rt_mutex_wai * then right waiter has a dl_prio() too. */ if (dl_prio(left->prio)) - return dl_time_before(left->task->dl.deadline, - right->task->dl.deadline); + return dl_time_before(left->deadline, right->deadline); return 0; } @@ -585,6 +584,7 @@ static int rt_mutex_adjust_prio_chain(st /* [7] Requeue the waiter in the lock waiter tree. */ rt_mutex_dequeue(lock, waiter); waiter->prio = task->prio; + waiter->deadline = task->dl.deadline; rt_mutex_enqueue(lock, waiter); /* [8] Release the task */ @@ -855,6 +855,7 @@ static int task_blocks_on_rt_mutex(struc waiter->task = task; waiter->lock = lock; waiter->prio = task->prio; + waiter->deadline = task->dl.deadline; /* Get the top priority waiter on the lock */ if (rt_mutex_has_waiters(lock)) --- a/kernel/locking/rtmutex_common.h +++ b/kernel/locking/rtmutex_common.h @@ -33,6 +33,7 @@ struct rt_mutex_waiter { struct rt_mutex *deadlock_lock; #endif int prio; + u64 deadline; }; /*