summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_mmap.c
diff options
context:
space:
mode:
authordyson <dyson@FreeBSD.org>1996-01-19 04:00:31 +0000
committerdyson <dyson@FreeBSD.org>1996-01-19 04:00:31 +0000
commit8fc8a772af22f6e03233d248fa2dbd9b5c2bdd7d (patch)
tree3c31fd95ea745005a9cd6733db5a16f31bd828a6 /sys/vm/vm_mmap.c
parent6755beedbf0ddaa9e66e91c8e74f620ede6bfad5 (diff)
downloadFreeBSD-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.c79
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) {
OpenPOWER on IntegriCloud