diff options
author | dyson <dyson@FreeBSD.org> | 1996-01-19 04:00:31 +0000 |
---|---|---|
committer | dyson <dyson@FreeBSD.org> | 1996-01-19 04:00:31 +0000 |
commit | 8fc8a772af22f6e03233d248fa2dbd9b5c2bdd7d (patch) | |
tree | 3c31fd95ea745005a9cd6733db5a16f31bd828a6 /sys/vm/vm_mmap.c | |
parent | 6755beedbf0ddaa9e66e91c8e74f620ede6bfad5 (diff) | |
download | FreeBSD-src-8fc8a772af22f6e03233d248fa2dbd9b5c2bdd7d.zip FreeBSD-src-8fc8a772af22f6e03233d248fa2dbd9b5c2bdd7d.tar.gz |
Eliminated many redundant vm_map_lookup operations for vm_mmap.
Speed up for vfs_bio -- addition of a routine bqrelse to greatly diminish
overhead for merged cache.
Efficiency improvement for vfs_cluster. It used to do alot of redundant
calls to cluster_rbuild.
Correct the ordering for vrele of .text and release of credentials.
Use the selective tlb update for 486/586/P6.
Numerous fixes to the size of objects allocated for files. Additionally,
fixes in the various pagers.
Fixes for proper positioning of vnode_pager_setsize in msdosfs and ext2fs.
Fixes in the swap pager for exhausted resources. The pageout code
will not as readily thrash.
Change the page queue flags (PG_ACTIVE, PG_INACTIVE, PG_FREE, PG_CACHE) into
page queue indices (PQ_ACTIVE, PQ_INACTIVE, PQ_FREE, PQ_CACHE),
thereby improving efficiency of several routines.
Eliminate even more unnecessary vm_page_protect operations.
Significantly speed up process forks.
Make vm_object_page_clean more efficient, thereby eliminating the pause
that happens every 30seconds.
Make sequential clustered writes B_ASYNC instead of B_DELWRI even in the
case of filesystems mounted async.
Fix a panic with busy pages when write clustering is done for non-VMIO
buffers.
Diffstat (limited to 'sys/vm/vm_mmap.c')
-rw-r--r-- | sys/vm/vm_mmap.c | 79 |
1 files changed, 36 insertions, 43 deletions
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index 6579961..c68f5f4 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -38,7 +38,7 @@ * from: Utah $Hdr: vm_mmap.c 1.6 91/10/21$ * * @(#)vm_mmap.c 8.4 (Berkeley) 1/12/94 - * $Id: vm_mmap.c,v 1.33 1995/12/13 12:28:39 dyson Exp $ + * $Id: vm_mmap.c,v 1.34 1995/12/17 07:19:57 bde Exp $ */ /* @@ -70,6 +70,7 @@ #include <vm/vm_pager.h> #include <vm/vm_pageout.h> #include <vm/vm_extern.h> +#include <vm/vm_kern.h> #ifndef _SYS_SYSPROTO_H_ struct sbrk_args { @@ -604,11 +605,12 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff) vm_ooffset_t foff; { boolean_t fitit; - vm_object_t object; + vm_object_t object, object2; struct vnode *vp = NULL; objtype_t type; int rv = KERN_SUCCESS; - vm_size_t objsize; + vm_ooffset_t objsize; + int docow; struct proc *p = curproc; if (size == 0) @@ -659,69 +661,60 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff) error = VOP_GETATTR(vp, &vat, p->p_ucred, p); if (error) return (error); - objsize = vat.va_size; + objsize = round_page(vat.va_size); type = OBJT_VNODE; } } - object = vm_pager_allocate(type, handle, objsize, prot, foff); + object = vm_pager_allocate(type, handle, OFF_TO_IDX(objsize), prot, foff); if (object == NULL) return (type == OBJT_DEVICE ? EINVAL : ENOMEM); - rv = vm_map_find(map, object, foff, addr, size, fitit); + object2 = NULL; + docow = 0; + if ((flags & (MAP_ANON|MAP_SHARED)) == 0 && (type != OBJT_DEVICE)) { + docow = MAP_COPY_ON_WRITE; + if (objsize < size) { + object2 = vm_object_allocate( OBJT_DEFAULT, + OFF_TO_IDX(size - (foff & ~(PAGE_SIZE - 1)))); + object2->backing_object = object; + object2->backing_object_offset = foff; + TAILQ_INSERT_TAIL(&object->shadow_head, + object2, shadow_list); + } else { + docow |= MAP_COPY_NEEDED; + } + } + if (object2) + rv = vm_map_find(map, object2, 0, addr, size, fitit, + prot, maxprot, docow); + else + rv = vm_map_find(map, object, foff, addr, size, fitit, + prot, maxprot, docow); + + if (rv != KERN_SUCCESS) { /* * Lose the object reference. Will destroy the * object if it's an unnamed anonymous mapping * or named anonymous without other references. */ - vm_object_deallocate(object); + if (object2) + vm_object_deallocate(object2); + else + vm_object_deallocate(object); goto out; } /* - * mmap a COW regular file - */ - if ((flags & (MAP_ANON|MAP_SHARED)) == 0 && (type != OBJT_DEVICE)) { - vm_map_entry_t entry; - if (!vm_map_lookup_entry(map, *addr, &entry)) { - panic("vm_mmap: missing map entry!!!"); - } - entry->copy_on_write = TRUE; - /* - * This will create the processes private object on - * an as needed basis. - */ - entry->needs_copy = TRUE; - - /* - * set pages COW and protect for read access only - */ - vm_object_pmap_copy(object, foff, foff + size); - - } - - /* * "Pre-fault" resident pages. */ - if ((type == OBJT_VNODE) && (map->pmap != NULL)) { + if ((map != kernel_map) && + (type == OBJT_VNODE) && (map->pmap != NULL)) { pmap_object_init_pt(map->pmap, *addr, object, (vm_pindex_t) OFF_TO_IDX(foff), size); } /* - * Correct protection (default is VM_PROT_ALL). If maxprot is - * different than prot, we must set both explicitly. - */ - rv = KERN_SUCCESS; - if (maxprot != VM_PROT_ALL) - rv = vm_map_protect(map, *addr, *addr + size, maxprot, TRUE); - if (rv == KERN_SUCCESS && prot != maxprot) - rv = vm_map_protect(map, *addr, *addr + size, prot, FALSE); - if (rv != KERN_SUCCESS) { - (void) vm_map_remove(map, *addr, *addr + size); - goto out; - } - /* * Shared memory is also shared with children. */ if (flags & MAP_SHARED) { |