Subject: Re: uvm_vnp_setsize
To: Nathan J. Williams <nathanw@wasabisystems.com>
From: Chuck Silvers <chuq@chuq.com>
List: tech-kern
Date: 07/07/2006 08:23:35
On Thu, Jul 06, 2006 at 02:00:26PM -0400, Nathan J. Williams wrote:
> Chuck Silvers <chuq@chuq.com> writes:
> 
> > a lockmgr() option for "tell me if I could take this lock but don't
> > actually take it" would be even better.
> 
> Wait, when is that a good idea? If you don't take the lock when it's
> avaliable, then the validity of "I could take the lock" could be true
> when you examine it but false when you try to do something with it.

usually that's right, but in this case there are other locks involved that
allow this to be useful.  the way to think about what VOP_GETPAGES does
to return already-existing pages is more like:

	take vnode getpages sleep lock (shared)
	take vnode object spin lock
	take page sleep locks (aka. PG_BUSY bits)
	release vnode object spin lock
	release vnode getpages lock
	return locked pages

(this is more like what VOP_GETPAGES does in the !PGO_LOCKED case).

however, in the PGO_LOCKED case, VOP_GETPAGES is called with the vnode
object lock already held, so it can't sleep.  this means we can only
acquire sleep locks that are not already held, and it doesn't matter
in what order we try to get them.  if any of the locks we need are
already held then we'll release any locks we did get and return an error.
it's much more likely for the desired pages to not exist than for the
getpages lock to be held exclusively, so I was thinking to minimize the
cost of checking if the pages exist by trying to get the getpages lock last:

	called with vnode object spin lock held
	try to take page sleep locks (aka. PG_BUSY bits)
	try to take vnode getpages sleep lock (shared)
	if (didn't get all locks)
		release any locks we did get and return failure
	release vnode getpages lock
	return locked pages (or an error if we couldn't get all the locks)

since the first thing we do after getting the getpages lock is to release it,
we don't actually need to take it and release it as separate steps.

-Chuck