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, --SailajaReceived on Thu Nov 06 2008 - 18:46:55 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:37 UTC