From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753151AbcAVLHF (ORCPT ); Fri, 22 Jan 2016 06:07:05 -0500 Received: from casper.infradead.org ([85.118.1.10]:33316 "EHLO casper.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753060AbcAVLG4 (ORCPT ); Fri, 22 Jan 2016 06:06:56 -0500 Date: Fri, 22 Jan 2016 12:06:53 +0100 From: Peter Zijlstra To: Jason Low Cc: Waiman Long , Ding Tianhong , Ingo Molnar , "linux-kernel@vger.kernel.org" , Davidlohr Bueso , Linus Torvalds , "Paul E. McKenney" , Thomas Gleixner , Will Deacon , Tim Chen , Waiman Long Subject: Re: [PATCH RFC] locking/mutexes: don't spin on owner when wait list is not NULL. Message-ID: <20160122110653.GF6375@twins.programming.kicks-ass.net> References: <56A0A4ED.3070308@huawei.com> <56A1638A.7050202@hpe.com> <20160122085422.GO6357@twins.programming.kicks-ass.net> <1453458019.9727.8.camel@j-VirtualBox> <20160122105312.GQ6357@twins.programming.kicks-ass.net> <20160122105652.GE6375@twins.programming.kicks-ass.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20160122105652.GE6375@twins.programming.kicks-ass.net> User-Agent: Mutt/1.5.21 (2012-12-30) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, Jan 22, 2016 at 11:56:52AM +0100, Peter Zijlstra wrote: > On Fri, Jan 22, 2016 at 11:53:12AM +0100, Peter Zijlstra wrote: > > > There might be other details, but this is the one that stood out. > > I think this also does the wrong thing for use_ww_ctx. Something like so? --- kernel/locking/mutex.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c index 0551c219c40e..070a0ac34aa7 100644 --- a/kernel/locking/mutex.c +++ b/kernel/locking/mutex.c @@ -512,6 +512,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, struct task_struct *task = current; struct mutex_waiter waiter; unsigned long flags; + bool acquired; int ret; preempt_disable(); @@ -543,6 +544,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, lock_contended(&lock->dep_map, ip); for (;;) { + acquired = false; /* * Lets try to take the lock again - this is needed even if * we get here for the first time (shortly after failing to @@ -577,7 +579,16 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, /* didn't get the lock, go to sleep: */ spin_unlock_mutex(&lock->wait_lock, flags); schedule_preempt_disabled(); + + if (mutex_is_locked(lock)) + acquired = mutex_optimistic_spin(lock, ww_ctx, use_ww_ctx); + spin_lock_mutex(&lock->wait_lock, flags); + + if (acquired) { + atomic_set(&lock->count, -1); + break; + } } __set_task_state(task, TASK_RUNNING); @@ -587,6 +598,9 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, atomic_set(&lock->count, 0); debug_mutex_free_waiter(&waiter); + if (acquired) + goto unlock; + skip_wait: /* got the lock - cleanup and rejoice! */ lock_acquired(&lock->dep_map, ip); @@ -597,6 +611,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, ww_mutex_set_context_slowpath(ww, ww_ctx); } +unlock: spin_unlock_mutex(&lock->wait_lock, flags); preempt_enable(); return 0;