Fix 4 problems:
Major: When blocking occurs in allocbuf() for VMIO files, excess wire counts could accumulate. Major: Pages are incorrectly accumulated into the physical buffer for clustered reads. This happens when bogus page is needed. Minor: When reclaiming buffers, the async flag on the buffer needs to be zero, or the reclaim is not optimal. Minor: The age flag should be cleared, if a buffer is wanted.
This commit is contained in:
parent
1f3a0ea7fd
commit
ffe2522e29
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=18737
@ -18,7 +18,7 @@
|
||||
* 5. Modifications may be freely made to this file if the above conditions
|
||||
* are met.
|
||||
*
|
||||
* $Id: vfs_bio.c,v 1.101 1996/09/18 15:57:41 dyson Exp $
|
||||
* $Id: vfs_bio.c,v 1.102 1996/09/20 02:26:35 dyson Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -112,10 +112,7 @@ static struct bqueues bufqueues[BUFFER_QUEUES];
|
||||
|
||||
extern int vm_swap_size;
|
||||
|
||||
#define BUF_MAXUSE 8
|
||||
/*
|
||||
#define NO_B_MALLOC
|
||||
*/
|
||||
#define BUF_MAXUSE 16
|
||||
|
||||
/*
|
||||
* Initialize buffer headers and related structures.
|
||||
@ -464,7 +461,7 @@ brelse(struct buf * bp)
|
||||
|
||||
/* anyone need this block? */
|
||||
if (bp->b_flags & B_WANTED) {
|
||||
bp->b_flags &= ~B_WANTED;
|
||||
bp->b_flags &= ~(B_WANTED | B_AGE);
|
||||
wakeup(bp);
|
||||
}
|
||||
|
||||
@ -664,9 +661,9 @@ vfs_vmio_release(bp)
|
||||
tsleep(m, PVM, "vmiorl", 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
vm_page_unwire(m);
|
||||
|
||||
|
||||
if (m->wire_count == 0) {
|
||||
|
||||
if (m->flags & PG_WANTED) {
|
||||
@ -860,6 +857,12 @@ getnewbuf(int slpflag, int slptimeo, int doingvmio)
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if defined(DIAGNOSTIC)
|
||||
if (bp->b_flags & B_BUSY) {
|
||||
panic("getnewbuf: busy buffer on free list\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We are fairly aggressive about freeing VMIO buffers, but since
|
||||
* the buffering is intact without buffer headers, there is not
|
||||
@ -894,8 +897,10 @@ getnewbuf(int slpflag, int slptimeo, int doingvmio)
|
||||
bremfree(bp);
|
||||
bp->b_flags |= B_BUSY;
|
||||
|
||||
if (bp->b_flags & B_VMIO)
|
||||
if (bp->b_flags & B_VMIO) {
|
||||
bp->b_flags &= ~B_ASYNC;
|
||||
vfs_vmio_release(bp);
|
||||
}
|
||||
|
||||
if (bp->b_vp)
|
||||
brelvp(bp);
|
||||
@ -1303,6 +1308,10 @@ allocbuf(struct buf * bp, int size)
|
||||
* is the responsibility of vnode_pager_setsize
|
||||
*/
|
||||
m = bp->b_pages[i];
|
||||
#if defined(DIAGNOSTIC)
|
||||
if (m == bogus_page)
|
||||
panic("allocbuf: bogus page found");
|
||||
#endif
|
||||
s = splvm();
|
||||
while ((m->flags & PG_BUSY) || (m->busy != 0)) {
|
||||
m->flags |= PG_WANTED;
|
||||
@ -1339,8 +1348,8 @@ allocbuf(struct buf * bp, int size)
|
||||
if (tinc > bsize)
|
||||
tinc = bsize;
|
||||
off = (vm_ooffset_t) bp->b_lblkno * bsize;
|
||||
doretry:
|
||||
curbpnpages = bp->b_npages;
|
||||
doretry:
|
||||
bp->b_flags |= B_CACHE;
|
||||
for (toff = 0; toff < newbsize; toff += tinc) {
|
||||
int bytesinpage;
|
||||
|
@ -33,7 +33,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)vfs_cluster.c 8.7 (Berkeley) 2/13/94
|
||||
* $Id: vfs_cluster.c,v 1.36 1996/06/03 04:40:35 dyson Exp $
|
||||
* $Id: vfs_cluster.c,v 1.37 1996/07/27 18:49:18 dyson Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -368,18 +368,24 @@ cluster_rbuild(vp, filesize, lbn, blkno, size, run)
|
||||
m = tbp->b_pages[j];
|
||||
++m->busy;
|
||||
++m->object->paging_in_progress;
|
||||
if ((m->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) {
|
||||
m = bogus_page;
|
||||
}
|
||||
if ((bp->b_npages == 0) ||
|
||||
(bp->b_pages[bp->b_npages-1] != m)) {
|
||||
bp->b_pages[bp->b_npages] = m;
|
||||
bp->b_npages++;
|
||||
}
|
||||
if ((m->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL)
|
||||
tbp->b_pages[j] = bogus_page;
|
||||
}
|
||||
bp->b_bcount += tbp->b_bcount;
|
||||
bp->b_bufsize += tbp->b_bufsize;
|
||||
}
|
||||
|
||||
for(j=0;j<bp->b_npages;j++) {
|
||||
if ((bp->b_pages[j]->valid & VM_PAGE_BITS_ALL) ==
|
||||
VM_PAGE_BITS_ALL)
|
||||
bp->b_pages[j] = bogus_page;
|
||||
}
|
||||
|
||||
pmap_qenter(trunc_page((vm_offset_t) bp->b_data),
|
||||
(vm_page_t *)bp->b_pages, bp->b_npages);
|
||||
return (bp);
|
||||
|
Loading…
Reference in New Issue
Block a user