Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753724AbdDCP04 convert rfc822-to-8bit (ORCPT ); Mon, 3 Apr 2017 11:26:56 -0400 Received: from mx2.suse.de ([195.135.220.15]:49765 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753024AbdDCP0z (ORCPT ); Mon, 3 Apr 2017 11:26:55 -0400 Date: Mon, 3 Apr 2017 08:26:43 -0700 From: Davidlohr Bueso To: Laurent Dufour Cc: mingo@kernel.org, peterz@infradead.org, akpm@linux-foundation.org, jack@suse.cz, kirill.shutemov@linux.intel.com, mhocko@suse.com, mgorman@techsingularity.net, linux-kernel@vger.kernel.org, Davidlohr Bueso Subject: Re: [PATCH 1/5] locking: Introduce range reader/writer lock Message-ID: <20170403152643.GB2270@linux-80c1.suse> References: <1488863010-13028-1-git-send-email-dave@stgolabs.net> <1488863010-13028-2-git-send-email-dave@stgolabs.net> <2f7628f4-58e1-22c4-ccbe-3106c15cb405@linux.vnet.ibm.com> <20170328163918.GA27446@linux-80c1.suse> <20170403161917.4ef46f17@nimbus> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1; format=flowed Content-Disposition: inline Content-Transfer-Encoding: 8BIT In-Reply-To: <20170403161917.4ef46f17@nimbus> User-Agent: Mutt/1.5.24 (2015-08-30) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1706 Lines: 45 On Mon, 03 Apr 2017, Laurent Dufour wrote: >Le Tue, 28 Mar 2017 09:39:18 -0700, >Davidlohr Bueso a ?crit : >> I'll wait to see if there are any more concerns and send a v2 with >> your corrections. > >Hi Bavidlohr, I think there is a major issue regarding the task >catching a signal in wait_for_range(). >I can see it when a thread is catching a signal, the process deadlock >in exit path. > >Let's imagine all these tasks waiting for the complete range lock, so >range doesn't matter: > >A get the lock in write >B want the read lock => B->blocking_range=1 (because of A) >C want the write lock => C->blocking_range=2 (A,B) >D want the read lock => D->blocking_range=3 (A,B,C) >=> C catch a signal and exit wait_for_ranges() >A release the lock > => B->blocking_range=0 > => D->blocking_range=2 (D has not seen C removal) >=> B get the lock >B release the lock > => D->blocking_range=1 > >D remains blocked while no one has the lock ! > >The issue is when removing a task from the interval tree, we >should decrement all the blocking_ranges of the task added to that >range after the one leaving... I can't see an easy fix for that :( > >Am I right ? Yes. Peter had also mentioned the issue too. One way I though of fixing the problem was to track the jiffies timestamp in a per range_rwlock basis for when it was added, and in the signal_pending() case, along with removing the lock from the tree, we iterate the tree again and decrement the blocking_ranges for those with a higher timestamp. It would add some overhead, but again this is the unlikely() case. It also adds an extra 8 bytes of footprint, but this is usually stack allocated. Thanks, Davidlohr