Date: Mon, 14 Oct 2024 17:12:21 GMT From: Doug Moore <dougm@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 2c8caa4b3925 - main - vfs_subr: optimize inval_buf_range Message-ID: <202410141712.49EHCL6e064271@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by dougm: URL: https://cgit.FreeBSD.org/src/commit/?id=2c8caa4b3925aa73350d687cd13876c275f35889 commit 2c8caa4b3925aa73350d687cd13876c275f35889 Author: Doug Moore <dougm@FreeBSD.org> AuthorDate: 2024-10-14 17:07:59 +0000 Commit: Doug Moore <dougm@FreeBSD.org> CommitDate: 2024-10-14 17:07:59 +0000 vfs_subr: optimize inval_buf_range Use a pctrie_lookup to avoid walking over low out-of-range buf list entries, and an early break to avoid the high out-of-range entries. Avoid writing almost identical loops for the dirty and clean lists. Because pctries are built for unsigned keys, and these are signed values, handle the wraparound problem the same way that bnoreuselist() does. Reviewed by: kib Tested by: pho Differential Revision: https://reviews.freebsd.org/D46963 --- sys/kern/vfs_subr.c | 50 ++++++++++++++++++-------------------------------- 1 file changed, 18 insertions(+), 32 deletions(-) diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index f192c6798858..ff18c50546dd 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -2616,17 +2616,25 @@ static int v_inval_buf_range_locked(struct vnode *vp, struct bufobj *bo, daddr_t startlbn, daddr_t endlbn) { + struct bufv *bv; struct buf *bp, *nbp; - bool anyfreed; + uint8_t anyfreed; + bool clean; ASSERT_VOP_LOCKED(vp, "v_inval_buf_range_locked"); ASSERT_BO_LOCKED(bo); + anyfreed = 1; + clean = true; do { - anyfreed = false; - TAILQ_FOREACH_SAFE(bp, &bo->bo_clean.bv_hd, b_bobufs, nbp) { - if (bp->b_lblkno < startlbn || bp->b_lblkno >= endlbn) - continue; + bv = clean ? &bo->bo_clean : &bo->bo_dirty; + bp = BUF_PCTRIE_LOOKUP_GE(&bv->bv_root, startlbn); + if (bp == NULL || bp->b_lblkno >= endlbn || + bp->b_lblkno < startlbn) + continue; + TAILQ_FOREACH_FROM_SAFE(bp, &bv->bv_hd, b_bobufs, nbp) { + if (bp->b_lblkno >= endlbn) + break; if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_SLEEPFAIL | LK_INTERLOCK, BO_LOCKPTR(bo)) == ENOLCK) { @@ -2638,39 +2646,17 @@ v_inval_buf_range_locked(struct vnode *vp, struct bufobj *bo, bp->b_flags |= B_INVAL | B_RELBUF; bp->b_flags &= ~B_ASYNC; brelse(bp); - anyfreed = true; + anyfreed = 2; BO_LOCK(bo); if (nbp != NULL && - (((nbp->b_xflags & BX_VNCLEAN) == 0) || + (((nbp->b_xflags & + (clean ? BX_VNCLEAN : BX_VNDIRTY)) == 0) || nbp->b_vp != vp || - (nbp->b_flags & B_DELWRI) != 0)) - return (EAGAIN); - } - - TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, nbp) { - if (bp->b_lblkno < startlbn || bp->b_lblkno >= endlbn) - continue; - if (BUF_LOCK(bp, - LK_EXCLUSIVE | LK_SLEEPFAIL | LK_INTERLOCK, - BO_LOCKPTR(bo)) == ENOLCK) { - BO_LOCK(bo); - return (EAGAIN); - } - bremfree(bp); - bp->b_flags |= B_INVAL | B_RELBUF; - bp->b_flags &= ~B_ASYNC; - brelse(bp); - anyfreed = true; - - BO_LOCK(bo); - if (nbp != NULL && - (((nbp->b_xflags & BX_VNDIRTY) == 0) || - (nbp->b_vp != vp) || - (nbp->b_flags & B_DELWRI) == 0)) + (nbp->b_flags & B_DELWRI) == (clean? B_DELWRI: 0))) return (EAGAIN); } - } while (anyfreed); + } while (clean = !clean, anyfreed-- > 0); return (0); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202410141712.49EHCL6e064271>