summaryrefslogtreecommitdiff
path: root/vm/vm_fault.c
diff options
context:
space:
mode:
Diffstat (limited to 'vm/vm_fault.c')
-rw-r--r--vm/vm_fault.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/vm/vm_fault.c b/vm/vm_fault.c
index 46779f6..101ebce 100644
--- a/vm/vm_fault.c
+++ b/vm/vm_fault.c
@@ -229,6 +229,17 @@ vm_fault_return_t vm_fault_page(
boolean_t look_for_page;
vm_prot_t access_required;
+ /* We need to unlock an object before making requests to a
+ memory manager. We use this object to temporarily store
+ object attributes needed for the request to avoid accessing
+ the object while it is unlocked. */
+ struct
+ {
+ struct ipc_port * pager;
+ pager_request_t pager_request;
+ vm_offset_t paging_offset;
+ } obj;
+
if (resume) {
vm_fault_state_t *state =
(vm_fault_state_t *) current_thread()->ith_other;
@@ -510,11 +521,16 @@ vm_fault_return_t vm_fault_page(
new_unlock_request = m->unlock_request =
(access_required | m->unlock_request);
+ obj.pager = object->pager;
+ obj.pager_request =
+ object->pager_request;
+ obj.paging_offset =
+ object->paging_offset;
vm_object_unlock(object);
if ((rc = memory_object_data_unlock(
- object->pager,
- object->pager_request,
- offset + object->paging_offset,
+ obj.pager,
+ obj.pager_request,
+ offset + obj.paging_offset,
PAGE_SIZE,
new_unlock_request))
!= KERN_SUCCESS) {
@@ -633,6 +649,11 @@ vm_fault_return_t vm_fault_page(
m->absent = TRUE;
object->absent_count++;
+ /* Save attributes for the request. */
+ obj.pager = object->pager;
+ obj.pager_request = object->pager_request;
+ obj.paging_offset = object->paging_offset;
+
/*
* We have a busy page, so we can
* release the object lock.
@@ -647,16 +668,16 @@ vm_fault_return_t vm_fault_page(
vm_stat_sample(SAMPLED_PC_VM_PAGEIN_FAULTS);
current_task()->pageins++;
- if ((rc = memory_object_data_request(object->pager,
- object->pager_request,
- m->offset + object->paging_offset,
+ if ((rc = memory_object_data_request(obj.pager,
+ obj.pager_request,
+ m->offset + obj.paging_offset,
PAGE_SIZE, access_required)) != KERN_SUCCESS) {
if (rc != MACH_SEND_INTERRUPTED)
printf("%s(0x%p, 0x%p, 0x%lx, 0x%x, 0x%x) failed, %x\n",
"memory_object_data_request",
- object->pager,
- object->pager_request,
- m->offset + object->paging_offset,
+ obj.pager,
+ obj.pager_request,
+ m->offset + obj.paging_offset,
PAGE_SIZE, access_required, rc);
/*
* Don't want to leave a busy page around,