vm_page.c (255566) | vm_page.c (255608) |
---|---|
1/*- 2 * Copyright (c) 1991 Regents of the University of California. 3 * All rights reserved. 4 * Copyright (c) 1998 Matthew Dillon. All Rights Reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * The Mach Operating System project at Carnegie-Mellon University. 8 * --- 68 unchanged lines hidden (view full) --- 77 * 78 */ 79 80/* 81 * Resident memory management module. 82 */ 83 84#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1991 Regents of the University of California. 3 * All rights reserved. 4 * Copyright (c) 1998 Matthew Dillon. All Rights Reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * The Mach Operating System project at Carnegie-Mellon University. 8 * --- 68 unchanged lines hidden (view full) --- 77 * 78 */ 79 80/* 81 * Resident memory management module. 82 */ 83 84#include <sys/cdefs.h> |
85__FBSDID("$FreeBSD: head/sys/vm/vm_page.c 255566 2013-09-14 10:11:38Z kib $"); | 85__FBSDID("$FreeBSD: head/sys/vm/vm_page.c 255608 2013-09-16 06:25:54Z kib $"); |
86 87#include "opt_vm.h" 88 89#include <sys/param.h> 90#include <sys/systm.h> 91#include <sys/lock.h> 92#include <sys/kernel.h> 93#include <sys/limits.h> --- 575 unchanged lines hidden (view full) --- 669 mem->hold_count++; 670} 671 672void 673vm_page_unhold(vm_page_t mem) 674{ 675 676 vm_page_lock_assert(mem, MA_OWNED); | 86 87#include "opt_vm.h" 88 89#include <sys/param.h> 90#include <sys/systm.h> 91#include <sys/lock.h> 92#include <sys/kernel.h> 93#include <sys/limits.h> --- 575 unchanged lines hidden (view full) --- 669 mem->hold_count++; 670} 671 672void 673vm_page_unhold(vm_page_t mem) 674{ 675 676 vm_page_lock_assert(mem, MA_OWNED); |
677 KASSERT(mem->hold_count >= 1, ("vm_page_unhold: hold count < 0!!!")); |
|
677 --mem->hold_count; | 678 --mem->hold_count; |
678 KASSERT(mem->hold_count >= 0, ("vm_page_unhold: hold count < 0!!!")); | |
679 if (mem->hold_count == 0 && (mem->flags & PG_UNHOLDFREE) != 0) 680 vm_page_free_toq(mem); 681} 682 683/* 684 * vm_page_unhold_pages: 685 * 686 * Unhold each of the pages that is referenced by the given array. --- 2416 unchanged lines hidden (view full) --- 3103void 3104vm_page_lock_assert_KBI(vm_page_t m, int a, const char *file, int line) 3105{ 3106 3107 mtx_assert_(vm_page_lockptr(m), a, file, line); 3108} 3109#endif 3110 | 679 if (mem->hold_count == 0 && (mem->flags & PG_UNHOLDFREE) != 0) 680 vm_page_free_toq(mem); 681} 682 683/* 684 * vm_page_unhold_pages: 685 * 686 * Unhold each of the pages that is referenced by the given array. --- 2416 unchanged lines hidden (view full) --- 3103void 3104vm_page_lock_assert_KBI(vm_page_t m, int a, const char *file, int line) 3105{ 3106 3107 mtx_assert_(vm_page_lockptr(m), a, file, line); 3108} 3109#endif 3110 |
3111int so_zerocp_fullpage = 0; 3112 3113/* 3114 * Replace the given page with a copy. The copied page assumes 3115 * the portion of the given page's "wire_count" that is not the 3116 * responsibility of this copy-on-write mechanism. 3117 * 3118 * The object containing the given page must have a non-zero 3119 * paging-in-progress count and be locked. 3120 */ 3121void 3122vm_page_cowfault(vm_page_t m) 3123{ 3124 vm_page_t mnew; 3125 vm_object_t object; 3126 vm_pindex_t pindex; 3127 3128 vm_page_lock_assert(m, MA_OWNED); 3129 object = m->object; 3130 VM_OBJECT_ASSERT_WLOCKED(object); 3131 KASSERT(object->paging_in_progress != 0, 3132 ("vm_page_cowfault: object %p's paging-in-progress count is zero.", 3133 object)); 3134 pindex = m->pindex; 3135 3136 retry_alloc: 3137 mnew = vm_page_alloc(NULL, pindex, VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ); 3138 if (mnew == NULL) { 3139 vm_page_unlock(m); 3140 VM_OBJECT_WUNLOCK(object); 3141 VM_WAIT; 3142 VM_OBJECT_WLOCK(object); 3143 if (m == vm_page_lookup(object, pindex)) { 3144 vm_page_lock(m); 3145 goto retry_alloc; 3146 } else { 3147 /* 3148 * Page disappeared during the wait. 3149 */ 3150 return; 3151 } 3152 } 3153 3154 if (m->cow == 0) { 3155 /* 3156 * check to see if we raced with an xmit complete when 3157 * waiting to allocate a page. If so, put things back 3158 * the way they were 3159 */ 3160 vm_page_unlock(m); 3161 vm_page_lock(mnew); 3162 vm_page_free(mnew); 3163 vm_page_unlock(mnew); 3164 } else { /* clear COW & copy page */ 3165 pmap_remove_all(m); 3166 mnew->object = object; 3167 if (object->memattr != VM_MEMATTR_DEFAULT && 3168 (object->flags & OBJ_FICTITIOUS) == 0) 3169 pmap_page_set_memattr(mnew, object->memattr); 3170 if (vm_page_replace(mnew, object, pindex) != m) 3171 panic("vm_page_cowfault: invalid page replacement"); 3172 if (!so_zerocp_fullpage) 3173 pmap_copy_page(m, mnew); 3174 mnew->valid = VM_PAGE_BITS_ALL; 3175 vm_page_dirty(mnew); 3176 mnew->wire_count = m->wire_count - m->cow; 3177 m->wire_count = m->cow; 3178 vm_page_unlock(m); 3179 } 3180} 3181 3182void 3183vm_page_cowclear(vm_page_t m) 3184{ 3185 3186 vm_page_lock_assert(m, MA_OWNED); 3187 if (m->cow) { 3188 m->cow--; 3189 /* 3190 * let vm_fault add back write permission lazily 3191 */ 3192 } 3193 /* 3194 * sf_buf_free() will free the page, so we needn't do it here 3195 */ 3196} 3197 3198int 3199vm_page_cowsetup(vm_page_t m) 3200{ 3201 3202 vm_page_lock_assert(m, MA_OWNED); 3203 if ((m->flags & PG_FICTITIOUS) != 0 || 3204 (m->oflags & VPO_UNMANAGED) != 0 || 3205 m->cow == USHRT_MAX - 1 || !VM_OBJECT_TRYWLOCK(m->object)) 3206 return (EBUSY); 3207 m->cow++; 3208 pmap_remove_write(m); 3209 VM_OBJECT_WUNLOCK(m->object); 3210 return (0); 3211} 3212 | |
3213#ifdef INVARIANTS 3214void 3215vm_page_object_lock_assert(vm_page_t m) 3216{ 3217 3218 /* 3219 * Certain of the page's fields may only be modified by the 3220 * holder of the containing object's lock or the exclusive busy. --- 69 unchanged lines hidden --- | 3111#ifdef INVARIANTS 3112void 3113vm_page_object_lock_assert(vm_page_t m) 3114{ 3115 3116 /* 3117 * Certain of the page's fields may only be modified by the 3118 * holder of the containing object's lock or the exclusive busy. --- 69 unchanged lines hidden --- |