diff options
author | dyson <dyson@FreeBSD.org> | 1997-12-19 09:03:37 +0000 |
---|---|---|
committer | dyson <dyson@FreeBSD.org> | 1997-12-19 09:03:37 +0000 |
commit | 6bd1f74dcf56a424893fe1175291006b3107adff (patch) | |
tree | 09b494586a427ed4a21b1017399c6c22d1198fd9 | |
parent | 47b91b0d8abca4e003acc0ff741437c1c44deb38 (diff) | |
download | FreeBSD-src-6bd1f74dcf56a424893fe1175291006b3107adff.zip FreeBSD-src-6bd1f74dcf56a424893fe1175291006b3107adff.tar.gz |
Some performance improvements, and code cleanups (including changing our
expensive OFF_TO_IDX to btoc whenever possible.)
-rw-r--r-- | sys/kern/kern_subr.c | 77 | ||||
-rw-r--r-- | sys/kern/vfs_export.c | 6 | ||||
-rw-r--r-- | sys/kern/vfs_subr.c | 6 | ||||
-rw-r--r-- | sys/sys/uio.h | 5 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_readwrite.c | 33 | ||||
-rw-r--r-- | sys/vm/vm_fault.c | 9 | ||||
-rw-r--r-- | sys/vm/vm_map.c | 314 | ||||
-rw-r--r-- | sys/vm/vm_map.h | 4 | ||||
-rw-r--r-- | sys/vm/vm_object.c | 35 | ||||
-rw-r--r-- | sys/vm/vm_object.h | 7 | ||||
-rw-r--r-- | sys/vm/vnode_pager.c | 14 |
11 files changed, 479 insertions, 31 deletions
diff --git a/sys/kern/kern_subr.c b/sys/kern/kern_subr.c index ba6e43b..cae8521 100644 --- a/sys/kern/kern_subr.c +++ b/sys/kern/kern_subr.c @@ -36,13 +36,19 @@ * SUCH DAMAGE. * * @(#)kern_subr.c 8.3 (Berkeley) 1/21/94 - * $Id: kern_subr.c,v 1.12 1997/09/02 20:05:42 bde Exp $ + * $Id: kern_subr.c,v 1.13 1997/10/10 18:14:23 phk Exp $ */ #include <sys/param.h> #include <sys/systm.h> #include <sys/proc.h> #include <sys/malloc.h> +#include <sys/lock.h> + +#include <vm/vm.h> +#include <vm/vm_prot.h> +#include <vm/vm_page.h> +#include <vm/vm_map.h> int uiomove(cp, n, uio) @@ -102,6 +108,75 @@ uiomove(cp, n, uio) return (0); } +int +uiomoveco(cp, n, uio, obj) + caddr_t cp; + int n; + struct uio *uio; + struct vm_object *obj; +{ + struct iovec *iov; + u_int cnt; + int error; + +#ifdef DIAGNOSTIC + if (uio->uio_rw != UIO_READ && uio->uio_rw != UIO_WRITE) + panic("uiomove: mode"); + if (uio->uio_segflg == UIO_USERSPACE && uio->uio_procp != curproc) + panic("uiomove proc"); +#endif + while (n > 0 && uio->uio_resid) { + iov = uio->uio_iov; + cnt = iov->iov_len; + if (cnt == 0) { + uio->uio_iov++; + uio->uio_iovcnt--; + continue; + } + if (cnt > n) + cnt = n; + + switch (uio->uio_segflg) { + + case UIO_USERSPACE: + case UIO_USERISPACE: + if (uio->uio_rw == UIO_READ) { + if (((cnt & PAGE_MASK) == 0) && + ((((int) iov->iov_base) & PAGE_MASK) == 0) && + ((uio->uio_offset & PAGE_MASK) == 0) && + ((((int) cp) & PAGE_MASK) == 0)) { + error = vm_uiomove(&curproc->p_vmspace->vm_map, obj, + uio->uio_offset, cnt, + (vm_offset_t) iov->iov_base); + } else { + error = copyout(cp, iov->iov_base, cnt); + } + } else { + error = copyin(iov->iov_base, cp, cnt); + } + if (error) + return (error); + break; + + case UIO_SYSSPACE: + if (uio->uio_rw == UIO_READ) + bcopy((caddr_t)cp, iov->iov_base, cnt); + else + bcopy(iov->iov_base, (caddr_t)cp, cnt); + break; + case UIO_NOCOPY: + break; + } + iov->iov_base += cnt; + iov->iov_len -= cnt; + uio->uio_resid -= cnt; + uio->uio_offset += cnt; + cp += cnt; + n -= cnt; + } + return (0); +} + /* * Give next character to user as result of read. */ diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c index c978bbf..c2e5369 100644 --- a/sys/kern/vfs_export.c +++ b/sys/kern/vfs_export.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95 - * $Id: vfs_subr.c,v 1.114 1997/11/22 08:35:39 bde Exp $ + * $Id: vfs_subr.c,v 1.115 1997/12/15 03:09:32 wollman Exp $ */ /* @@ -63,6 +63,8 @@ #include <vm/vm.h> #include <vm/vm_object.h> #include <vm/vm_extern.h> +#include <vm/pmap.h> +#include <vm/vm_map.h> #include <vm/vnode_pager.h> #include <sys/sysctl.h> @@ -921,6 +923,8 @@ vputrele(vp, put) if ((vp->v_usecount == 2) && vp->v_object && (vp->v_object->flags & OBJ_VFS_REF)) { + + vm_freeze_copyopts(vp->v_object, 0, vp->v_object->size); vp->v_usecount--; vp->v_object->flags &= ~OBJ_VFS_REF; if (put) { diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index c978bbf..c2e5369 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95 - * $Id: vfs_subr.c,v 1.114 1997/11/22 08:35:39 bde Exp $ + * $Id: vfs_subr.c,v 1.115 1997/12/15 03:09:32 wollman Exp $ */ /* @@ -63,6 +63,8 @@ #include <vm/vm.h> #include <vm/vm_object.h> #include <vm/vm_extern.h> +#include <vm/pmap.h> +#include <vm/vm_map.h> #include <vm/vnode_pager.h> #include <sys/sysctl.h> @@ -921,6 +923,8 @@ vputrele(vp, put) if ((vp->v_usecount == 2) && vp->v_object && (vp->v_object->flags & OBJ_VFS_REF)) { + + vm_freeze_copyopts(vp->v_object, 0, vp->v_object->size); vp->v_usecount--; vp->v_object->flags &= ~OBJ_VFS_REF; if (put) { diff --git a/sys/sys/uio.h b/sys/sys/uio.h index 3059415..ab577fc 100644 --- a/sys/sys/uio.h +++ b/sys/sys/uio.h @@ -31,12 +31,14 @@ * SUCH DAMAGE. * * @(#)uio.h 8.5 (Berkeley) 2/22/94 - * $Id$ + * $Id: uio.h,v 1.6 1997/02/22 09:46:19 peter Exp $ */ #ifndef _SYS_UIO_H_ #define _SYS_UIO_H_ +struct vm_object; + /* * XXX * iov_base should be a void *. @@ -77,6 +79,7 @@ struct uio { #ifdef KERNEL int uiomove __P((caddr_t, int, struct uio *)); +int uiomoveco __P((caddr_t, int, struct uio *, struct vm_object *)); #else /* !KERNEL */ diff --git a/sys/ufs/ufs/ufs_readwrite.c b/sys/ufs/ufs/ufs_readwrite.c index 9383f23..81dc742 100644 --- a/sys/ufs/ufs/ufs_readwrite.c +++ b/sys/ufs/ufs/ufs_readwrite.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)ufs_readwrite.c 8.11 (Berkeley) 5/8/95 - * $Id: ufs_readwrite.c,v 1.34 1997/12/15 03:09:54 wollman Exp $ + * $Id: ufs_readwrite.c,v 1.35 1997/12/16 22:28:26 eivind Exp $ */ #ifdef LFS_READWRITE @@ -54,9 +54,16 @@ #define WRITE_S "ffs_write" #include <vm/vm.h> #include <vm/vm_pager.h> +#include <vm/vm_map.h> #include <vm/vnode_pager.h> #endif #include <sys/poll.h> +#include <sys/sysctl.h> + +int vfs_ioopt = 1; + +SYSCTL_INT(_vfs, OID_AUTO, ioopt, + CTLFLAG_RW, &vfs_ioopt, 0, ""); /* * Vnode op for reading. @@ -154,8 +161,20 @@ READ(ap) break; xfersize = size; } - error = - uiomove((char *)bp->b_data + blkoffset, (int)xfersize, uio); + + if (vfs_ioopt && + (bp->b_flags & B_VMIO) && + ((blkoffset & PAGE_MASK) == 0) && + ((xfersize & PAGE_MASK) == 0)) { + error = + uiomoveco((char *)bp->b_data + blkoffset, + (int)xfersize, uio, vp->v_object); + } else { + error = + uiomove((char *)bp->b_data + blkoffset, + (int)xfersize, uio); + } + if (error) break; @@ -273,6 +292,14 @@ WRITE(ap) if (size < xfersize) xfersize = size; + if (vfs_ioopt && + vp->v_object && (vp->v_object->flags & OBJ_OPT) && + vp->v_object->shadow_count) { + vm_freeze_copyopts(vp->v_object, + OFF_TO_IDX(uio->uio_offset), + OFF_TO_IDX(uio->uio_offset + size)); + } + error = uiomove((char *)bp->b_data + blkoffset, (int)xfersize, uio); #ifdef LFS_READWRITE diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 7d67efa..a14512d 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.70 1997/08/25 22:15:19 bde Exp $ + * $Id: vm_fault.c,v 1.71 1997/09/01 03:17:15 bde Exp $ */ /* @@ -202,7 +202,8 @@ RetryFault:; * to COW .text. We simply keep .text from ever being COW'ed * and take the heat that one cannot debug wired .text sections. */ - if (((fault_flags & VM_FAULT_WIRE_MASK) == VM_FAULT_USER_WIRE) && (entry->eflags & MAP_ENTRY_NEEDS_COPY)) { + if (((fault_flags & VM_FAULT_WIRE_MASK) == VM_FAULT_USER_WIRE) && + (entry->eflags & MAP_ENTRY_NEEDS_COPY)) { if(entry->protection & VM_PROT_WRITE) { int tresult; vm_map_lookup_done(map, entry); @@ -222,6 +223,10 @@ RetryFault:; } vp = vnode_pager_lock(first_object); + if ((fault_type & VM_PROT_WRITE) && + (first_object->type == OBJT_VNODE)) { + vm_freeze_copyopts(first_object, first_pindex, first_pindex + 1); + } lookup_still_valid = TRUE; diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index ae4eef9..a187106 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -61,7 +61,7 @@ * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. * - * $Id: vm_map.c,v 1.97 1997/11/14 23:42:10 tegge Exp $ + * $Id: vm_map.c,v 1.98 1997/11/24 15:03:13 bde Exp $ */ /* @@ -74,6 +74,8 @@ #include <sys/proc.h> #include <sys/vmmeter.h> #include <sys/mman.h> +#include <sys/buf.h> +#include <sys/vnode.h> #include <vm/vm.h> #include <vm/vm_param.h> @@ -84,6 +86,7 @@ #include <vm/vm_map.h> #include <vm/vm_page.h> #include <vm/vm_object.h> +#include <vm/vm_pageout.h> #include <vm/vm_kern.h> #include <vm/vm_extern.h> #include <vm/default_pager.h> @@ -168,6 +171,7 @@ static void vm_map_entry_dispose __P((vm_map_t, vm_map_entry_t)); static void vm_map_entry_unwire __P((vm_map_t, vm_map_entry_t)); static void vm_map_copy_entry __P((vm_map_t, vm_map_t, vm_map_entry_t, vm_map_entry_t)); +static vm_page_t vm_freeze_page_alloc __P((vm_object_t, vm_pindex_t)); void vm_map_startup() @@ -844,7 +848,7 @@ _vm_map_clip_start(map, entry, start) vm_object_t object; object = vm_object_allocate(OBJT_DEFAULT, - OFF_TO_IDX(entry->end - entry->start)); + btoc(entry->end - entry->start)); entry->object.vm_object = object; entry->offset = 0; } @@ -902,7 +906,7 @@ _vm_map_clip_end(map, entry, end) vm_object_t object; object = vm_object_allocate(OBJT_DEFAULT, - OFF_TO_IDX(entry->end - entry->start)); + btoc(entry->end - entry->start)); entry->object.vm_object = object; entry->offset = 0; } @@ -1332,7 +1336,7 @@ vm_map_user_pageable(map, start, end, new_pageable) vm_object_shadow(&entry->object.vm_object, &entry->offset, - OFF_TO_IDX(entry->end + btoc(entry->end - entry->start)); entry->eflags &= ~MAP_ENTRY_NEEDS_COPY; @@ -1340,7 +1344,7 @@ vm_map_user_pageable(map, start, end, new_pageable) entry->object.vm_object = vm_object_allocate(OBJT_DEFAULT, - OFF_TO_IDX(entry->end - entry->start)); + btoc(entry->end - entry->start)); entry->offset = (vm_offset_t) 0; } @@ -1525,13 +1529,12 @@ vm_map_pageable(map, start, end, new_pageable) vm_object_shadow(&entry->object.vm_object, &entry->offset, - OFF_TO_IDX(entry->end - - entry->start)); + btoc(entry->end - entry->start)); entry->eflags &= ~MAP_ENTRY_NEEDS_COPY; } else if (entry->object.vm_object == NULL) { entry->object.vm_object = vm_object_allocate(OBJT_DEFAULT, - OFF_TO_IDX(entry->end - entry->start)); + btoc(entry->end - entry->start)); entry->offset = (vm_offset_t) 0; } default_pager_convert_to_swapq(entry->object.vm_object); @@ -2076,13 +2079,13 @@ vmspace_fork(vm1) object = old_entry->object.vm_object; if (object == NULL) { object = vm_object_allocate(OBJT_DEFAULT, - OFF_TO_IDX(old_entry->end - old_entry->start)); + btoc(old_entry->end - old_entry->start)); old_entry->object.vm_object = object; old_entry->offset = (vm_offset_t) 0; } else if (old_entry->eflags & MAP_ENTRY_NEEDS_COPY) { vm_object_shadow(&old_entry->object.vm_object, &old_entry->offset, - OFF_TO_IDX(old_entry->end - old_entry->start)); + btoc(old_entry->end - old_entry->start)); old_entry->eflags &= ~MAP_ENTRY_NEEDS_COPY; object = old_entry->object.vm_object; } @@ -2366,7 +2369,7 @@ RetryLookup:; vm_object_shadow( &entry->object.vm_object, &entry->offset, - OFF_TO_IDX(entry->end - entry->start)); + btoc(entry->end - entry->start)); entry->eflags &= ~MAP_ENTRY_NEEDS_COPY; vm_map_lock_downgrade(share_map); @@ -2390,7 +2393,7 @@ RetryLookup:; goto RetryLookup; } entry->object.vm_object = vm_object_allocate(OBJT_DEFAULT, - OFF_TO_IDX(entry->end - entry->start)); + btoc(entry->end - entry->start)); entry->offset = 0; vm_map_lock_downgrade(share_map); } @@ -2446,6 +2449,293 @@ vm_map_lookup_done(map, entry) vm_map_unlock_read(map); } +/* + * Implement uiomove with VM operations. This handles (and collateral changes) + * support every combination of source object modification, and COW type + * operations. + */ +int +vm_uiomove(mapa, srcobject, cp, cnt, uaddra) + vm_map_t mapa; + vm_object_t srcobject; + off_t cp; + int cnt; + vm_offset_t uaddra; +{ + vm_map_t map; + vm_object_t first_object, object; + vm_map_entry_t first_entry, entry; + vm_prot_t prot; + boolean_t wired, su; + int tcnt, rv; + vm_offset_t uaddr, start, end; + vm_pindex_t first_pindex, osize, oindex; + off_t ooffset; + + while (cnt > 0) { + map = mapa; + uaddr = uaddra; + + if ((vm_map_lookup(&map, uaddr, + VM_PROT_READ|VM_PROT_WRITE, &first_entry, &first_object, + &first_pindex, &prot, &wired, &su)) != KERN_SUCCESS) { + return EFAULT; + } + +#if 0 + printf("foff: 0x%x, uaddr: 0x%x\norig entry: (0x%x, 0x%x), ", + (int) cp, uaddr, first_entry->start, first_entry->end); +#endif + + vm_map_clip_start(map, first_entry, uaddr); + + tcnt = cnt; + if ((uaddr + tcnt) > first_entry->end) + tcnt = first_entry->end - uaddr; + + vm_map_clip_end(map, first_entry, uaddr + tcnt); + + start = first_entry->start; + end = first_entry->end; +#if 0 + printf("new entry: (0x%x, 0x%x)\n", start, end); +#endif + + osize = btoc(tcnt); + oindex = OFF_TO_IDX(first_entry->offset); + +/* + * If we are changing an existing map entry, just redirect + * the object, and change mappings. + */ + if ((first_object->ref_count == 1) && + (first_object->backing_object == srcobject) && + (first_object->size == osize) && + (first_object->resident_page_count == 0)) { + + /* + * Remove old window into the file + */ + pmap_remove (map->pmap, start, end); + + /* + * Force copy on write for mmaped regions + */ + vm_object_pmap_copy_1 (first_object, + oindex, oindex + osize); + + /* + * Point the object appropriately + */ + first_object->backing_object_offset = cp; +/* + * Otherwise, we have to do a logical mmap. + */ + } else { + + object = srcobject; + object->flags |= OBJ_OPT; + object->ref_count++; + ooffset = cp; + + vm_object_shadow(&object, &ooffset, osize); + + pmap_remove (map->pmap, start, end); + vm_object_pmap_copy_1 (first_object, + oindex, oindex + osize); + vm_map_lookup_done(map, first_entry); + + vm_map_lock(map); + + if (first_entry == &map->header) { + map->first_free = &map->header; + } else if (map->first_free->start >= start) { + map->first_free = first_entry->prev; + } + + SAVE_HINT(map, first_entry->prev); + vm_map_entry_delete(map, first_entry); + + rv = vm_map_insert(map, object, 0, start, end, + VM_PROT_ALL, VM_PROT_ALL, MAP_COPY_ON_WRITE); + + if (rv != KERN_SUCCESS) + panic("vm_uiomove: could not insert new entry: %d", rv); + } + +/* + * Map the window directly, if it is already in memory + */ + pmap_object_init_pt(map->pmap, start, + srcobject, (vm_pindex_t) OFF_TO_IDX(cp), end - start, 1); + + vm_map_unlock(map); + + cnt -= tcnt; + uaddra += tcnt; + cp += tcnt; + } + return 0; +} + +/* + * local routine to allocate a page for an object. + */ +static vm_page_t +vm_freeze_page_alloc(object, pindex) + vm_object_t object; + vm_pindex_t pindex; +{ + vm_page_t m; + + while ((m = vm_page_alloc(object, pindex, VM_ALLOC_NORMAL)) == NULL) { + VM_WAIT; + if (m = vm_page_lookup(object, pindex)) + return NULL; + } + + m->valid = VM_PAGE_BITS_ALL; + m->dirty = 0; + vm_page_deactivate(m); + return m; +} + +/* + * Performs the copy_on_write operations necessary to allow the virtual copies + * into user space to work. This has to be called for write(2) system calls + * from other processes, file unlinking, and file size shrinkage. + */ +void +vm_freeze_copyopts(object, froma, toa) + vm_object_t object; + vm_pindex_t froma, toa; +{ + int s; + vm_object_t robject, robjectn; + vm_pindex_t idx, from, to; + + if ((object == NULL) || ((object->flags & OBJ_OPT) == 0)) + return; + +#if 0 + printf("sc: %d, rc: %d\n", object->shadow_count, object->ref_count); +#endif + + if (object->shadow_count > object->ref_count) + panic("vm_freeze_copyopts: sc > rc"); + + for( robject = TAILQ_FIRST(&object->shadow_head); + robject; + robject = robjectn) { + vm_pindex_t bo_pindex; + vm_pindex_t dstpindex; + vm_page_t m_in, m_out; + + robjectn = TAILQ_NEXT(robject, shadow_list); + + bo_pindex = OFF_TO_IDX(robject->backing_object_offset); + if (bo_pindex > toa) + continue; + + if ((bo_pindex + robject->size) < froma) + continue; + + robject->ref_count++; + while (robject->paging_in_progress) { + robject->flags |= OBJ_PIPWNT; + tsleep(robject, PVM, "objfrz", 0); + } + if (robject->ref_count == 1) { + vm_object_deallocate(robject); + continue; + } + + robject->paging_in_progress++; + from = froma; + if (from < bo_pindex) + from = bo_pindex; + + to = toa; + + for (idx = from; idx < to; idx++) { + + dstpindex = idx - bo_pindex; + if (dstpindex >= robject->size) + break; + + m_in = vm_page_lookup(object, idx); + if (m_in == NULL) + continue; + + if( m_in->flags & PG_BUSY) { + s = splhigh(); + while (m_in && (m_in->flags & PG_BUSY)) { + m_in->flags |= PG_WANTED; + tsleep(m_in, PVM, "pwtfrz", 0); + m_in = vm_page_lookup(object, idx); + } + splx(s); + if (m_in == NULL) + continue; + } + m_in->flags |= PG_BUSY; + +retryout: + m_out = vm_page_lookup(robject, dstpindex); + if( m_out && (m_out->flags & PG_BUSY)) { + s = splhigh(); + while (m_out && (m_out->flags & PG_BUSY)) { + m_out->flags |= PG_WANTED; + tsleep(m_out, PVM, "pwtfrz", 0); + m_out = vm_page_lookup(robject, dstpindex); + } + splx(s); + } + + if (m_out == NULL) { + m_out = vm_freeze_page_alloc(robject, dstpindex); + if (m_out == NULL) + goto retryout; + } + + if (m_out->valid == 0) { + vm_page_protect(m_in, VM_PROT_NONE); + pmap_copy_page(VM_PAGE_TO_PHYS(m_in), + VM_PAGE_TO_PHYS(m_out)); + m_out->valid = VM_PAGE_BITS_ALL; + } + PAGE_WAKEUP(m_out); + PAGE_WAKEUP(m_in); + } + + vm_object_pip_wakeup(robject); + + if (((from - bo_pindex) == 0) && ((to - bo_pindex) == robject->size)) { +#if 0 + printf("removing obj: %d, %d\n", object->shadow_count, object->ref_count); +#endif + object->shadow_count--; + + TAILQ_REMOVE(&object->shadow_head, robject, shadow_list); + robject->backing_object = NULL; + robject->backing_object_offset = 0; + + if (object->ref_count == 1) { + if (object->shadow_count == 0) + object->flags &= ~OBJ_OPT; + vm_object_deallocate(object); + vm_object_deallocate(robject); + return; + } else { + object->ref_count--; + } + } + vm_object_deallocate(robject); + } + if (object->shadow_count == 0) + object->flags &= ~OBJ_OPT; +} + #include "opt_ddb.h" #ifdef DDB #include <sys/kernel.h> diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h index aa8ddb2..666205b 100644 --- a/sys/vm/vm_map.h +++ b/sys/vm/vm_map.h @@ -61,7 +61,7 @@ * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. * - * $Id: vm_map.h,v 1.27 1997/08/05 00:01:58 dyson Exp $ + * $Id: vm_map.h,v 1.28 1997/08/18 02:06:24 dyson Exp $ */ /* @@ -336,6 +336,8 @@ int vm_map_submap __P((vm_map_t, vm_offset_t, vm_offset_t, vm_map_t)); void vm_map_madvise __P((vm_map_t, pmap_t, vm_offset_t, vm_offset_t, int)); void vm_map_simplify_entry __P((vm_map_t, vm_map_entry_t)); void vm_init2 __P((void)); +int vm_uiomove __P((vm_map_t, vm_object_t, off_t, int, vm_offset_t)); +void vm_freeze_copyopts __P((vm_object_t, vm_pindex_t, vm_pindex_t)); #endif #endif /* _VM_MAP_ */ diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index 3aee153..30f26c9 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.100 1997/11/07 09:21:00 phk Exp $ + * $Id: vm_object.c,v 1.101 1997/11/18 11:02:19 bde Exp $ */ /* @@ -359,6 +359,15 @@ vm_object_deallocate(object) */ object->flags |= OBJ_DEAD; + if (object->type == OBJT_VNODE) { + struct vnode *vp = object->handle; + if (vp->v_flag & VVMIO) { + object->ref_count++; + vm_freeze_copyopts(object, 0, object->size); + object->ref_count--; + } + } + temp = object->backing_object; if (temp) { TAILQ_REMOVE(&temp->shadow_head, object, shadow_list); @@ -681,6 +690,30 @@ vm_object_pmap_copy(object, start, end) } /* + * Same as vm_object_pmap_copy_1, except range checking really + * works, and is meant for small sections of an object. + */ +void +vm_object_pmap_copy_1(object, start, end) + register vm_object_t object; + register vm_pindex_t start; + register vm_pindex_t end; +{ + vm_pindex_t idx; + register vm_page_t p; + + if (object == NULL || (object->flags & OBJ_WRITEABLE) == 0) + return; + + for (idx = start; idx < end; idx++) { + p = vm_page_lookup(object, idx); + if (p == NULL) + continue; + vm_page_protect(p, VM_PROT_READ); + } +} + +/* * vm_object_pmap_remove: * * Removes all physical pages in the specified diff --git a/sys/vm/vm_object.h b/sys/vm/vm_object.h index e2ef694..305043b 100644 --- a/sys/vm/vm_object.h +++ b/sys/vm/vm_object.h @@ -61,7 +61,7 @@ * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. * - * $Id: vm_object.h,v 1.37 1997/09/01 02:55:50 bde Exp $ + * $Id: vm_object.h,v 1.38 1997/09/21 04:24:24 dyson Exp $ */ /* @@ -131,9 +131,9 @@ struct vm_object { #define OBJ_MIGHTBEDIRTY 0x0100 /* object might be dirty */ #define OBJ_CLEANING 0x0200 #define OBJ_VFS_REF 0x0400 /* object is refed by vfs layer */ - - #define OBJ_VNODE_GONE 0x0800 /* vnode is gone */ +#define OBJ_OPT 0x1000 /* I/O optimization */ + #define OBJ_NORMAL 0x0 /* default behavior */ #define OBJ_SEQUENTIAL 0x1 /* expect sequential accesses */ #define OBJ_RANDOM 0x2 /* expect random accesses */ @@ -179,6 +179,7 @@ void vm_object_init __P((void)); void vm_object_page_clean __P((vm_object_t, vm_pindex_t, vm_pindex_t, boolean_t, boolean_t)); void vm_object_page_remove __P((vm_object_t, vm_pindex_t, vm_pindex_t, boolean_t)); void vm_object_pmap_copy __P((vm_object_t, vm_pindex_t, vm_pindex_t)); +void vm_object_pmap_copy_1 __P((vm_object_t, vm_pindex_t, vm_pindex_t)); void vm_object_pmap_remove __P((vm_object_t, vm_pindex_t, vm_pindex_t)); void vm_object_reference __P((vm_object_t)); void vm_object_shadow __P((vm_object_t *, vm_ooffset_t *, vm_size_t)); diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c index df5d5bf..8ea2728 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.75 1997/10/06 02:38:30 dyson Exp $ + * $Id: vnode_pager.c,v 1.76 1997/12/02 21:07:20 phk Exp $ */ /* @@ -64,6 +64,7 @@ #include <vm/vm_object.h> #include <vm/vm_page.h> #include <vm/vm_pager.h> +#include <vm/vm_map.h> #include <vm/vnode_pager.h> #include <vm/vm_extern.h> @@ -291,10 +292,12 @@ vnode_pager_setsize(vp, nsize) vm_ooffset_t nsizerounded; nsizerounded = IDX_TO_OFF(OFF_TO_IDX(nsize + PAGE_MASK)); if (nsizerounded < object->un_pager.vnp.vnp_size) { - vm_object_page_remove(object, - OFF_TO_IDX(nsize + PAGE_MASK), - OFF_TO_IDX(object->un_pager.vnp.vnp_size), - FALSE); + vm_pindex_t st, end; + st = OFF_TO_IDX(nsize + PAGE_MASK); + end = OFF_TO_IDX(object->un_pager.vnp.vnp_size); + + vm_freeze_copyopts(object, OFF_TO_IDX(nsize), object->size); + vm_object_page_remove(object, st, end, FALSE); } /* * this gets rid of garbage at the end of a page that is now @@ -371,6 +374,7 @@ vnode_pager_uncache(vp, p) return; vm_object_reference(object); + vm_freeze_copyopts(object, 0, object->size); /* * XXX We really should handle locking on |