summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/swap_pager.c63
-rw-r--r--sys/vm/vm_fault.c13
-rw-r--r--sys/vm/vm_kern.c4
-rw-r--r--sys/vm/vm_object.c68
-rw-r--r--sys/vm/vm_page.c34
-rw-r--r--sys/vm/vm_page.h21
-rw-r--r--sys/vm/vm_pageout.c9
-rw-r--r--sys/vm/vnode_pager.c13
8 files changed, 105 insertions, 120 deletions
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index 05d8a327..828eab9 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -39,7 +39,7 @@
* from: Utah $Hdr: swap_pager.c 1.4 91/04/30$
*
* @(#)swap_pager.c 8.9 (Berkeley) 3/21/94
- * $Id: swap_pager.c,v 1.89 1998/02/23 08:22:24 dyson Exp $
+ * $Id: swap_pager.c,v 1.90 1998/02/25 03:55:47 dyson Exp $
*/
/*
@@ -60,7 +60,7 @@
#include <sys/rlist.h>
#ifndef MAX_PAGEOUT_CLUSTER
-#define MAX_PAGEOUT_CLUSTER 8
+#define MAX_PAGEOUT_CLUSTER 16
#endif
#ifndef NPENDINGIO
@@ -165,7 +165,6 @@ static int swap_pager_block_offset __P((vm_pindex_t pindex));
static daddr_t *swap_pager_diskaddr __P((vm_object_t object,
vm_pindex_t pindex, int *valid));
static void swap_pager_finish __P((swp_clean_t spc));
-static void swap_pager_freepage __P((vm_page_t m));
static void swap_pager_free_swap __P((vm_object_t object));
static void swap_pager_freeswapspace __P((vm_object_t object,
unsigned int from,
@@ -860,17 +859,6 @@ swap_pager_haspage(object, pindex, before, after)
}
/*
- * swap_pager_freepage is a convienience routine that clears the busy
- * bit and deallocates a page.
- */
-static void
-swap_pager_freepage(m)
- vm_page_t m;
-{
- vm_page_free(m);
-}
-
-/*
* Wakeup based upon spc state
*/
static void
@@ -914,9 +902,11 @@ swap_pager_ridpages(m, count, reqpage)
{
int i;
- for (i = 0; i < count; i++)
- if (i != reqpage)
- swap_pager_freepage(m[i]);
+ for (i = 0; i < count; i++) {
+ if (i != reqpage) {
+ vm_page_free(m[i]);
+ }
+ }
}
/*
@@ -967,7 +957,7 @@ swap_pager_getpages(object, m, count, reqpage)
return (VM_PAGER_FAIL);
}
for (j = i; j < count; j++) {
- swap_pager_freepage(m[j]);
+ vm_page_free(m[j]);
}
count = i;
break;
@@ -997,7 +987,7 @@ swap_pager_getpages(object, m, count, reqpage)
(reqaddr[i] != (reqaddr[reqpage] + (i - reqpage) * btodb(PAGE_SIZE))) ||
((reqaddr[i] / dmmax) != reqdskregion)) {
failed = 1;
- swap_pager_freepage(m[i]);
+ vm_page_free(m[i]);
if (first == 0)
first = i + 1;
}
@@ -1013,7 +1003,7 @@ swap_pager_getpages(object, m, count, reqpage)
(reqaddr[i] != (reqaddr[reqpage] + (i - reqpage) * btodb(PAGE_SIZE))) ||
((reqaddr[i] / dmmax) != reqdskregion)) {
failed = 1;
- swap_pager_freepage(m[i]);
+ vm_page_free(m[i]);
if (last == count)
last = i;
}
@@ -1427,7 +1417,6 @@ swap_pager_putpages(object, m, count, sync, rtvals)
bp->b_bcount = PAGE_SIZE * ix;
bp->b_bufsize = PAGE_SIZE * ix;
-
s = splvm();
swapdev_vp->v_numoutput++;
@@ -1560,7 +1549,7 @@ swap_pager_sync()
return;
}
-static void
+void
swap_pager_finish(spc)
register swp_clean_t spc;
{
@@ -1569,7 +1558,7 @@ swap_pager_finish(spc)
vm_page_t *ma;
ma = spc->spc_m;
- object = ma[spc->spc_first]->object;
+ object = spc->spc_object;
lastidx = spc->spc_first + spc->spc_count;
s = splvm();
@@ -1589,6 +1578,8 @@ swap_pager_finish(spc)
printf("swap_pager_finish: I/O error, clean of page %lx failed\n",
(u_long) VM_PAGE_TO_PHYS(ma[i]));
ma[i]->dirty = VM_PAGE_BITS_ALL;
+ ma[i]->flags |= PG_BUSY;
+ ma[i]->busy--;
PAGE_WAKEUP(ma[i]);
}
@@ -1603,8 +1594,9 @@ swap_pager_finish(spc)
for (i = spc->spc_first; i < lastidx; i++) {
if ((ma[i]->queue != PQ_ACTIVE) &&
((ma[i]->flags & PG_WANTED) ||
- pmap_ts_referenced(VM_PAGE_TO_PHYS(ma[i]))))
+ pmap_ts_referenced(VM_PAGE_TO_PHYS(ma[i])))) {
vm_page_activate(ma[i]);
+ }
}
}
@@ -1622,16 +1614,18 @@ static void
swap_pager_iodone(bp)
register struct buf *bp;
{
- int i, s;
+ int i, s, lastidx;
register swp_clean_t spc;
vm_object_t object;
+ vm_page_t *ma;
+
s = splvm();
spc = (swp_clean_t) bp->b_spc;
TAILQ_REMOVE(&swap_pager_inuse, spc, spc_list);
TAILQ_INSERT_TAIL(&swap_pager_done, spc, spc_list);
- object = bp->b_pages[0]->object;
+ object = spc->spc_object;
#if defined(DIAGNOSTIC)
if (object->paging_in_progress < spc->spc_count)
@@ -1645,19 +1639,22 @@ swap_pager_iodone(bp)
(bp->b_flags & B_READ) ? "pagein" : "pageout",
(u_long) bp->b_blkno, bp->b_bcount, bp->b_error);
} else {
- for (i = 0; i < bp->b_npages; i++) {
- /*
- * we wakeup any processes that are waiting on these pages.
- */
- PAGE_WAKEUP(bp->b_pages[i]);
- }
-
object->paging_in_progress -= spc->spc_count;
if ((object->paging_in_progress == 0) &&
(object->flags & OBJ_PIPWNT)) {
object->flags &= ~OBJ_PIPWNT;
wakeup(object);
}
+ ma = spc->spc_m;
+ lastidx = spc->spc_first + spc->spc_count;
+ for (i = spc->spc_first; i < lastidx; i++) {
+ /*
+ * we wakeup any processes that are waiting on these pages.
+ */
+ ma[i]->flags |= PG_BUSY;
+ ma[i]->busy--;
+ PAGE_WAKEUP(ma[i]);
+ }
}
if (bp->b_vp)
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index bb352bc..a986aeb 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -66,7 +66,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_fault.c,v 1.79 1998/02/06 12:14:22 eivind Exp $
+ * $Id: vm_fault.c,v 1.80 1998/02/09 06:11:23 eivind Exp $
*/
/*
@@ -139,6 +139,7 @@ vm_fault(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type, int fault_flags)
vm_page_t marray[VM_FAULT_READ];
int hardfault = 0;
int faultcount;
+ int pagewaitbits;
struct vnode *vp = NULL;
struct proc *p = curproc; /* XXX */
@@ -181,6 +182,7 @@ vm_fault(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type, int fault_flags)
}
+ pagewaitbits = PG_BUSY;
RetryFault:;
faultcount = 0;
@@ -286,7 +288,6 @@ RetryFault:;
/*
* See whether this page is resident
*/
-
while (TRUE) {
if (object->flags & OBJ_DEAD) {
@@ -301,12 +302,12 @@ RetryFault:;
* If the page is being brought in, wait for it and
* then retry.
*/
- if ((m->flags & PG_BUSY) || m->busy) {
+ if ((m->flags & PG_BUSY) || (m->busy && (m->valid & VM_PAGE_BITS_ALL) != VM_PAGE_BITS_ALL)) {
int s;
UNLOCK_THINGS;
s = splvm();
- if (((m->flags & PG_BUSY) || m->busy)) {
+ if ((m->flags & PG_BUSY) || (m->busy && (m->valid & VM_PAGE_BITS_ALL) != VM_PAGE_BITS_ALL)) {
m->flags |= PG_WANTED | PG_REFERENCED;
cnt.v_intrans++;
tsleep(m, PSWP, "vmpfw", 0);
@@ -331,11 +332,11 @@ RetryFault:;
}
m->flags |= PG_BUSY;
-
if (((m->valid & VM_PAGE_BITS_ALL) != VM_PAGE_BITS_ALL) &&
m->object != kernel_object && m->object != kmem_object) {
goto readrest;
}
+
break;
}
if (((object->type != OBJT_DEFAULT) &&
@@ -398,7 +399,7 @@ readrest:
if (mt == NULL || (mt->valid != VM_PAGE_BITS_ALL))
break;
if (mt->busy ||
- (mt->flags & (PG_BUSY|PG_FICTITIOUS)) ||
+ (mt->flags & (PG_BUSY | PG_FICTITIOUS)) ||
mt->hold_count ||
mt->wire_count)
continue;
diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c
index 2f4485a..179a9cc 100644
--- a/sys/vm/vm_kern.c
+++ b/sys/vm/vm_kern.c
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_kern.c,v 1.44 1998/02/06 12:14:23 eivind Exp $
+ * $Id: vm_kern.c,v 1.45 1998/02/23 08:22:29 dyson Exp $
*/
/*
@@ -182,7 +182,7 @@ kmem_alloc(map, size)
VM_ALLOC_ZERO | VM_ALLOC_RETRY);
if ((mem->flags & PG_ZERO) == 0)
vm_page_zero_fill(mem);
- mem->flags &= ~(PG_BUSY|PG_ZERO);
+ mem->flags &= ~(PG_BUSY | PG_ZERO);
mem->valid = VM_PAGE_BITS_ALL;
}
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index ad339d4..fd63b8d 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_object.c,v 1.113 1998/02/09 06:11:30 eivind Exp $
+ * $Id: vm_object.c,v 1.114 1998/02/25 03:55:50 dyson Exp $
*/
/*
@@ -334,20 +334,19 @@ vm_object_deallocate(object)
robject->ref_count++;
retry:
- if (robject->paging_in_progress || object->paging_in_progress) {
+ if (robject->paging_in_progress ||
+ object->paging_in_progress) {
vm_object_pip_sleep(robject, "objde1");
- if (robject->paging_in_progress) {
- if (robject->type == OBJT_SWAP) {
- swap_pager_sync();
- goto retry;
- }
+ if (robject->paging_in_progress &&
+ robject->type == OBJT_SWAP) {
+ swap_pager_sync();
+ goto retry;
}
vm_object_pip_sleep(object, "objde2");
- if (object->paging_in_progress) {
- if (object->type == OBJT_SWAP) {
- swap_pager_sync();
- }
+ if (object->paging_in_progress &&
+ object->type == OBJT_SWAP) {
+ swap_pager_sync();
}
goto retry;
}
@@ -569,7 +568,7 @@ rescan:
s = splvm();
while ((p->flags & PG_BUSY) || p->busy) {
- p->flags |= PG_WANTED|PG_REFERENCED;
+ p->flags |= PG_WANTED | PG_REFERENCED;
tsleep(p, PVM, "vpcwai", 0);
if (object->generation != curgeneration) {
splx(s);
@@ -581,7 +580,8 @@ rescan:
for(i=1;i<vm_pageout_page_count;i++) {
if (tp = vm_page_lookup(object, pi + i)) {
if ((tp->flags & PG_BUSY) ||
- (tp->flags & PG_CLEANCHK) == 0)
+ (tp->flags & PG_CLEANCHK) == 0 ||
+ (tp->busy != 0))
break;
if((tp->queue - tp->pc) == PQ_CACHE) {
tp->flags &= ~PG_CLEANCHK;
@@ -605,7 +605,8 @@ rescan:
for(i = 1; i < chkb;i++) {
if (tp = vm_page_lookup(object, pi - i)) {
if ((tp->flags & PG_BUSY) ||
- (tp->flags & PG_CLEANCHK) == 0)
+ (tp->flags & PG_CLEANCHK) == 0 ||
+ (tp->busy != 0))
break;
if((tp->queue - tp->pc) == PQ_CACHE) {
tp->flags &= ~PG_CLEANCHK;
@@ -810,15 +811,8 @@ shadowlookup:
continue;
}
- if (m->busy || (m->flags & PG_BUSY)) {
- s = splvm();
- if (m->busy || (m->flags & PG_BUSY)) {
- m->flags |= PG_WANTED;
- tsleep(m, PVM, "madvpw", 0);
- }
- splx(s);
- goto relookup;
- }
+ if (vm_page_sleep(m, "madvpo", &m->busy))
+ goto relookup;
if (advise == MADV_WILLNEED) {
vm_page_activate(m);
@@ -1200,9 +1194,8 @@ vm_object_collapse(object)
for (p = TAILQ_FIRST(&backing_object->memq); p;
p = TAILQ_NEXT(p, listq)) {
- p->flags |= PG_BUSY;
-
new_pindex = p->pindex - backing_offset_index;
+ p->flags |= PG_BUSY;
/*
* If the parent has a page here, or if this
@@ -1317,16 +1310,9 @@ again:
* The busy flags are only cleared at
* interrupt -- minimize the spl transitions
*/
- if ((p->flags & PG_BUSY) || p->busy) {
- s = splvm();
- if ((p->flags & PG_BUSY) || p->busy) {
- p->flags |= PG_WANTED;
- tsleep(p, PVM, "vmopar", 0);
- splx(s);
- goto again;
- }
- splx(s);
- }
+
+ if (vm_page_sleep(p, "vmopar", &p->busy))
+ goto again;
if (clean_only) {
vm_page_test_dirty(p);
@@ -1355,16 +1341,8 @@ again:
* The busy flags are only cleared at
* interrupt -- minimize the spl transitions
*/
- if ((p->flags & PG_BUSY) || p->busy) {
- s = splvm();
- if ((p->flags & PG_BUSY) || p->busy) {
- p->flags |= PG_WANTED;
- tsleep(p, PVM, "vmopar", 0);
- splx(s);
- goto again;
- }
- splx(s);
- }
+ if (vm_page_sleep(p, "vmopar", &p->busy))
+ goto again;
if (clean_only) {
vm_page_test_dirty(p);
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index c9edfd8..439fc3d 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)vm_page.c 7.4 (Berkeley) 5/7/91
- * $Id: vm_page.c,v 1.92 1998/02/06 12:14:27 eivind Exp $
+ * $Id: vm_page.c,v 1.93 1998/02/09 06:11:32 eivind Exp $
*/
/*
@@ -917,7 +917,7 @@ vm_page_alloc(object, pindex, page_req)
(*pq->lcnt)--;
oldobject = NULL;
if (qtype == PQ_ZERO) {
- m->flags = PG_ZERO|PG_BUSY;
+ m->flags = PG_ZERO | PG_BUSY;
} else if (qtype == PQ_CACHE) {
oldobject = m->object;
m->flags |= PG_BUSY;
@@ -983,6 +983,22 @@ vm_wait()
splx(s);
}
+int
+vm_page_sleep(vm_page_t m, char *msg, char *busy) {
+ vm_object_t object = m->object;
+ int generation = object->generation;
+ if ((busy && *busy) || (m->flags & PG_BUSY)) {
+ int s;
+ s = splvm();
+ if ((busy && *busy) || (m->flags & PG_BUSY)) {
+ m->flags |= PG_WANTED;
+ tsleep(m, PVM, msg, 800);
+ }
+ splx(s);
+ }
+ return ((generation != object->generation) || (busy && *busy) ||
+ (m->flags & PG_BUSY));
+}
/*
* vm_page_activate:
@@ -1058,6 +1074,8 @@ vm_page_freechk_and_unqueue(m)
return 0;
}
+ m->valid = 0;
+
if (m->wire_count != 0) {
#if !defined(MAX_PERF)
if (m->wire_count > 1) {
@@ -1516,11 +1534,8 @@ again1:
}
next = TAILQ_NEXT(m, pageq);
- if (m->flags & PG_BUSY) {
- m->flags |= PG_WANTED;
- tsleep(m, PVM, "vpctw0", 0);
+ if (vm_page_sleep(m, "vpctw0", &m->busy))
goto again1;
- }
vm_page_test_dirty(m);
if (m->dirty) {
if (m->object->type == OBJT_VNODE) {
@@ -1530,6 +1545,7 @@ again1:
goto again1;
} else if (m->object->type == OBJT_SWAP ||
m->object->type == OBJT_DEFAULT) {
+ m->flags |= PG_BUSY;
vm_page_protect(m, VM_PROT_NONE);
vm_pageout_flush(&m, 1, 0);
goto again1;
@@ -1548,11 +1564,8 @@ again1:
}
next = TAILQ_NEXT(m, pageq);
- if (m->flags & PG_BUSY) {
- m->flags |= PG_WANTED;
- tsleep(m, PVM, "vpctw1", 0);
+ if (vm_page_sleep(m, "vpctw1", &m->busy))
goto again1;
- }
vm_page_test_dirty(m);
if (m->dirty) {
if (m->object->type == OBJT_VNODE) {
@@ -1562,6 +1575,7 @@ again1:
goto again1;
} else if (m->object->type == OBJT_SWAP ||
m->object->type == OBJT_DEFAULT) {
+ m->flags |= PG_BUSY;
vm_page_protect(m, VM_PROT_NONE);
vm_pageout_flush(&m, 1, 0);
goto again1;
diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h
index 8a819bb..b9241dc 100644
--- a/sys/vm/vm_page.h
+++ b/sys/vm/vm_page.h
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_page.h,v 1.35 1997/02/22 09:48:32 peter Exp $
+ * $Id: vm_page.h,v 1.36 1998/02/05 03:32:47 dyson Exp $
*/
/*
@@ -264,17 +264,17 @@ extern vm_offset_t last_phys_addr; /* physical address for last_page */
*/
#define PAGE_ASSERT_WAIT(m, interruptible) { \
- (m)->flags |= PG_WANTED; \
- assert_wait((int) (m), (interruptible)); \
- }
+ (m)->flags |= PG_WANTED; \
+ assert_wait((int) (m), (interruptible)); \
+}
#define PAGE_WAKEUP(m) { \
- (m)->flags &= ~PG_BUSY; \
- if ((m)->flags & PG_WANTED) { \
- (m)->flags &= ~PG_WANTED; \
- wakeup((caddr_t) (m)); \
- } \
- }
+ (m)->flags &= ~PG_BUSY; \
+ if (((m)->flags & PG_WANTED) && ((m)->busy == 0)) { \
+ (m)->flags &= ~PG_WANTED; \
+ wakeup((m)); \
+ } \
+}
#if PAGE_SIZE == 4096
#define VM_PAGE_BITS_ALL 0xff
@@ -316,6 +316,7 @@ int vm_page_bits __P((int, int));
vm_page_t vm_page_list_find __P((int, int));
int vm_page_queue_index __P((vm_offset_t, int));
vm_page_t vm_page_select __P((vm_object_t, vm_pindex_t, int));
+int vm_page_sleep(vm_page_t m, char *msg, char *busy);
/*
* Keep page from being freed by the page daemon
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index 6eb7927..b614c3d 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -65,7 +65,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_pageout.c,v 1.115 1998/02/23 08:22:37 dyson Exp $
+ * $Id: vm_pageout.c,v 1.116 1998/02/24 10:16:23 dyson Exp $
*/
/*
@@ -190,7 +190,7 @@ SYSCTL_INT(_vm, OID_AUTO, max_page_launder,
CTLFLAG_RW, &max_page_launder, 0, "");
-#define VM_PAGEOUT_PAGE_COUNT 8
+#define VM_PAGEOUT_PAGE_COUNT 16
int vm_pageout_page_count = VM_PAGEOUT_PAGE_COUNT;
int vm_page_max_wired; /* XXX max # of wired pages system-wide */
@@ -352,7 +352,7 @@ do_backward:
* we allow reads during pageouts...
*/
for (i = page_base; i < (page_base + pageout_count); i++) {
- mc[i]->flags |= PG_BUSY;
+ mc[i]->busy++;
vm_page_protect(mc[i], VM_PROT_READ);
}
@@ -409,7 +409,6 @@ vm_pageout_flush(mc, count, sync)
break;
}
-
/*
* If the operation is still going, leave the page busy to
* block all other accesses. Also, leave the paging in
@@ -418,6 +417,8 @@ vm_pageout_flush(mc, count, sync)
*/
if (pageout_status[i] != VM_PAGER_PEND) {
vm_object_pip_wakeup(object);
+ mt->flags |= PG_BUSY;
+ mt->busy--;
PAGE_WAKEUP(mt);
}
}
diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c
index ae934c1..33c69a3 100644
--- a/sys/vm/vnode_pager.c
+++ b/sys/vm/vnode_pager.c
@@ -38,7 +38,7 @@
* SUCH DAMAGE.
*
* from: @(#)vnode_pager.c 7.5 (Berkeley) 4/20/91
- * $Id: vnode_pager.c,v 1.86 1998/02/25 03:55:53 dyson Exp $
+ * $Id: vnode_pager.c,v 1.87 1998/02/26 06:39:58 msmith Exp $
*/
/*
@@ -893,15 +893,8 @@ vnode_pager_generic_putpages(vp, m, bytecount, sync, rtvals)
printf("vnode_pager_putpages: residual I/O %d at %ld\n",
auio.uio_resid, m[0]->pindex);
}
- for (i = 0; i < count; i++) {
- m[i]->busy--;
- if (i < ncount) {
- rtvals[i] = VM_PAGER_OK;
- }
- if ((m[i]->busy == 0) && (m[i]->flags & PG_WANTED)) {
- vm_page_activate(m[i]);
- wakeup(m[i]);
- }
+ for (i = 0; i < ncount; i++) {
+ rtvals[i] = VM_PAGER_OK;
}
return rtvals[0];
}
OpenPOWER on IntegriCloud