diff options
| author | John Dyson <dyson@FreeBSD.org> | 1996-07-30 03:08:57 +0000 |
|---|---|---|
| committer | John Dyson <dyson@FreeBSD.org> | 1996-07-30 03:08:57 +0000 |
| commit | 67bf686897aa870f94c306e8e319f91fa33d49e1 (patch) | |
| tree | ac8503dbf428f1dae7c0a8bba152c865f89a493a /sys/vm | |
| parent | 43f15e7154539d68609804467e071c383226f1e9 (diff) | |
Notes
Diffstat (limited to 'sys/vm')
| -rw-r--r-- | sys/vm/pmap.h | 10 | ||||
| -rw-r--r-- | sys/vm/swap_pager.c | 29 | ||||
| -rw-r--r-- | sys/vm/vm_fault.c | 19 | ||||
| -rw-r--r-- | sys/vm/vm_map.c | 145 | ||||
| -rw-r--r-- | sys/vm/vm_map.h | 3 | ||||
| -rw-r--r-- | sys/vm/vm_mmap.c | 229 | ||||
| -rw-r--r-- | sys/vm/vm_object.c | 7 | ||||
| -rw-r--r-- | sys/vm/vm_page.c | 49 | ||||
| -rw-r--r-- | sys/vm/vm_page.h | 10 | ||||
| -rw-r--r-- | sys/vm/vm_pageout.c | 60 | ||||
| -rw-r--r-- | sys/vm/vnode_pager.c | 8 |
11 files changed, 207 insertions, 362 deletions
diff --git a/sys/vm/pmap.h b/sys/vm/pmap.h index cc5f6f0e8dfc..b8eb6fc24e01 100644 --- a/sys/vm/pmap.h +++ b/sys/vm/pmap.h @@ -61,7 +61,7 @@ * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. * - * $Id: pmap.h,v 1.11 1996/06/17 03:35:34 dyson Exp $ + * $Id: pmap.h,v 1.13 1996/07/27 04:22:12 dyson Exp $ */ /* @@ -99,8 +99,9 @@ void pmap_enter __P((pmap_t, vm_offset_t, vm_offset_t, vm_prot_t, vm_offset_t pmap_extract __P((pmap_t, vm_offset_t)); void pmap_growkernel __P((vm_offset_t)); void pmap_init __P((vm_offset_t, vm_offset_t)); -int pmap_tc_modified __P((vm_page_t m)); -int pmap_tc_referenced __P((vm_offset_t pa)); +boolean_t pmap_is_modified __P((vm_offset_t pa)); +boolean_t pmap_is_referenced __P((vm_offset_t pa)); +boolean_t pmap_ts_referenced __P((vm_offset_t pa)); void pmap_kenter __P((vm_offset_t, vm_offset_t)); void pmap_kremove __P((vm_offset_t)); vm_offset_t pmap_map __P((vm_offset_t, vm_offset_t, vm_offset_t, int)); @@ -108,7 +109,7 @@ void pmap_object_init_pt __P((pmap_t pmap, vm_offset_t addr, vm_object_t object, vm_pindex_t pindex, vm_offset_t size, int pagelimit)); boolean_t pmap_page_exists __P((pmap_t, vm_offset_t)); -void pmap_page_protect __P((vm_page_t, vm_prot_t)); +void pmap_page_protect __P((vm_offset_t, vm_prot_t)); void pmap_pageable __P((pmap_t, vm_offset_t, vm_offset_t, boolean_t)); vm_offset_t pmap_phys_address __P((int)); @@ -120,7 +121,6 @@ void pmap_qremove __P((vm_offset_t, int)); void pmap_reference __P((pmap_t)); void pmap_release __P((pmap_t)); void pmap_remove __P((pmap_t, vm_offset_t, vm_offset_t)); -void pmap_remove_pages __P((pmap_t, vm_offset_t, vm_offset_t)); void pmap_zero_page __P((vm_offset_t)); void pmap_prefault __P((pmap_t pmap, vm_offset_t addra, vm_map_entry_t entry, vm_object_t object)); diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c index b68195cf04a4..b378cd2485a8 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.68 1996/06/10 04:58:48 dyson Exp $ + * $Id: swap_pager.c,v 1.69 1996/07/27 03:23:51 dyson Exp $ */ /* @@ -1078,7 +1078,7 @@ swap_pager_getpages(object, m, count, reqpage) pagedaemon_wakeup(); swap_pager_needflags &= ~(SWAP_FREE_NEEDED|SWAP_FREE_NEEDED_BY_PAGEOUT); if (rv == VM_PAGER_OK) { - pmap_tc_modified(m[reqpage]); + pmap_clear_modify(VM_PAGE_TO_PHYS(m[reqpage])); m[reqpage]->valid = VM_PAGE_BITS_ALL; m[reqpage]->dirty = 0; } @@ -1092,7 +1092,7 @@ swap_pager_getpages(object, m, count, reqpage) */ if (rv == VM_PAGER_OK) { for (i = 0; i < count; i++) { - pmap_tc_modified(m[i]); + pmap_clear_modify(VM_PAGE_TO_PHYS(m[i])); m[i]->dirty = 0; m[i]->flags &= ~PG_ZERO; if (i != reqpage) { @@ -1469,7 +1469,7 @@ retryfree: if (rv == VM_PAGER_OK) { for (i = 0; i < count; i++) { if (rtvals[i] == VM_PAGER_OK) { - pmap_tc_modified(m[i]); + pmap_clear_modify(VM_PAGE_TO_PHYS(m[i])); m[i]->dirty = 0; /* * optimization, if a page has been read @@ -1477,7 +1477,7 @@ retryfree: */ if ((m[i]->queue != PQ_ACTIVE) && ((m[i]->flags & (PG_WANTED|PG_REFERENCED)) || - pmap_tc_referenced(VM_PAGE_TO_PHYS(m[i])))) { + pmap_is_referenced(VM_PAGE_TO_PHYS(m[i])))) { vm_page_activate(m[i]); } } @@ -1580,21 +1580,12 @@ swap_pager_finish(spc) (u_long) VM_PAGE_TO_PHYS(spc->spc_m[i])); } } else { - int pagewanted = 0; for (i = 0; i < spc->spc_count; i++) { - if (spc->spc_m[i]->flags & (PG_WANTED | PG_REFERENCED)) { - pagewanted = 1; - break; - } - } - for (i = 0; i < spc->spc_count; i++) { - pmap_tc_modified(spc->spc_m[i]); + pmap_clear_modify(VM_PAGE_TO_PHYS(spc->spc_m[i])); spc->spc_m[i]->dirty = 0; - if (pagewanted) { - if (spc->spc_m[i]->queue != PQ_ACTIVE) - vm_page_activate(spc->spc_m[i]); - spc->spc_m[i]->flags |= PG_REFERENCED; - } + if ((spc->spc_m[i]->queue != PQ_ACTIVE) && + ((spc->spc_m[i]->flags & PG_WANTED) || pmap_is_referenced(VM_PAGE_TO_PHYS(spc->spc_m[i])))) + vm_page_activate(spc->spc_m[i]); } } @@ -1634,7 +1625,9 @@ swap_pager_iodone(bp) if (bp->b_vp) pbrelvp(bp); +/* if (bp->b_flags & B_WANTED) +*/ wakeup(bp); if (bp->b_rcred != NOCRED) diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 66965d411dcb..43b4158ece42 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.54 1996/07/27 03:23:52 dyson Exp $ + * $Id: vm_fault.c,v 1.55 1996/07/28 01:14:01 dyson Exp $ */ /* @@ -103,6 +103,10 @@ int vm_fault_additional_pages __P((vm_page_t, int, int, vm_page_t *, int *)); #define VM_FAULT_READ_BEHIND 3 #define VM_FAULT_READ (VM_FAULT_READ_AHEAD+VM_FAULT_READ_BEHIND+1) +int vm_fault_free_1; +int vm_fault_copy_save_1; +int vm_fault_copy_save_2; + /* * vm_fault: * @@ -278,7 +282,7 @@ RetryFault:; } queue = m->queue; - vm_page_unqueue(m,0); + vm_page_unqueue_nowakeup(m); /* * Mark page busy for other processes, and the pagedaemon. @@ -561,6 +565,7 @@ readrest: first_m = m; m->dirty = VM_PAGE_BITS_ALL; m = NULL; + ++vm_fault_copy_save_1; } else { /* * Oh, well, lets copy it. @@ -634,6 +639,7 @@ readrest: PAGE_WAKEUP(m); vm_page_free(m); m = NULL; + ++vm_fault_free_1; tm->dirty = VM_PAGE_BITS_ALL; first_m->dirty = VM_PAGE_BITS_ALL; } @@ -645,6 +651,7 @@ readrest: vm_page_rename(m, other_object, other_pindex); m->dirty = VM_PAGE_BITS_ALL; m->valid = VM_PAGE_BITS_ALL; + ++vm_fault_copy_save_2; } } } @@ -653,9 +660,9 @@ readrest: if (m) { if (m->queue != PQ_ACTIVE) vm_page_activate(m); - /* - * We no longer need the old page or object. - */ + /* + * We no longer need the old page or object. + */ PAGE_WAKEUP(m); } @@ -1084,7 +1091,7 @@ vm_fault_additional_pages(m, rbehind, rahead, marray, reqpage) endpindex = pindex + (rahead + 1); if (endpindex > object->size) endpindex = object->size; - while (tpindex < endpindex) { + while (tpindex < endpindex) { if ( vm_page_lookup(object, tpindex)) { break; } diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index 31455b4e75d9..0c5996a07a50 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.52 1996/07/07 03:27:41 davidg Exp $ + * $Id: vm_map.c,v 1.53 1996/07/27 03:23:56 dyson Exp $ */ /* @@ -172,8 +172,6 @@ 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 void vm_map_simplify_entry __P((vm_map_t, vm_map_entry_t)); -static __pure int vm_map_simplify_okay __P((vm_map_entry_t entry1, - vm_map_entry_t entry2)); void vm_map_startup() @@ -232,6 +230,7 @@ vmspace_alloc(min, max, pageable) vm_map_init(&vm->vm_map, min, max, pageable); pmap_pinit(&vm->vm_pmap); vm->vm_map.pmap = &vm->vm_pmap; /* XXX */ + vm->vm_pmap.pm_map = &vm->vm_map; vm->vm_refcnt = 1; return (vm); } @@ -635,8 +634,8 @@ vm_map_insert(map, object, offset, start, end, prot, max, cow) return (KERN_NO_SPACE); if ((prev_entry != &map->header) && - (object == NULL) && (prev_entry->end == start) && + ((object == NULL) || (prev_entry->object.vm_object == object)) && (prev_entry->is_a_map == FALSE) && (prev_entry->is_sub_map == FALSE) && (prev_entry->inheritance == VM_INHERIT_DEFAULT) && @@ -649,22 +648,24 @@ vm_map_insert(map, object, offset, start, end, prot, max, cow) * See if we can avoid creating a new entry by extending one of our * neighbors. */ - if (vm_object_coalesce(prev_entry->object.vm_object, - OFF_TO_IDX(prev_entry->offset), - (vm_size_t) (prev_entry->end - - prev_entry->start), - (vm_size_t) (end - prev_entry->end))) { + if (object == NULL) { + if (vm_object_coalesce(prev_entry->object.vm_object, + OFF_TO_IDX(prev_entry->offset), + (vm_size_t) (prev_entry->end + - prev_entry->start), + (vm_size_t) (end - prev_entry->end))) { - /* - * Coalesced the two objects - can extend the - * previous map entry to include the new - * range. - */ - map->size += (end - prev_entry->end); - prev_entry->end = end; - prev_object = prev_entry->object.vm_object; - default_pager_convert_to_swapq(prev_object); - return (KERN_SUCCESS); + /* + * Coalesced the two objects - can extend the + * previous map entry to include the new + * range. + */ + map->size += (end - prev_entry->end); + prev_entry->end = end; + prev_object = prev_entry->object.vm_object; + default_pager_convert_to_swapq(prev_object); + return (KERN_SUCCESS); + } } } /* @@ -706,10 +707,9 @@ vm_map_insert(map, object, offset, start, end, prot, max, cow) /* * Update the free space hint */ - if (map->first_free == prev_entry) { - if (prev_entry->end == new_entry->start) - map->first_free = new_entry; - } + if ((map->first_free == prev_entry) && + (prev_entry->end >= new_entry->start)) + map->first_free = new_entry; default_pager_convert_to_swapq(object); return (KERN_SUCCESS); @@ -739,9 +739,8 @@ vm_map_findspace(map, start, length, addr) * at this address, we have to start after it. */ if (start == map->min_offset) { - if ((entry = map->first_free) != &map->header) { + if ((entry = map->first_free) != &map->header) start = entry->end; - } } else { vm_map_entry_t tmp; @@ -822,39 +821,12 @@ vm_map_find(map, object, offset, addr, length, find_space, prot, max, cow) return (result); } -static __pure int -vm_map_simplify_okay(entry1, entry2) - vm_map_entry_t entry1, entry2; -{ - if ((entry1->end != entry2->start) || - (entry1->object.vm_object != entry2->object.vm_object)) - return 0; - if (entry1->object.vm_object) { - if (entry1->object.vm_object->behavior != - entry2->object.vm_object->behavior) - return 0; - if (entry1->offset + (entry1->end - entry1->start) != - entry2->offset) - return 0; - } - if ((entry1->needs_copy != entry2->needs_copy) || - (entry1->copy_on_write != entry2->copy_on_write) || - (entry1->protection != entry2->protection) || - (entry1->max_protection != entry2->max_protection) || - (entry1->inheritance != entry2->inheritance) || - (entry1->is_sub_map != FALSE) || - (entry1->is_a_map != FALSE) || - (entry1->wired_count != 0) || - (entry2->is_sub_map != FALSE) || - (entry2->is_a_map != FALSE) || - (entry2->wired_count != 0)) - return 0; - - return 1; -} - /* * vm_map_simplify_entry: [ internal use only ] + * + * Simplify the given map entry by: + * removing extra sharing maps + * [XXX maybe later] merging with a neighbor */ static void vm_map_simplify_entry(map, entry) @@ -862,13 +834,34 @@ vm_map_simplify_entry(map, entry) vm_map_entry_t entry; { vm_map_entry_t next, prev; + vm_size_t nextsize, prevsize, esize; + + /* + * If this entry corresponds to a sharing map, then see if we can + * remove the level of indirection. If it's not a sharing map, then it + * points to a VM object, so see if we can merge with either of our + * neighbors. + */ - if (entry->is_a_map || entry->is_sub_map || entry->wired_count) + if (entry->is_sub_map || entry->is_a_map || entry->wired_count) return; prev = entry->prev; if (prev != &map->header) { - if ( vm_map_simplify_okay(prev, entry)) { + prevsize = prev->end - prev->start; + if ( (prev->end == entry->start) && + (prev->object.vm_object == entry->object.vm_object) && + (!prev->object.vm_object || (prev->object.vm_object->behavior == entry->object.vm_object->behavior)) && + (!prev->object.vm_object || + (prev->offset + prevsize == entry->offset)) && + (prev->needs_copy == entry->needs_copy) && + (prev->copy_on_write == entry->copy_on_write) && + (prev->protection == entry->protection) && + (prev->max_protection == entry->max_protection) && + (prev->inheritance == entry->inheritance) && + (prev->is_a_map == FALSE) && + (prev->is_sub_map == FALSE) && + (prev->wired_count == 0)) { if (map->first_free == prev) map->first_free = entry; if (map->hint == prev) @@ -884,7 +877,21 @@ vm_map_simplify_entry(map, entry) next = entry->next; if (next != &map->header) { - if ( vm_map_simplify_okay(entry, next)) { + nextsize = next->end - next->start; + esize = entry->end - entry->start; + if ((entry->end == next->start) && + (next->object.vm_object == entry->object.vm_object) && + (!next->object.vm_object || (next->object.vm_object->behavior == entry->object.vm_object->behavior)) && + (!entry->object.vm_object || + (entry->offset + esize == next->offset)) && + (next->needs_copy == entry->needs_copy) && + (next->copy_on_write == entry->copy_on_write) && + (next->protection == entry->protection) && + (next->max_protection == entry->max_protection) && + (next->inheritance == entry->inheritance) && + (next->is_a_map == FALSE) && + (next->is_sub_map == FALSE) && + (next->wired_count == 0)) { if (map->first_free == next) map->first_free = entry; if (map->hint == next) @@ -897,7 +904,6 @@ vm_map_simplify_entry(map, entry) } } } - /* * vm_map_clip_start: [ internal use only ] * @@ -1835,21 +1841,6 @@ vm_map_remove(map, start, end) } /* - * vm_map_remove_userspace: - * Removes the user portion of the address space. - */ -void -vm_map_remove_userspace(map) - register vm_map_t map; -{ - vm_map_lock(map); - pmap_remove_pages(map->pmap, VM_MIN_ADDRESS, VM_MAXUSER_ADDRESS); - vm_map_delete(map, VM_MIN_ADDRESS, VM_MAXUSER_ADDRESS); - vm_map_unlock(map); - return; -} - -/* * vm_map_check_protection: * * Assert that the target map allows the specified @@ -2266,8 +2257,8 @@ RetryLookup:; lock_write_to_read(&share_map->lock); } - default_pager_convert_to_swapq(entry->object.vm_object); - + if (entry->object.vm_object != NULL) + default_pager_convert_to_swapq(entry->object.vm_object); /* * Return the object/offset from this entry. If the entry was * copy-on-write or empty, it has been fixed up. diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h index a50fa6256c19..fd04d87de264 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.13 1996/05/19 07:36:48 dyson Exp $ + * $Id: vm_map.h,v 1.14 1996/07/27 03:23:59 dyson Exp $ */ /* @@ -233,7 +233,6 @@ int vm_map_clean __P((vm_map_t, vm_offset_t, vm_offset_t, boolean_t, boolean_t)) int vm_map_protect __P((vm_map_t, vm_offset_t, vm_offset_t, vm_prot_t, boolean_t)); void vm_map_reference __P((vm_map_t)); int vm_map_remove __P((vm_map_t, vm_offset_t, vm_offset_t)); -void vm_map_remove_userspace __P((vm_map_t)); void vm_map_simplify __P((vm_map_t, vm_offset_t)); void vm_map_startup __P((void)); int vm_map_submap __P((vm_map_t, vm_offset_t, vm_offset_t, vm_map_t)); diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index a1a48a9416a1..047b39ec553e 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.47 1996/07/27 17:21:41 dyson Exp $ + * $Id: vm_mmap.c,v 1.48 1996/07/28 02:54:09 davidg Exp $ */ /* @@ -72,7 +72,6 @@ #include <vm/vm_extern.h> #include <vm/vm_kern.h> #include <vm/vm_page.h> -#include <vm/default_pager.h> #ifndef _SYS_SYSPROTO_H_ struct sbrk_args { @@ -690,10 +689,10 @@ mincore(p, uap, retval) if (m) { mincoreinfo = MINCORE_INCORE; if (m->dirty || - pmap_tc_modified(m)) + pmap_is_modified(VM_PAGE_TO_PHYS(m))) mincoreinfo |= MINCORE_MODIFIED_OTHER; if ((m->flags & PG_REFERENCED) || - pmap_tc_referenced(VM_PAGE_TO_PHYS(m))) + pmap_is_referenced(VM_PAGE_TO_PHYS(m))) mincoreinfo |= MINCORE_REFERENCED_OTHER; } } @@ -845,7 +844,7 @@ 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; @@ -883,15 +882,12 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff) * Lookup/allocate object. */ if (flags & MAP_ANON) { + type = OBJT_SWAP; /* * Unnamed anonymous regions always start at 0. */ - if (handle == 0) { + if (handle == 0) foff = 0; - type = OBJT_DEFAULT; - } else { - type = OBJT_SWAP; - } } else { vp = (struct vnode *) handle; if (vp->v_type == VCHR) { @@ -908,15 +904,9 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff) type = OBJT_VNODE; } } - - if (type != OBJT_DEFAULT) { - object = vm_pager_allocate(type, handle, - OFF_TO_IDX(objsize), prot, foff); - if (object == NULL) - return (type == OBJT_DEVICE ? EINVAL : ENOMEM); - } else { - object = NULL; - } + object = vm_pager_allocate(type, handle, OFF_TO_IDX(objsize), prot, foff); + if (object == NULL) + return (type == OBJT_DEVICE ? EINVAL : ENOMEM); /* * Force device mappings to be shared. @@ -926,13 +916,30 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff) flags |= MAP_SHARED; } + object2 = NULL; docow = 0; if ((flags & (MAP_ANON|MAP_SHARED)) == 0) { - docow = MAP_COPY_ON_WRITE|MAP_COPY_NEEDED; + docow = MAP_COPY_ON_WRITE; + if (objsize < size) { + object2 = vm_object_allocate( OBJT_DEFAULT, + OFF_TO_IDX(size - (foff & ~PAGE_MASK))); + object2->backing_object = object; + object2->backing_object_offset = foff; + TAILQ_INSERT_TAIL(&object->shadow_head, + object2, shadow_list); + ++object->shadow_count; + } else { + docow |= MAP_COPY_NEEDED; + } } - rv = vm_map_find(map, object, foff, addr, size, fitit, - prot, maxprot, docow); + 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) { /* @@ -940,7 +947,10 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff) * 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; } @@ -975,176 +985,3 @@ out: return (EINVAL); } } - -#ifdef notyet -/* - * Efficient mapping of a .text+.data+.bss object - */ -int -vm_mapaout(map, baseaddr, vp, foff, textsize, datasize, bsssize, addr) - vm_map_t map; - vm_offset_t baseaddr; - struct vnode *vp; - vm_ooffset_t foff; - register vm_size_t textsize, datasize, bsssize; - vm_offset_t *addr; -{ - vm_object_t object; - int rv; - vm_pindex_t objpsize; - struct proc *p = curproc; - - vm_size_t totalsize; - vm_size_t textend; - struct vattr vat; - int error; - - textsize = round_page(textsize); - datasize = round_page(datasize); - bsssize = round_page(bsssize); - totalsize = textsize + datasize + bsssize; - - vm_map_lock(map); - /* - * If baseaddr == -1, then we need to search for space. Otherwise, - * we need to be loaded into a certain spot. - */ - if (baseaddr != (vm_offset_t) -1) { - if (vm_map_findspace(map, baseaddr, totalsize, addr)) { - goto outnomem; - } - - if(*addr != baseaddr) { - goto outnomem; - } - } else { - baseaddr = round_page(p->p_vmspace->vm_daddr + MAXDSIZ); - if (vm_map_findspace(map, baseaddr, totalsize, addr)) { - goto outnomem; - } - } - - if (foff & PAGE_MASK) { - vm_map_unlock(map); - return EINVAL; - } - - if ((vp->v_object != 0) && - ((((vm_object_t)vp->v_object)->flags & OBJ_DEAD) == 0)) { - object = vp->v_object; - vm_object_reference(object); - } else { - /* - * get the object size to allocate - */ - error = VOP_GETATTR(vp, &vat, p->p_ucred, p); - if (error) { - vm_map_unlock(map); - return error; - } - objpsize = OFF_TO_IDX(round_page(vat.va_size)); - /* - * Alloc/reference the object - */ - object = vm_pager_allocate(OBJT_VNODE, vp, - objpsize, VM_PROT_ALL, foff); - if (object == NULL) { - goto outnomem; - } - } - - /* - * Insert .text into the map - */ - textend = *addr + textsize; - rv = vm_map_insert(map, object, foff, - *addr, textend, - VM_PROT_READ|VM_PROT_EXECUTE, VM_PROT_ALL, - MAP_COPY_ON_WRITE|MAP_COPY_NEEDED); - if (rv != KERN_SUCCESS) { - vm_object_deallocate(object); - goto out; - } - - /* - * Insert .data into the map, if there is any to map. - */ - if (datasize != 0) { - object->ref_count++; - rv = vm_map_insert(map, object, foff + textsize, - textend, textend + datasize, - VM_PROT_ALL, VM_PROT_ALL, - MAP_COPY_ON_WRITE|MAP_COPY_NEEDED); - if (rv != KERN_SUCCESS) { - --object->ref_count; - vm_map_delete(map, *addr, textend); - goto out; - } - } - - /* - * Preload the page tables - */ - pmap_object_init_pt(map->pmap, *addr, - object, (vm_pindex_t) OFF_TO_IDX(foff), - textsize + datasize, 1); - - /* - * Get the space for bss. - */ - if (bsssize != 0) { - rv = vm_map_insert(map, NULL, 0, - textend + datasize, - *addr + totalsize, - VM_PROT_ALL, VM_PROT_ALL, 0); - } - if (rv != KERN_SUCCESS) { - vm_map_delete(map, *addr, textend + datasize + bsssize); - } - -out: - vm_map_unlock(map); - switch (rv) { - case KERN_SUCCESS: - return 0; - case KERN_INVALID_ADDRESS: - case KERN_NO_SPACE: - return ENOMEM; - case KERN_PROTECTION_FAILURE: - return EACCES; - default: - return EINVAL; - } -outnomem: - vm_map_unlock(map); - return ENOMEM; -} - - -int -mapaout(struct proc *p, struct mapaout_args *uap, int *retval) -{ - - register struct filedesc *fdp = p->p_fd; - struct file *fp; - struct vnode *vp; - int rtval; - - if (((unsigned) uap->fd) >= fdp->fd_nfiles || - (fp = fdp->fd_ofiles[uap->fd]) == NULL) - return (EBADF); - if (fp->f_type != DTYPE_VNODE) - return (EINVAL); - - vp = (struct vnode *) fp->f_data; - if ((vp->v_type != VREG) && (vp->v_type != VCHR)) - return (EINVAL); - - rtval = vm_mapaout( &p->p_vmspace->vm_map, - uap->addr, vp, uap->offset, - uap->textsize, uap->datasize, uap->bsssize, - (vm_offset_t *)retval); - - return rtval; -} -#endif diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index 39c7ee05ba76..496da963ba18 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.76 1996/06/16 20:37:30 dyson Exp $ + * $Id: vm_object.c,v 1.77 1996/07/27 03:24:03 dyson Exp $ */ /* @@ -219,6 +219,7 @@ vm_object_allocate(type, size) result = (vm_object_t) malloc((u_long) sizeof *result, M_VMOBJ, M_WAITOK); + _vm_object_allocate(type, size, result); return (result); @@ -230,7 +231,7 @@ vm_object_allocate(type, size) * * Gets another reference to the given object. */ -void +inline void vm_object_reference(object) register vm_object_t object; { @@ -402,10 +403,8 @@ vm_object_terminate(object) * from paging queues. */ while ((p = TAILQ_FIRST(&object->memq)) != NULL) { -#if defined(DIAGNOSTIC) if (p->flags & PG_BUSY) printf("vm_object_terminate: freeing busy page\n"); -#endif PAGE_WAKEUP(p); vm_page_free(p); cnt.v_pfree++; diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index 79dd930d4217..4857d45b09db 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.60 1996/06/26 05:39:25 dyson Exp $ + * $Id: vm_page.c,v 1.61 1996/07/27 03:24:05 dyson Exp $ */ /* @@ -385,7 +385,7 @@ vm_page_hash(object, pindex) * The object and page must be locked, and must be splhigh. */ -void +__inline void vm_page_insert(m, object, pindex) register vm_page_t m; register vm_object_t object; @@ -434,7 +434,7 @@ vm_page_insert(m, object, pindex) * The object and page must be locked, and at splhigh. */ -void +__inline void vm_page_remove(m) register vm_page_t m; { @@ -523,19 +523,34 @@ vm_page_rename(m, new_object, new_pindex) } /* + * vm_page_unqueue without any wakeup + */ +__inline void +vm_page_unqueue_nowakeup(m) + vm_page_t m; +{ + int queue = m->queue; + if (queue != PQ_NONE) { + m->queue = PQ_NONE; + TAILQ_REMOVE(vm_page_queues[queue].pl, m, pageq); + --(*vm_page_queues[queue].cnt); + } +} + + +/* * vm_page_unqueue must be called at splhigh(); */ __inline void -vm_page_unqueue(m, wakeup) +vm_page_unqueue(m) vm_page_t m; - int wakeup; { int queue = m->queue; if (queue != PQ_NONE) { m->queue = PQ_NONE; TAILQ_REMOVE(vm_page_queues[queue].pl, m, pageq); --(*vm_page_queues[queue].cnt); - if ((queue == PQ_CACHE) && wakeup) { + if (queue == PQ_CACHE) { if ((cnt.v_cache_count + cnt.v_free_count) < (cnt.v_free_reserved + cnt.v_cache_min)) pagedaemon_wakeup(); @@ -721,7 +736,7 @@ vm_page_activate(m) if (m->queue == PQ_CACHE) cnt.v_reactivated++; - vm_page_unqueue(m, 1); + vm_page_unqueue(m); if (m->wire_count == 0) { TAILQ_INSERT_TAIL(&vm_page_queue_active, m, pageq); @@ -736,7 +751,7 @@ vm_page_activate(m) /* * helper routine for vm_page_free and vm_page_free_zero */ -__inline static int +static int vm_page_freechk_and_unqueue(m) vm_page_t m; { @@ -754,7 +769,7 @@ vm_page_freechk_and_unqueue(m) } vm_page_remove(m); - vm_page_unqueue(m,0); + vm_page_unqueue_nowakeup(m); if ((m->flags & PG_FICTITIOUS) != 0) { return 0; } @@ -773,7 +788,7 @@ vm_page_freechk_and_unqueue(m) /* * helper routine for vm_page_free and vm_page_free_zero */ -__inline static void +static __inline void vm_page_free_wakeup() { @@ -880,7 +895,7 @@ vm_page_wire(m) if (m->wire_count == 0) { s = splvm(); - vm_page_unqueue(m,1); + vm_page_unqueue(m); splx(s); cnt.v_wire_count++; } @@ -946,7 +961,7 @@ vm_page_deactivate(m) if (m->wire_count == 0 && m->hold_count == 0) { if (m->queue == PQ_CACHE) cnt.v_reactivated++; - vm_page_unqueue(m,1); + vm_page_unqueue(m); TAILQ_INSERT_TAIL(&vm_page_queue_inactive, m, pageq); m->queue = PQ_INACTIVE; cnt.v_inactive_count++; @@ -977,7 +992,7 @@ vm_page_cache(m) panic("vm_page_cache: caching a dirty page, pindex: %d", m->pindex); } s = splvm(); - vm_page_unqueue(m,0); + vm_page_unqueue_nowakeup(m); TAILQ_INSERT_TAIL(&vm_page_queue_cache, m, pageq); m->queue = PQ_CACHE; cnt.v_cache_count++; @@ -1016,7 +1031,7 @@ vm_page_set_validclean(m, base, size) m->valid |= pagebits; m->dirty &= ~pagebits; if( base == 0 && size == PAGE_SIZE) - pmap_tc_modified(m); + pmap_clear_modify(VM_PAGE_TO_PHYS(m)); } /* @@ -1056,8 +1071,10 @@ void vm_page_test_dirty(m) vm_page_t m; { - if (m->dirty != VM_PAGE_BITS_ALL) - pmap_tc_modified(m); + if ((m->dirty != VM_PAGE_BITS_ALL) && + pmap_is_modified(VM_PAGE_TO_PHYS(m))) { + m->dirty = VM_PAGE_BITS_ALL; + } } /* diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h index 1680d4d837b1..921aa31e864e 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.29 1996/06/26 05:39:25 dyson Exp $ + * $Id: vm_page.h,v 1.30 1996/07/27 03:24:06 dyson Exp $ */ /* @@ -220,7 +220,6 @@ extern vm_offset_t last_phys_addr; /* physical address for last_page */ (m)->flags &= ~PG_BUSY; \ if ((m)->flags & PG_WANTED) { \ (m)->flags &= ~PG_WANTED; \ - (m)->flags |= PG_REFERENCED; \ wakeup((caddr_t) (m)); \ } \ } @@ -252,7 +251,8 @@ void vm_page_rename __P((vm_page_t, vm_object_t, vm_pindex_t)); vm_offset_t vm_page_startup __P((vm_offset_t, vm_offset_t, vm_offset_t)); void vm_page_unwire __P((vm_page_t)); void vm_page_wire __P((vm_page_t)); -void vm_page_unqueue __P((vm_page_t, int)); +void vm_page_unqueue __P((vm_page_t)); +void vm_page_unqueue_nowakeup __P((vm_page_t)); void vm_page_set_validclean __P((vm_page_t, int, int)); void vm_page_set_invalid __P((vm_page_t, int, int)); static __inline boolean_t vm_page_zero_fill __P((vm_page_t)); @@ -292,11 +292,11 @@ vm_page_protect(vm_page_t mem, int prot) { if (prot == VM_PROT_NONE) { if (mem->flags & (PG_WRITEABLE|PG_MAPPED)) { - pmap_page_protect(mem, prot); + pmap_page_protect(VM_PAGE_TO_PHYS(mem), prot); mem->flags &= ~(PG_WRITEABLE|PG_MAPPED); } } else if ((prot == VM_PROT_READ) && (mem->flags & PG_WRITEABLE)) { - pmap_page_protect(mem, prot); + pmap_page_protect(VM_PAGE_TO_PHYS(mem), prot); mem->flags &= ~PG_WRITEABLE; } } diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index 26df38c302b5..d4db0bc48114 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.81 1996/07/08 02:25:53 dyson Exp $ + * $Id: vm_pageout.c,v 1.83 1996/07/27 03:24:08 dyson Exp $ */ /* @@ -314,9 +314,12 @@ do_backward: } } + /* + * we allow reads during pageouts... + */ for (i = page_base; i < (page_base + pageout_count); i++) { mc[i]->flags |= PG_BUSY; - vm_page_protect(mc[i], VM_PROT_NONE); + vm_page_protect(mc[i], VM_PROT_READ); } return vm_pageout_flush(&mc[page_base], pageout_count, sync); @@ -356,7 +359,7 @@ vm_pageout_flush(mc, count, sync) * essentially lose the changes by pretending it * worked. */ - pmap_tc_modified(mt); + pmap_clear_modify(VM_PAGE_TO_PHYS(mt)); mt->dirty = 0; break; case VM_PAGER_ERROR: @@ -443,7 +446,7 @@ vm_pageout_object_deactivate_pages(map, object, desired, map_remove_only) continue; } - refcount = pmap_tc_referenced(VM_PAGE_TO_PHYS(p)); + refcount = pmap_ts_referenced(VM_PAGE_TO_PHYS(p)); if (refcount) { p->flags |= PG_REFERENCED; } else if (p->flags & PG_REFERENCED) { @@ -583,7 +586,7 @@ vm_pageout_scan() maxlaunder = (cnt.v_inactive_target > MAXLAUNDER) ? MAXLAUNDER : cnt.v_inactive_target; - +rescan0: maxscan = cnt.v_inactive_count; for( m = TAILQ_FIRST(&vm_page_queue_inactive); @@ -596,7 +599,7 @@ vm_pageout_scan() cnt.v_pdpages++; if (m->queue != PQ_INACTIVE) { - break; + goto rescan0; } next = TAILQ_NEXT(m, pageq); @@ -618,33 +621,32 @@ vm_pageout_scan() continue; } - if (m->valid != 0) { - if (m->object->ref_count == 0) { - m->flags &= ~PG_REFERENCED; - pmap_tc_referenced(VM_PAGE_TO_PHYS(m)); - } else if (((m->flags & PG_REFERENCED) == 0) && - pmap_tc_referenced(VM_PAGE_TO_PHYS(m))) { - vm_page_activate(m); - continue; - } + if (m->object->ref_count == 0) { + m->flags &= ~PG_REFERENCED; + pmap_clear_reference(VM_PAGE_TO_PHYS(m)); + } else if (((m->flags & PG_REFERENCED) == 0) && + pmap_ts_referenced(VM_PAGE_TO_PHYS(m))) { + vm_page_activate(m); + continue; + } - if ((m->flags & PG_REFERENCED) != 0) { - m->flags &= ~PG_REFERENCED; - pmap_tc_referenced(VM_PAGE_TO_PHYS(m)); - vm_page_activate(m); - continue; - } - if (m->dirty == 0) { - vm_page_test_dirty(m); - } else if (m->dirty != 0) { - m->dirty = VM_PAGE_BITS_ALL; - } - } + if ((m->flags & PG_REFERENCED) != 0) { + m->flags &= ~PG_REFERENCED; + pmap_clear_reference(VM_PAGE_TO_PHYS(m)); + vm_page_activate(m); + continue; + } + + if (m->dirty == 0) { + vm_page_test_dirty(m); + } else if (m->dirty != 0) { + m->dirty = VM_PAGE_BITS_ALL; + } if (m->valid == 0) { vm_page_protect(m, VM_PROT_NONE); vm_page_free(m); - ++cnt.v_dfree; + cnt.v_dfree++; ++pages_freed; } else if (m->dirty == 0) { vm_page_cache(m); @@ -786,7 +788,7 @@ vm_pageout_scan() if (m->flags & PG_REFERENCED) { refcount += 1; } - refcount += pmap_tc_referenced(VM_PAGE_TO_PHYS(m)); + refcount += pmap_ts_referenced(VM_PAGE_TO_PHYS(m)); if (refcount) { m->act_count += ACT_ADVANCE + refcount; if (m->act_count > ACT_MAX) diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c index 3fe0ae3a2a7c..3c9d21aece22 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.60 1996/05/03 21:01:54 phk Exp $ + * $Id: vnode_pager.c,v 1.61 1996/07/27 03:24:10 dyson Exp $ */ /* @@ -525,7 +525,7 @@ vnode_pager_input_smlfs(object, m) } } vm_pager_unmap_page(kva); - pmap_tc_modified(m); + pmap_clear_modify(VM_PAGE_TO_PHYS(m)); m->flags &= ~PG_ZERO; if (error) { return VM_PAGER_ERROR; @@ -588,7 +588,7 @@ vnode_pager_input_old(object, m) } vm_pager_unmap_page(kva); } - pmap_tc_modified(m); + pmap_clear_modify(VM_PAGE_TO_PHYS(m)); m->dirty = 0; m->flags &= ~PG_ZERO; return error ? VM_PAGER_ERROR : VM_PAGER_OK; @@ -808,7 +808,7 @@ vnode_pager_leaf_getpages(object, m, count, reqpage) relpbuf(bp); for (i = 0; i < count; i++) { - pmap_tc_modified(m[i]); + pmap_clear_modify(VM_PAGE_TO_PHYS(m[i])); m[i]->dirty = 0; m[i]->valid = VM_PAGE_BITS_ALL; m[i]->flags &= ~PG_ZERO; |
