Changeset View
Changeset View
Standalone View
Standalone View
head/sys/vm/vm_fault.c
Show First 20 Lines • Show All 954 Lines • ▼ Show 20 Lines | if (fs->object == fs->first_object) { | ||||
fault_page_free(&fs->m); | fault_page_free(&fs->m); | ||||
/* | /* | ||||
* Move on to the next object. Lock the next object before | * Move on to the next object. Lock the next object before | ||||
* unlocking the current one. | * unlocking the current one. | ||||
*/ | */ | ||||
VM_OBJECT_ASSERT_WLOCKED(fs->object); | VM_OBJECT_ASSERT_WLOCKED(fs->object); | ||||
next_object = fs->object->backing_object; | next_object = fs->object->backing_object; | ||||
if (next_object == NULL) { | if (next_object == NULL) | ||||
return (false); | |||||
MPASS(fs->first_m != NULL); | |||||
KASSERT(fs->object != next_object, ("object loop %p", next_object)); | |||||
VM_OBJECT_WLOCK(next_object); | |||||
vm_object_pip_add(next_object, 1); | |||||
if (fs->object != fs->first_object) | |||||
vm_object_pip_wakeup(fs->object); | |||||
fs->pindex += OFF_TO_IDX(fs->object->backing_object_offset); | |||||
VM_OBJECT_WUNLOCK(fs->object); | |||||
fs->object = next_object; | |||||
return (true); | |||||
} | |||||
static void | |||||
vm_fault_zerofill(struct faultstate *fs) | |||||
{ | |||||
/* | /* | ||||
* If there's no object left, fill the page in the top | * If there's no object left, fill the page in the top | ||||
* object with zeros. | * object with zeros. | ||||
*/ | */ | ||||
VM_OBJECT_WUNLOCK(fs->object); | |||||
if (fs->object != fs->first_object) { | if (fs->object != fs->first_object) { | ||||
vm_object_pip_wakeup(fs->object); | vm_object_pip_wakeup(fs->object); | ||||
fs->object = fs->first_object; | fs->object = fs->first_object; | ||||
fs->pindex = fs->first_pindex; | fs->pindex = fs->first_pindex; | ||||
} | } | ||||
MPASS(fs->first_m != NULL); | MPASS(fs->first_m != NULL); | ||||
MPASS(fs->m == NULL); | MPASS(fs->m == NULL); | ||||
fs->m = fs->first_m; | fs->m = fs->first_m; | ||||
fs->first_m = NULL; | fs->first_m = NULL; | ||||
/* | /* | ||||
* Zero the page if necessary and mark it valid. | * Zero the page if necessary and mark it valid. | ||||
*/ | */ | ||||
if ((fs->m->flags & PG_ZERO) == 0) { | if ((fs->m->flags & PG_ZERO) == 0) { | ||||
pmap_zero_page(fs->m); | pmap_zero_page(fs->m); | ||||
} else { | } else { | ||||
VM_CNT_INC(v_ozfod); | VM_CNT_INC(v_ozfod); | ||||
} | } | ||||
VM_CNT_INC(v_zfod); | VM_CNT_INC(v_zfod); | ||||
vm_page_valid(fs->m); | vm_page_valid(fs->m); | ||||
return (false); | |||||
} | } | ||||
MPASS(fs->first_m != NULL); | |||||
KASSERT(fs->object != next_object, ("object loop %p", next_object)); | |||||
VM_OBJECT_WLOCK(next_object); | |||||
vm_object_pip_add(next_object, 1); | |||||
if (fs->object != fs->first_object) | |||||
vm_object_pip_wakeup(fs->object); | |||||
fs->pindex += OFF_TO_IDX(fs->object->backing_object_offset); | |||||
VM_OBJECT_WUNLOCK(fs->object); | |||||
fs->object = next_object; | |||||
return (true); | |||||
} | |||||
/* | /* | ||||
* Allocate a page directly or via the object populate method. | * Allocate a page directly or via the object populate method. | ||||
*/ | */ | ||||
static int | static int | ||||
vm_fault_allocate(struct faultstate *fs) | vm_fault_allocate(struct faultstate *fs) | ||||
{ | { | ||||
struct domainset *dset; | struct domainset *dset; | ||||
int alloc_req; | int alloc_req; | ||||
▲ Show 20 Lines • Show All 389 Lines • ▼ Show 20 Lines | if (fs.object->type != OBJT_DEFAULT) { | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* The page was not found in the current object. Try to | * The page was not found in the current object. Try to | ||||
* traverse into a backing object or zero fill if none is | * traverse into a backing object or zero fill if none is | ||||
* found. | * found. | ||||
*/ | */ | ||||
if (!vm_fault_next(&fs)) { | if (vm_fault_next(&fs)) | ||||
continue; | |||||
VM_OBJECT_WUNLOCK(fs.object); | |||||
vm_fault_zerofill(&fs); | |||||
/* Don't try to prefault neighboring pages. */ | /* Don't try to prefault neighboring pages. */ | ||||
faultcount = 1; | faultcount = 1; | ||||
break; /* break to PAGE HAS BEEN FOUND. */ | break; /* break to PAGE HAS BEEN FOUND. */ | ||||
} | |||||
} | } | ||||
/* | /* | ||||
* PAGE HAS BEEN FOUND. A valid page has been found and exclusively | * PAGE HAS BEEN FOUND. A valid page has been found and exclusively | ||||
* busied. The object lock must no longer be held. | * busied. The object lock must no longer be held. | ||||
*/ | */ | ||||
vm_page_assert_xbusied(fs.m); | vm_page_assert_xbusied(fs.m); | ||||
VM_OBJECT_ASSERT_UNLOCKED(fs.object); | VM_OBJECT_ASSERT_UNLOCKED(fs.object); | ||||
▲ Show 20 Lines • Show All 585 Lines • Show Last 20 Lines |