1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-14 10:09:48 +00:00

Two fixes for excessive iterations after r292326.

Advance the logical block number to the lblkno of the found block plus
one, instead of incrementing the block number which was used for
lookup.  This change skips sparcely populated buffer ranges, similar
to r292325, instead of doing useless lookups.

Do not restart the bnoreuselist() from the start of the range if
buffer lock cannot be obtained without sleep.  Only retry lookup and
lock for the same queue and same logical block number.

Reported by:	benno
Tested by:	pho
Sponsored by:	The FreeBSD Foundation
MFC after:	3 days
This commit is contained in:
Konstantin Belousov 2016-01-05 14:48:40 +00:00
parent e10c4cc0a4
commit 1041e09089
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=293197
2 changed files with 8 additions and 10 deletions

View File

@ -1080,15 +1080,9 @@ vop_stdadvise(struct vop_advise_args *ap)
bsize = vp->v_bufobj.bo_bsize;
startn = ap->a_start / bsize;
endn = ap->a_end / bsize;
for (;;) {
error = bnoreuselist(&bo->bo_clean, bo, startn, endn);
if (error == EAGAIN)
continue;
error = bnoreuselist(&bo->bo_clean, bo, startn, endn);
if (error == 0)
error = bnoreuselist(&bo->bo_dirty, bo, startn, endn);
if (error == EAGAIN)
continue;
break;
}
BO_RUNLOCK(bo);
VOP_UNLOCK(vp, 0);
break;

View File

@ -1669,7 +1669,8 @@ bnoreuselist(struct bufv *bufv, struct bufobj *bo, daddr_t startn, daddr_t endn)
ASSERT_BO_LOCKED(bo);
for (lblkno = startn;; lblkno++) {
for (lblkno = startn;;) {
again:
bp = BUF_PCTRIE_LOOKUP_GE(&bufv->bv_root, lblkno);
if (bp == NULL || bp->b_lblkno >= endn)
break;
@ -1677,11 +1678,14 @@ bnoreuselist(struct bufv *bufv, struct bufobj *bo, daddr_t startn, daddr_t endn)
LK_INTERLOCK, BO_LOCKPTR(bo), "brlsfl", 0, 0);
if (error != 0) {
BO_RLOCK(bo);
return (error != ENOLCK ? error : EAGAIN);
if (error == ENOLCK)
goto again;
return (error);
}
KASSERT(bp->b_bufobj == bo,
("bp %p wrong b_bufobj %p should be %p",
bp, bp->b_bufobj, bo));
lblkno = bp->b_lblkno + 1;
if ((bp->b_flags & B_MANAGED) == 0)
bremfree(bp);
bp->b_flags |= B_RELBUF;