diff options
author | dyson <dyson@FreeBSD.org> | 1995-11-05 20:46:03 +0000 |
---|---|---|
committer | dyson <dyson@FreeBSD.org> | 1995-11-05 20:46:03 +0000 |
commit | 1b8e5404ee43d51a47f50d452f1f170f3ca57b22 (patch) | |
tree | 4b5a3508979357f31fb77292bfa5c2930e8ba243 /sys/vm/vm_object.c | |
parent | d461b5899dc0ba4686df948588f1fb15f2133fb7 (diff) | |
download | FreeBSD-src-1b8e5404ee43d51a47f50d452f1f170f3ca57b22.zip FreeBSD-src-1b8e5404ee43d51a47f50d452f1f170f3ca57b22.tar.gz |
Greatly simplify the msync code. Eliminate complications in vm_pageout
for msyncing. Remove a bug that manifests itself primarily on NFS
(the dirty range on the buffers is not set on msync.)
Diffstat (limited to 'sys/vm/vm_object.c')
-rw-r--r-- | sys/vm/vm_object.c | 171 |
1 files changed, 61 insertions, 110 deletions
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index b6f3954..2a01901 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.53 1995/08/26 23:19:48 bde Exp $ + * $Id: vm_object.c,v 1.54 1995/10/23 03:49:43 dyson Exp $ */ /* @@ -121,6 +121,7 @@ vm_object_t kernel_object; vm_object_t kmem_object; struct vm_object kernel_object_store; struct vm_object kmem_object_store; +extern int vm_pageout_page_count; long object_collapses; long object_bypasses; @@ -423,26 +424,26 @@ vm_object_page_clean(object, start, end, syncio, lockflag) { register vm_page_t p; register vm_offset_t tstart, tend; - int pass; - int pgcount, s; - int allclean; - int entireobj; + int s; struct vnode *vp; + int runlen; + vm_page_t ma[vm_pageout_page_count]; - if (object->type != OBJT_VNODE || (object->flags & OBJ_WRITEABLE) == 0) + if (object->type != OBJT_VNODE || + (object->flags & OBJ_MIGHTBEDIRTY) == 0) return; vp = object->handle; if (lockflag) VOP_LOCK(vp); + object->flags |= OBJ_CLEANING; if (start != end) { start = trunc_page(start); end = round_page(end); } - pass = 0; startover: tstart = start; if (end == 0) { @@ -450,108 +451,72 @@ startover: } else { tend = end; } - entireobj = 0; if (tstart == 0 && tend == object->size) { - object->flags &= ~OBJ_WRITEABLE; - entireobj = 1; + object->flags &= ~(OBJ_WRITEABLE|OBJ_MIGHTBEDIRTY); } - pgcount = object->resident_page_count; - - if (pass == 0 && - (pgcount < 128 || pgcount > (object->size / (8 * PAGE_SIZE)))) { - allclean = 1; - for(; pgcount && (tstart < tend); tstart += PAGE_SIZE) { - p = vm_page_lookup(object, tstart); - if (!p) - continue; - --pgcount; - s = splhigh(); - TAILQ_REMOVE(&object->memq, p, listq); - TAILQ_INSERT_TAIL(&object->memq, p, listq); - splx(s); - if (entireobj) - vm_page_protect(p, VM_PROT_READ); - if ((p->flags & (PG_BUSY|PG_CACHE)) || p->busy || - p->valid == 0) { - continue; - } - vm_page_test_dirty(p); - if ((p->valid & p->dirty) != 0) { - vm_offset_t tincr; - tincr = vm_pageout_clean(p, VM_PAGEOUT_FORCE); - if( tincr) { - pgcount -= (tincr - 1); - tincr *= PAGE_SIZE; - tstart += tincr - PAGE_SIZE; - } - allclean = 0; + runlen = 0; + for(;tstart < tend; tstart += PAGE_SIZE) { +relookup: + p = vm_page_lookup(object, tstart); + if (!p) { + if (runlen > 0) { + vm_pageout_flush(ma, runlen, syncio); + runlen = 0; } + continue; } - if (!allclean) { - pass = 1; - goto startover; - } - if (lockflag) - VOP_UNLOCK(vp); - return; - } - - allclean = 1; - while ((p = object->memq.tqh_first) != NULL && pgcount > 0) { - - if (p->flags & PG_CACHE) { - goto donext; + if (p->valid == 0 || (p->flags & PG_CACHE)) { + if (runlen > 0) { + vm_pageout_flush(ma, runlen, syncio); + runlen = 0; + } + continue; } - if (entireobj || (p->offset >= tstart && p->offset < tend)) { - if (entireobj) - vm_page_protect(p, VM_PROT_READ); - - if (p->valid == 0) { - goto donext; - } + vm_page_protect(p, VM_PROT_READ); - s = splhigh(); - if ((p->flags & PG_BUSY) || p->busy) { - allclean = 0; - if (pass > 0) { - p->flags |= PG_WANTED; - tsleep(p, PVM, "objpcn", 0); - splx(s); - continue; - } else { - splx(s); - goto donext; - } + s = splhigh(); + while ((p->flags & PG_BUSY) || p->busy) { + if (runlen > 0) { + splx(s); + vm_pageout_flush(ma, runlen, syncio); + runlen = 0; + goto relookup; } - - TAILQ_REMOVE(&object->memq, p, listq); - TAILQ_INSERT_TAIL(&object->memq, p, listq); + p->flags |= PG_WANTED|PG_REFERENCED; + tsleep(p, PVM, "vpcwai", 0); splx(s); + goto relookup; + } + splx(s); - pgcount--; + if (p->dirty == 0) vm_page_test_dirty(p); - if ((p->valid & p->dirty) != 0) { - vm_pageout_clean(p, VM_PAGEOUT_FORCE); - allclean = 0; + + if ((p->valid & p->dirty) != 0) { + ma[runlen] = p; + p->flags |= PG_BUSY; + runlen++; + if (runlen >= vm_pageout_page_count) { + vm_pageout_flush(ma, runlen, syncio); + runlen = 0; } - continue; + } else if (runlen > 0) { + vm_pageout_flush(ma, runlen, syncio); + runlen = 0; } - donext: - TAILQ_REMOVE(&object->memq, p, listq); - TAILQ_INSERT_TAIL(&object->memq, p, listq); - pgcount--; + } - if ((!allclean && (pass == 0)) || - (entireobj && (object->flags & OBJ_WRITEABLE))) { - pass = 1; - if (entireobj) - object->flags &= ~OBJ_WRITEABLE; - goto startover; + if (runlen > 0) { + vm_pageout_flush(ma, runlen, syncio); } + + VOP_FSYNC(vp, NULL, syncio, curproc); + if (lockflag) VOP_UNLOCK(vp); + object->flags &= ~OBJ_CLEANING; return; } @@ -609,14 +574,14 @@ vm_object_pmap_copy(object, start, end) { register vm_page_t p; - if (object == NULL) + if (object == NULL || (object->flags & OBJ_WRITEABLE) == 0) return; for (p = object->memq.tqh_first; p != NULL; p = p->listq.tqe_next) { - if ((start <= p->offset) && (p->offset < end)) { - vm_page_protect(p, VM_PROT_READ); - } + vm_page_protect(p, VM_PROT_READ); } + + object->flags &= ~OBJ_WRITEABLE; } /* @@ -638,23 +603,9 @@ vm_object_pmap_remove(object, start, end) if (object == NULL) return; - ++object->paging_in_progress; - -again: for (p = object->memq.tqh_first; p != NULL; p = p->listq.tqe_next) { - if ((start <= p->offset) && (p->offset < end)) { - s = splhigh(); - if ((p->flags & PG_BUSY) || p->busy) { - p->flags |= PG_WANTED; - tsleep(p, PVM, "vmopmr", 0); - splx(s); - goto again; - } - splx(s); - vm_page_protect(p, VM_PROT_NONE); - } + vm_page_protect(p, VM_PROT_NONE); } - vm_object_pip_wakeup(object); } /* |