From owner-cvs-src@FreeBSD.ORG Wed Apr 2 14:47:37 2008 Return-Path: Delivered-To: cvs-src@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 857A5106566B for ; Wed, 2 Apr 2008 14:47:37 +0000 (UTC) (envelope-from max@love2party.net) Received: from moutng.kundenserver.de (moutng.kundenserver.de [212.227.126.179]) by mx1.freebsd.org (Postfix) with ESMTP id 180348FC1C for ; Wed, 2 Apr 2008 14:47:36 +0000 (UTC) (envelope-from max@love2party.net) Received: from vampire.homelinux.org (dslb-088-067-234-219.pools.arcor-ip.net [88.67.234.219]) by mrelayeu.kundenserver.de (node=mrelayeu5) with ESMTP (Nemesis) id 0ML25U-1Jh4FQ1JY5-0003YX; Wed, 02 Apr 2008 16:47:36 +0200 Received: (qmail 74675 invoked from network); 2 Apr 2008 14:46:33 -0000 Received: from myhost.laiers.local (192.168.4.151) by laiers.local with SMTP; 2 Apr 2008 14:46:33 -0000 From: Max Laier Organization: FreeBSD To: Jeff Roberson Date: Wed, 2 Apr 2008 16:45:19 +0200 User-Agent: KMail/1.9.9 References: <200804012031.m31KVtKs000176@repoman.freebsd.org> <200804020412.30624.max@love2party.net> <20080401210738.E72156@desktop> In-Reply-To: <20080401210738.E72156@desktop> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200804021645.19331.max@love2party.net> X-Provags-ID: V01U2FsdGVkX18qS5LSLBzRDiAO+GGT6FhTlEIcNglgtWVsLTn d7CAvNp35B2Y6IvjRl5bRNqfqxvsdcWNUevATk34kemUEe3EWR 5l2ys1BED5dj6h24TE0GA== Cc: Attilio Rao , cvs-src@freebsd.org, src-committers@freebsd.org, cvs-all@freebsd.org Subject: Re: cvs commit: src/sys/kern kern_rwlock.c src/sys/sys rwlock.h X-BeenThere: cvs-src@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: CVS commit messages for the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 02 Apr 2008 14:47:37 -0000 On Wednesday 02 April 2008 09:15:25 Jeff Roberson wrote: > On Wed, 2 Apr 2008, Max Laier wrote: > > On Wednesday 02 April 2008 03:11:11 Jeff Roberson wrote: > >> On Wed, 2 Apr 2008, Attilio Rao wrote: > >>> 2008/4/2, Max Laier : > >>>> On Wednesday 02 April 2008 00:52:45 Jeff Roberson wrote: > >>>>> On Wed, 2 Apr 2008, Max Laier wrote: > >>>>>> On Tuesday 01 April 2008 22:31:55 Attilio Rao wrote: > >>>>>>> attilio 2008-04-01 20:31:55 UTC > >>>>>>> > >>>>>>> FreeBSD src repository > >>>>>>> > >>>>>>> Modified files: > >>>>>>> sys/kern kern_rwlock.c > >>>>>>> sys/sys rwlock.h > >>>>>>> Log: > >>>>>>> Add rw_try_rlock() and rw_try_wlock() to rwlocks. > >>>>>>> These functions try the specified operation (rlocking and > >>>>>>> wlocking) and true is returned if the operation completes, > >>>>>>> false otherwise. > >>>>>> > >>>>>> hmmm ... I'm certainly missing something here, but what's a > >>>>>> possible usecase for these? It seems there is not much you can > >>>>>> do if you can't obtain a rw_lock. I can understand the need for > >>>>>> sx_try_* where you want to avoid sleeping, but I can't figure > >>>>>> out the need for it on a locking primitive that will only spin > >>>>>> or wait (not 100% sure about the terminology here). This is > >>>>>> especially strange for rw_try_wlock, unless you plan to sleep > >>>>>> manually on fail. But then again you'd have a good chance that > >>>>>> you have to do it over and over again if timing is unfortunate. > >>>>> > >>>>> I asked for it. We have a try operation for mtx already. I was > >>>>> experimenting with converting some code to use rwlocks from mtx > >>>>> and it required it. The specific case is in the softdep code > >>>>> where it uses trylock to avoid deadlocking. With trylock you can > >>>>> violate the lockorder. > >>>> > >>>> Makes sense, thanks! A little follow-up, though about something > >>>> I'm wondering about for quite some time now. Take the following > >>>> scenario: > >>>> > >>>> Thread A: rw_rlock(RW) ... mtx_lock(MTX) ... UNLOCK > >>>> Thread B: mtx_lock(MTX) ... rw_rlock(RW) ... UNLOCK > >>>> Thread C: rw_wlock(RW) ... UNLOCK > >>> > >>> This can't deadlock simply because rw_rlock() is not mutually > >>> exclusive. > >> > >> It can deadlock if there is a writer waiting in queue depending on > >> whether we prefer readers or writers. I think we should consider > >> the reader/writer perference an implementation detail to prevent > >> code like this from cropping up. > > > > Sorry, I still don't understand this. Even if there is a writer > > (thread C) waiting and we prefer writers, the reader (A or B) has to > > wait, but eventually the writer will give up the lock (as it can make > > progress independently of whether the mutex is held or not) and the > > readers can progress. What am I missing? > > Thread A: rw_rlock(RW) ... mtx_lock(MTX) ... UNLOCK > Thread B: mtx_lock(MTX) ... rw_rlock(RW) ... UNLOCK > Thread C: rw_wlock(RW) ... UNLOCK > > Thread A: Thread B: Thread C: > rw_rlock(rw) > mtx_lock(mtx) > rw_wlock(rw) <- Blocked waiting for a > rw_rlock(rw) <- Blocked waiting for c due to write > fairness mtx_lock(mtx) <- Blocked waiting for B > > Does that help? Yes it does, thanks. Do you know what the situation for rm_locks is? If I understand correctly they implement full priority propagation. In this scenario C would boost A via the RM and A would boost B via MTX so B could run and avoid the deadlock. Or am I missing something again? In any case doing "while (!rw_try_wlock(rw));" instead of a plain "rw_wlock(rw);" would now be a possible workaround - if we don't care about starvation of thread C, right? > > I don't think this is a good thing either, but I also think that > > there are some cases where there just are different access orders. > > I'd rather want a clean way out of this than a lot of difficult > > per-instance hacks. This does not mean that these can't be fixed > > cleanly, but I think it's really hard sometimes especially for code > > we import from elsewhere (hence the personal interest). > > I think the best solution is to treat rlocks as wlocks in terms of > access orders. > > >> Readers are only allowed to proceed with a read lock if they already > >> own a read lock, not just if the lock is already read locked. This > >> changed in current recently. So a single recursive read acqusition > >> can't deadlock but get multiple threads and a writer involved with > >> writer preference and you can. > > Thanks, > Jeff > > > -- > > /"\ Best regards, | mlaier@freebsd.org > > \ / Max Laier | ICQ #67774661 > > X http://pf4freebsd.love2party.net/ | mlaier@EFnet > > / \ ASCII Ribbon Campaign | Against HTML Mail and News -- /"\ Best regards, | mlaier@freebsd.org \ / Max Laier | ICQ #67774661 X http://pf4freebsd.love2party.net/ | mlaier@EFnet / \ ASCII Ribbon Campaign | Against HTML Mail and News