Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933809AbbHKIT4 (ORCPT ); Tue, 11 Aug 2015 04:19:56 -0400 Received: from LGEMRELSE7Q.lge.com ([156.147.1.151]:45183 "EHLO lgemrelse7q.lge.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932079AbbHKITy (ORCPT ); Tue, 11 Aug 2015 04:19:54 -0400 X-Original-SENDERIP: 10.177.222.220 X-Original-MAILFROM: iamjoonsoo.kim@lge.com Date: Tue, 11 Aug 2015 17:25:27 +0900 From: Joonsoo Kim To: Minchan Kim Cc: Sergey Senozhatsky , Andrew Morton , Nitin Gupta , linux-kernel@vger.kernel.org, paulmck@linux.vnet.ibm.com, peterz@infradead.org Subject: Re: [PATCH] zram: fix possible race when checking idle_strm Message-ID: <20150811082527.GA351@js1304-P5Q-DELUXE> References: <1438934609-16924-1-git-send-email-iamjoonsoo.kim@lge.com> <20150807091457.GL1891@swordfish> <20150807095816.GP1891@swordfish> <20150810003229.GA26074@js1304-P5Q-DELUXE> <20150810232633.GA7197@bgram> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20150810232633.GA7197@bgram> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3937 Lines: 108 On Tue, Aug 11, 2015 at 08:26:33AM +0900, Minchan Kim wrote: > Hi Joonsoo, > > On Mon, Aug 10, 2015 at 09:32:30AM +0900, Joonsoo Kim wrote: > > On Fri, Aug 07, 2015 at 06:58:16PM +0900, Sergey Senozhatsky wrote: > > > On (08/07/15 18:14), Sergey Senozhatsky wrote: > > > > hm... I need to think about it more. > > > > > > > > we do wake_up every time we put stream back to the list > > > > > > > > zcomp_strm_multi_release(): > > > > > > > > spin_lock(&zs->strm_lock); > > > > if (zs->avail_strm <= zs->max_strm) { > > > > list_add(&zstrm->list, &zs->idle_strm); > > > > spin_unlock(&zs->strm_lock); > > > > wake_up(&zs->strm_wait); > > > > return; > > > > } > > > > > > > > > > > > but I can probably see what you mean... in some very extreme case, > > > > though. I can't even formulate it... eh... we use a multi stream > > > > backend with ->max_strm == 1 and there are two processes, one > > > > just falsely passed the wait_event() `if (condition)' check, the > > > > other one just put stream back to ->idle_strm and called wake_up(), > > > > but the first process hasn't yet executed prepare_to_wait_event() > > > > so it might miss a wakeup. and there should be no other process > > > > doing read or write operation. otherwise, there will be wakeup > > > > eventually. > > > > > > > > is this the case you were thinking of?... then yes, this spinlock > > > > may help. > > > > > > > > > > on the other hand... it's actually > > > > > > wait_event() is > > > > > > if (condition) > > > break; > > > prepare_to_wait_event(&wq, &__wait, state) > > > if (condition) > > > break; > > > schedule(); > > > > > > if first condition check was false and we missed a wakeup call between > > > first condition and prepare_to_wait_event(), then second condition > > > check should do the trick I think (or you expect that second condition > > > check may be wrongly pre-fetched or something). > > > > Hello, Sergey. > > > > This is what I thought. > > I expected that second condition can be false if compiler reuse result > > of first check for optimization. I guess that there is no prevention > > for this kind of optimization. > > > > So, following is the problem sequence I thought. > > T1 means thread 1, T2 means another thread, 2. > > > > check if idle_strm is empty or not with holding the lock > > It is empty so do spin_unlock and run wait_event macro > > check if idle_strm is empty or not > > It is still empty > > > > do strm release > > call wake_up > > > > add T1 to wait queue > > check if idle_strm is empty or not > > compiler reuse 's result or CPU just fetch cached > > result so T1 starts waiting > > > > In this case, T1 can be sleep permanently. To prevent compiler > > optimization or fetching cached value, we need a lock here. > > When I read Documentation/memory-barrier.txt, it shouldn't happen. > > "All memory barriers except the data dependency barriers imply a compiler > barrier. Data dependencies do not impose any additional compiler ordering." > > "SLEEP AND WAKE-UP FUNCTIONS > --------------------------- > > Sleeping and waking on an event flagged in global data ... > ... > ... > ... > > A general memory barrier is interpolated automatically by set_current_state() > after it has altered the task state:" > > So I think your T1-7 assumption is not true. > > As well, there are many examples under drivers/ to use the global data > as event flag without locking or atomic. > Okay. Now, I'm convinced that race is not possible. I will drop this patch. Thanks. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/