Changeset View
Changeset View
Standalone View
Standalone View
head/sys/vm/vm_fault.c
Show First 20 Lines • Show All 1,353 Lines • ▼ Show 20 Lines | while (TRUE) { | ||||
} | } | ||||
/* | /* | ||||
* Default objects have no pager so no exclusive busy exists | * Default objects have no pager so no exclusive busy exists | ||||
* to protect this page in the chain. Skip to the next | * to protect this page in the chain. Skip to the next | ||||
* object without dropping the lock to preserve atomicity of | * object without dropping the lock to preserve atomicity of | ||||
* shadow faults. | * shadow faults. | ||||
*/ | */ | ||||
if (fs.object->type == OBJT_DEFAULT) { | if (fs.object->type != OBJT_DEFAULT) { | ||||
if (vm_fault_next(&fs)) | |||||
continue; | |||||
/* Don't try to prefault neighboring pages. */ | |||||
faultcount = 1; | |||||
break; | |||||
} | |||||
/* | /* | ||||
* At this point, we have either allocated a new page or found | * At this point, we have either allocated a new page | ||||
* an existing page that is only partially valid. | * or found an existing page that is only partially | ||||
* valid. | |||||
* | * | ||||
* We hold a reference on the current object and the page is | * We hold a reference on the current object and the | ||||
* exclusive busied. The exclusive busy prevents simultaneous | * page is exclusive busied. The exclusive busy | ||||
* faults and collapses while the object lock is dropped. | * prevents simultaneous faults and collapses while | ||||
* the object lock is dropped. | |||||
*/ | */ | ||||
VM_OBJECT_WUNLOCK(fs.object); | VM_OBJECT_WUNLOCK(fs.object); | ||||
/* | /* | ||||
* If the pager for the current object might have the page, | * If the pager for the current object might have | ||||
* then determine the number of additional pages to read and | * the page, then determine the number of additional | ||||
* potentially reprioritize previously read pages for earlier | * pages to read and potentially reprioritize | ||||
* reclamation. These operations should only be performed | * previously read pages for earlier reclamation. | ||||
* once per page fault. Even if the current pager doesn't | * These operations should only be performed once per | ||||
* have the page, the number of additional pages to read will | * page fault. Even if the current pager doesn't | ||||
* apply to subsequent objects in the shadow chain. | * have the page, the number of additional pages to | ||||
* read will apply to subsequent objects in the | |||||
* shadow chain. | |||||
*/ | */ | ||||
if (nera == -1 && !P_KILLED(curproc)) | if (nera == -1 && !P_KILLED(curproc)) | ||||
nera = vm_fault_readahead(&fs); | nera = vm_fault_readahead(&fs); | ||||
rv = vm_fault_getpages(&fs, nera, &behind, &ahead); | rv = vm_fault_getpages(&fs, nera, &behind, &ahead); | ||||
if (rv == KERN_SUCCESS) { | if (rv == KERN_SUCCESS) { | ||||
faultcount = behind + 1 + ahead; | faultcount = behind + 1 + ahead; | ||||
hardfault = true; | hardfault = true; | ||||
break; /* break to PAGE HAS BEEN FOUND. */ | break; /* break to PAGE HAS BEEN FOUND. */ | ||||
} | } | ||||
if (rv == KERN_RESOURCE_SHORTAGE) | if (rv == KERN_RESOURCE_SHORTAGE) | ||||
goto RetryFault; | goto RetryFault; | ||||
VM_OBJECT_WLOCK(fs.object); | VM_OBJECT_WLOCK(fs.object); | ||||
if (rv == KERN_OUT_OF_BOUNDS) { | if (rv == KERN_OUT_OF_BOUNDS) { | ||||
fault_page_free(&fs.m); | fault_page_free(&fs.m); | ||||
unlock_and_deallocate(&fs); | unlock_and_deallocate(&fs); | ||||
return (rv); | return (rv); | ||||
} | |||||
} | } | ||||
/* | /* | ||||
* 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)) { | ||||
▲ Show 20 Lines • Show All 597 Lines • Show Last 20 Lines |