Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751612AbdG0Ps4 convert rfc822-to-8bit (ORCPT ); Thu, 27 Jul 2017 11:48:56 -0400 Received: from mx1.redhat.com ([209.132.183.28]:60558 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751591AbdG0Psy (ORCPT ); Thu, 27 Jul 2017 11:48:54 -0400 DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 35F41C59CC Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=longman@redhat.com Subject: Re: [PATCH] rwsem: fix missed wakeup due to reordering of load To: Prateek Sood , peterz@infradead.org, mingo@redhat.com Cc: sramana@codeaurora.org, linux-kernel@vger.kernel.org References: <1501100272-16338-1-git-send-email-prsood@codeaurora.org> From: Waiman Long Organization: Red Hat Message-ID: <680a3f82-b36b-e09f-b1db-fa23d9f21fc2@redhat.com> Date: Thu, 27 Jul 2017 11:48:53 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.2.0 MIME-Version: 1.0 In-Reply-To: <1501100272-16338-1-git-send-email-prsood@codeaurora.org> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8BIT Content-Language: en-US X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Thu, 27 Jul 2017 15:48:54 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1915 Lines: 47 On 07/26/2017 04:17 PM, Prateek Sood wrote: > If a spinner is present, there is a chance that the load of > rwsem_has_spinner() in rwsem_wake() can be reordered with > respect to decrement of rwsem count in __up_write() leading > to wakeup being missed. > > spinning writer up_write caller > --------------- ----------------------- > [S] osq_unlock() [L] osq > spin_lock(wait_lock) > sem->count=0xFFFFFFFF00000001 > +0xFFFFFFFF00000000 > count=sem->count > MB > sem->count=0xFFFFFFFE00000001 > -0xFFFFFFFF00000001 > spin_trylock(wait_lock) > return > rwsem_try_write_lock(count) > spin_unlock(wait_lock) > schedule() > > Reordering of atomic_long_sub_return_release() in __up_write() > and rwsem_has_spinner() in rwsem_wake() can cause missing of > wakeup in up_write() context. In spinning writer, sem->count > and local variable count is 0XFFFFFFFE00000001. It would result > in rwsem_try_write_lock() failing to acquire rwsem and spinning > writer going to sleep in rwsem_down_write_failed(). > > The smp_rmb() will make sure that the spinner state is > consulted after sem->count is updated in up_write context. > > Signed-off-by: Prateek Sood Did you actually observe that the reordering happens? I am not sure if some architectures can actually speculatively execute instruction ahead of a branch and then ahead into a function call. I know it can happen if the function call is inlined, but rwsem_wake() will not be inlined into __up_read() or __up_write(). Even if that is the case, I am not sure if smp_rmb() alone is enough to guarantee the ordering as I think it will depend on how the atomic_long_sub_return_release() is implmented. Cheers, Longman