From owner-freebsd-current@FreeBSD.ORG Thu Nov 6 19:46:55 2008 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8B0E11065672 for ; Thu, 6 Nov 2008 19:46:55 +0000 (UTC) (envelope-from sbangaru@panasas.com) Received: from laguna.int.panasas.com (gw-ca.panasas.com [66.104.249.162]) by mx1.freebsd.org (Postfix) with ESMTP id 7019A8FC17 for ; Thu, 6 Nov 2008 19:46:55 +0000 (UTC) (envelope-from sbangaru@panasas.com) X-MimeOLE: Produced By Microsoft Exchange V6.5 Content-class: urn:content-classes:message MIME-Version: 1.0 Date: Thu, 6 Nov 2008 11:33:23 -0800 Message-ID: <977F1EB2DC429D40AB37C88180BFCD480352FD84@LAGUNA.int.panasas.com> X-MS-Has-Attach: X-MS-TNEF-Correlator: Thread-Topic: Is there a need to hold the vnode lock across getnewbuf( ) in getblk? Thread-Index: AclARogUkP3Z8XjYQGuoOFACFenPfA== From: "Bangaru, Sailaja" To: Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.5 Subject: Is there a need to hold the vnode lock across getnewbuf( ) in getblk? X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 06 Nov 2008 19:46:55 -0000 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: =20 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 =3D getnewbuf(slpflag, slptimeo, size, maxsize, vp_to_buf_index(vp)); if (bp =3D=3D 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 |=3D 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=20 any need to hold the vnode lock across getnewbuf call? =20 =20 thanks, --Sailaja =20