Deleted Added
full compact
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 ---