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:
parent
07c911dcef
commit
8c46f725d5
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user