One of the problems I'm running into is a deadlock where I have threads
blocked on newbuf (with vnode lock held) due to buffer shortage and
bufdaemon unable to flush buffers because it can't get the exclusive
lock for the vnode. From the code:

struct buf *
getblk(struct vnode * vp, daddr_t blkno, int size, int slpflag, int
slptimeo,
int flags)
{
..
..

/*
* Buffer is not in-core, create new buffer. The buffer
* returned by getnewbuf() is locked. Note that the
returned
* buffer is also considered valid (not marked B_INVAL).
*/
BO_UNLOCK(bo);
..
..
bp = getnewbuf(slpflag, slptimeo, size, maxsize,
vp_to_buf_index(vp));
if (bp == NULL) {
..
..
/*
* This code is used to make sure that a buffer is not
* created while the getnewbuf routine is blocked.
* This can be a problem whether the vnode is locked or
not.
* If the buffer is created out from under us, we have
to
* throw away the one we just created.
*
* Note: this must occur before we associate the buffer
* with the vp especially considering limitations in
* the splay tree implementation when dealing with
duplicate
* lblkno's.
*/
BO_LOCK(bo);
if (gbincore(bo, blkno)) {
BO_UNLOCK(bo);
bp->b_flags |= B_INVAL;
brelse(bp);
goto loop;
}

Given that this code rechecks if a buffer has already been created with
the possibility that this thread might have blocked on getnewbuf (), Is
there really
any need to hold the vnode lock across getnewbuf call?


thanks,
--Sailaja

_______________________________________________
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/lis...reebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscribe@freebsd.org"