Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 12 Dec 2002 21:56:56 +0300
From:      Yar Tikhiy <yar@freebsd.org>
To:        Nate Lawson <nate@root.org>
Cc:        freebsd-scsi@freebsd.org
Subject:   Re: {da,sa,...}open bug?
Message-ID:  <20021212215655.A92315@comp.chem.msu.su>
In-Reply-To: <Pine.BSF.4.21.0212101320570.28346-100000@root.org>; from nate@root.org on Tue, Dec 10, 2002 at 01:23:59PM -0800
References:  <20021210143954.B14989@comp.chem.msu.su> <Pine.BSF.4.21.0212101320570.28346-100000@root.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, Dec 10, 2002 at 01:23:59PM -0800, Nate Lawson wrote:
> On Tue, 10 Dec 2002, Yar Tikhiy wrote:
> > On Mon, Dec 09, 2002 at 01:52:23PM -0800, Nate Lawson wrote:
> > > This patch is bad since you need to move the acquire earlier, not
> > > later.  By moving it to the end, you increase the window where another
> > > proc could release the periph and free it.
> > 
> > Why, is the knowledge that cam_periph_lock() calls cam_periph_acquire()
> > first of all considered secret? :-)  The idea behind my patch was
> > as follows: having called cam_periph_lock() ensures the periph won't
> > disappear while it's being opened; and if the open succeeds, another
> > reference to the periph is obtained so it won't go away until it's
> > closed, and the former reference is released, which is one of
> > cam_periph_unlock() effects.
> 
> Here is what would happen with your patch:
> 
> open()
> 1. lock -- refcount +1, get lock, refcount -1
> 2. [open code runs]
> 3. acquire -- refcount +1
> 
> All throughout step 2, periph could disappear if another proc calls
> release.

I see your point, but your scenario isn't exactly what would happen, to my mind.
If periph weren't currently locked, the refcount would change as follows:
1. lock -- refcount +1, get lock
2. [open code runs], refcount >0
3. acquire -- refcount +1
4. unlock -- refcount -1

If periph were already locked by another thread, the following would happen:
1a. lock -- on entry refcount is already >0 since the other thread
    has called cam_periph_lock() and thus incremented refcount
1b. refcount gets +1 and becomes >=2
1c. this thread sleeps until the other unlocks periph, where refcount gets -1,
    but stays >0 since it was >1 before the decrement
1d. get lock
2. [open code runs], refcount > 0
3. acquire -- refcount gets +1 and becomes >1
4. unlock -- refcount gets -1, yet stays >0

As you may see, even if cam_periph_acquire() were called lately,
right before cam_periph_unlock(), refcount would never drop below 1.

-- 
Yar

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-scsi" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20021212215655.A92315>