diff options
author | dyson <dyson@FreeBSD.org> | 1996-06-16 20:37:31 +0000 |
---|---|---|
committer | dyson <dyson@FreeBSD.org> | 1996-06-16 20:37:31 +0000 |
commit | 4e8ccabc814c59d749b8668436e88de78f3c617d (patch) | |
tree | 6b39f5a681da400b6143dac6540e8218547a46e6 /sys/vm | |
parent | 787546bf1d9334d1251577ad85443d07dd86f971 (diff) | |
download | FreeBSD-src-4e8ccabc814c59d749b8668436e88de78f3c617d.zip FreeBSD-src-4e8ccabc814c59d749b8668436e88de78f3c617d.tar.gz |
Various bugfixes/cleanups from me and others:
1) Remove potential race conditions on waking up in vm_page_free_wakeup
by making sure that it is at splvm().
2) Fix another bug in vm_map_simplify_entry.
3) Be more complete about converting from default to swap pager
when an object grows to be large enough that there can be
a problem with data structure allocation under low memory
conditions.
4) Make some madvise code more efficient.
5) Added some comments.
Diffstat (limited to 'sys/vm')
-rw-r--r-- | sys/vm/default_pager.c | 15 | ||||
-rw-r--r-- | sys/vm/default_pager.h | 3 | ||||
-rw-r--r-- | sys/vm/vm_fault.c | 32 | ||||
-rw-r--r-- | sys/vm/vm_map.c | 35 | ||||
-rw-r--r-- | sys/vm/vm_object.c | 52 | ||||
-rw-r--r-- | sys/vm/vm_page.c | 19 |
6 files changed, 66 insertions, 90 deletions
diff --git a/sys/vm/default_pager.c b/sys/vm/default_pager.c index 9c7acdf..ee477eb 100644 --- a/sys/vm/default_pager.c +++ b/sys/vm/default_pager.c @@ -28,7 +28,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: default_pager.c,v 1.7 1996/05/24 05:14:44 dyson Exp $ + * $Id: default_pager.c,v 1.8 1996/05/29 05:12:23 dyson Exp $ */ #include <sys/param.h> @@ -36,6 +36,7 @@ #include <sys/kernel.h> #include <sys/malloc.h> #include <sys/queue.h> +#include <sys/vmmeter.h> #include <vm/vm.h> #include <vm/vm_param.h> @@ -153,3 +154,15 @@ default_pager_convert_to_swap(object) object->type = OBJT_DEFAULT; } } + +void +default_pager_convert_to_swapq(object) + vm_object_t object; +{ + if (object && + (object->type == OBJT_DEFAULT) && + (object != kernel_object && object != kmem_object) && + (object->size > ((cnt.v_page_count - cnt.v_wire_count) / 4))) + default_pager_convert_to_swap(object); +} + diff --git a/sys/vm/default_pager.h b/sys/vm/default_pager.h index 4fc71f0..317abcd 100644 --- a/sys/vm/default_pager.h +++ b/sys/vm/default_pager.h @@ -28,12 +28,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: default_pager.h,v 1.3 1995/12/14 09:54:48 phk Exp $ + * $Id: default_pager.h,v 1.4 1996/05/31 00:37:55 dyson Exp $ */ #ifndef _DEFAULT_PAGER_H_ #define _DEFAULT_PAGER_H_ 1 void default_pager_convert_to_swap __P((vm_object_t object)); +void default_pager_convert_to_swapq __P((vm_object_t object)); #endif /* _DEFAULT_PAGER_H_ */ diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 97b5f41..29a7c16 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.50 1996/06/10 00:25:40 dyson Exp $ + * $Id: vm_fault.c,v 1.51 1996/06/14 23:26:40 davidg Exp $ */ /* @@ -522,10 +522,13 @@ readrest: if (fault_type & VM_PROT_WRITE) { /* - * We already have an empty page in first_object - use - * it. + * This allows pages to be virtually copied from a backing_object + * into the first_object, where the backing object has no other + * refs to it, and cannot gain any more refs. Instead of a + * bcopy, we just move the page from the backing object to the + * first object. Note that we must mark the page dirty in the + * first object so that it will go out to swap when needed. */ - if (lookup_still_valid && /* * Only one shadow object @@ -570,6 +573,17 @@ readrest: vm_page_copy(m, first_m); } + /* + * This code handles the case where there are two references to the + * backing object, and one reference is getting a copy of the + * page. If the other reference is the only other object that + * points to the backing object, then perform a virtual copy + * from the backing object to the other object after the + * page is copied to the current first_object. If the other + * object already has the page, we destroy it in the backing object + * performing an optimized collapse-type operation. We don't + * bother removing the page from the backing object's swap space. + */ if (lookup_still_valid && /* * make sure that we have two shadow objs @@ -826,14 +840,6 @@ vm_fault_wire(map, start, end) */ for (va = start; va < end; va += PAGE_SIZE) { - -/* - while( curproc != pageproc && - (cnt.v_free_count <= cnt.v_pageout_free_min)) { - VM_WAIT; - } -*/ - rv = vm_fault(map, va, VM_PROT_READ|VM_PROT_WRITE, TRUE); if (rv) { if (va != start) @@ -966,10 +972,10 @@ vm_fault_copy_entry(dst_map, src_map, dst_entry, src_entry) * Enter it in the pmap... */ + dst_m->flags |= PG_WRITEABLE|PG_MAPPED; dst_m->flags &= ~PG_ZERO; pmap_enter(dst_map->pmap, vaddr, VM_PAGE_TO_PHYS(dst_m), prot, FALSE); - dst_m->flags |= PG_WRITEABLE|PG_MAPPED; /* * Mark it no longer busy, and put it on the active list. diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index 3bd0053..7b3c5b6 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.49 1996/05/31 00:37:58 dyson Exp $ + * $Id: vm_map.c,v 1.50 1996/06/12 04:03:21 dyson Exp $ */ /* @@ -663,11 +663,7 @@ vm_map_insert(map, object, offset, start, end, prot, max, cow) map->size += (end - prev_entry->end); prev_entry->end = end; prev_object = prev_entry->object.vm_object; - if (prev_object && - (prev_object->type == OBJT_DEFAULT) && - (prev_object->size >= ((cnt.v_page_count - cnt.v_wire_count) / 4))) { - default_pager_convert_to_swap(prev_object); - } + default_pager_convert_to_swapq(prev_object); return (KERN_SUCCESS); } } @@ -715,13 +711,7 @@ vm_map_insert(map, object, offset, start, end, prot, max, cow) (prev_entry->end >= new_entry->start)) map->first_free = new_entry; - if (object && - (object != kernel_object) && - (object != kmem_object) && - (object->type == OBJT_DEFAULT) && - (object->size >= ((cnt.v_page_count - cnt.v_wire_count) / 4))) { - default_pager_convert_to_swap(object); - } + default_pager_convert_to_swapq(object); return (KERN_SUCCESS); } @@ -861,7 +851,7 @@ vm_map_simplify_entry(map, 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->object.vm_object->behavior == entry->object.vm_object->behavior)) && (!prev->object.vm_object || (prev->offset + prevsize == entry->offset)) && (prev->needs_copy == entry->needs_copy) && @@ -891,7 +881,7 @@ vm_map_simplify_entry(map, entry) 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)) && + (!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) && @@ -1462,7 +1452,8 @@ vm_map_pageable(map, start, end, new_pageable) * hold the lock on the sharing map. */ if (!entry->is_a_map && !entry->is_sub_map) { - if (entry->needs_copy && + int copyflag = entry->needs_copy; + if (copyflag && ((entry->protection & VM_PROT_WRITE) != 0)) { vm_object_shadow(&entry->object.vm_object, @@ -1476,6 +1467,7 @@ vm_map_pageable(map, start, end, new_pageable) OFF_TO_IDX(entry->end - entry->start)); entry->offset = (vm_offset_t) 0; } + default_pager_convert_to_swapq(entry->object.vm_object); } } vm_map_clip_start(map, entry, start); @@ -1707,16 +1699,14 @@ vm_map_entry_delete(map, entry) register vm_map_t map; register vm_map_entry_t entry; { - if (entry->wired_count != 0) - vm_map_entry_unwire(map, entry); - vm_map_entry_unlink(map, entry); map->size -= entry->end - entry->start; - if (entry->is_a_map || entry->is_sub_map) + if (entry->is_a_map || entry->is_sub_map) { vm_map_deallocate(entry->object.share_map); - else + } else { vm_object_deallocate(entry->object.vm_object); + } vm_map_entry_dispose(map, entry); } @@ -2266,6 +2256,9 @@ RetryLookup:; entry->offset = 0; lock_write_to_read(&share_map->lock); } + + 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_object.c b/sys/vm/vm_object.c index 2916ee8e..473e2397 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.74 1996/05/24 05:17:21 dyson Exp $ + * $Id: vm_object.c,v 1.75 1996/05/31 00:38:02 dyson Exp $ */ /* @@ -397,8 +397,7 @@ vm_object_terminate(object) vm_object_page_clean(object, 0, 0, TRUE, FALSE); vinvalbuf(vp, V_SAVE, NOCRED, NULL, 0, 0); VOP_UNLOCK(vp); - } - + } /* * Now free the pages. For internal objects, this also removes them * from paging queues. @@ -577,9 +576,6 @@ rescan: } runlen = maxb + maxf + 1; splx(s); -/* - printf("maxb: %d, maxf: %d, runlen: %d, offset: %d\n", maxb, maxf, runlen, ma[0]->pindex); -*/ vm_pageout_flush(ma, runlen, 0); goto rescan; } @@ -652,7 +648,9 @@ vm_object_pmap_copy(object, start, end) if (object == NULL || (object->flags & OBJ_WRITEABLE) == 0) return; - for (p = TAILQ_FIRST(&object->memq); p != NULL; p = TAILQ_NEXT(p, listq)) { + for (p = TAILQ_FIRST(&object->memq); + p != NULL; + p = TAILQ_NEXT(p, listq)) { vm_page_protect(p, VM_PROT_READ); } @@ -676,7 +674,9 @@ vm_object_pmap_remove(object, start, end) register vm_page_t p; if (object == NULL) return; - for (p = TAILQ_FIRST(&object->memq); p != NULL; p = TAILQ_NEXT(p, listq)) { + for (p = TAILQ_FIRST(&object->memq); + p != NULL; + p = TAILQ_NEXT(p, listq)) { if (p->pindex >= start && p->pindex < end) vm_page_protect(p, VM_PROT_NONE); } @@ -720,42 +720,17 @@ vm_object_madvise(object, pindex, count, advise) vm_page_activate(m); } else if ((advise == MADV_DONTNEED) || ((advise == MADV_FREE) && - ((object->type != OBJT_DEFAULT) && (object->type != OBJT_SWAP)))) { - /* - * If the upper level VM system doesn't think that - * the page is dirty, check the pmap layer. - */ - if (m->dirty == 0) { - vm_page_test_dirty(m); - } - /* - * If the page is not dirty, then we place it onto - * the cache queue. When on the cache queue, it is - * available for immediate reuse. - */ - if (m->dirty == 0) { - vm_page_cache(m); - } else { - /* - * If the page IS dirty, then we remove it from all - * pmaps and deactivate it. - */ - vm_page_protect(m, VM_PROT_NONE); - vm_page_deactivate(m); - } + ((object->type != OBJT_DEFAULT) && + (object->type != OBJT_SWAP)))) { + vm_page_deactivate(m); } else if (advise == MADV_FREE) { /* * Force a demand-zero on next ref */ if (object->type == OBJT_SWAP) swap_pager_dmzspace(object, m->pindex, 1); -/* vm_page_protect(m, VM_PROT_NONE); vm_page_free(m); -*/ - pmap_clear_modify(VM_PAGE_TO_PHYS(m)); - m->dirty = 0; - vm_page_cache(m); } } } @@ -1400,11 +1375,6 @@ vm_object_in_map( object) for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) { if( !p->p_vmspace /* || (p->p_flag & (P_SYSTEM|P_WEXIT)) */) continue; -/* - if (p->p_stat != SRUN && p->p_stat != SSLEEP) { - continue; - } -*/ if( _vm_object_in_map(&p->p_vmspace->vm_map, object, 0)) return 1; } diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index b0b755f..d33495f 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.55 1996/06/08 06:48:34 dyson Exp $ + * $Id: vm_page.c,v 1.56 1996/06/12 06:52:06 dyson Exp $ */ /* @@ -797,7 +797,6 @@ vm_page_free_wakeup() wakeup(&vm_pageout_pages_needed); vm_pageout_pages_needed = 0; } - cnt.v_free_count++; /* * wakeup processes that are waiting on memory if we hit a * high water mark. And wakeup scheduler process if we have @@ -846,8 +845,9 @@ vm_page_free(m) TAILQ_INSERT_HEAD(&vm_page_queue_free, m, pageq); } - splx(s); + cnt.v_free_count++; vm_page_free_wakeup(); + splx(s); } void @@ -869,9 +869,9 @@ vm_page_free_zero(m) TAILQ_INSERT_HEAD(&vm_page_queue_zero, m, pageq); ++vm_page_zero_count; - - splx(s); + cnt.v_free_count++; vm_page_free_wakeup(); + splx(s); } /* @@ -992,14 +992,7 @@ vm_page_cache(m) TAILQ_INSERT_TAIL(&vm_page_queue_cache, m, pageq); m->queue = PQ_CACHE; cnt.v_cache_count++; - if ((cnt.v_free_count + cnt.v_cache_count) == cnt.v_free_min) { - wakeup(&cnt.v_free_count); - wakeup(&proc0); - } - if (vm_pageout_pages_needed) { - wakeup(&vm_pageout_pages_needed); - vm_pageout_pages_needed = 0; - } + vm_page_free_wakeup(); splx(s); } |