summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_map.c
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2004-05-22 04:53:51 +0000
committeralc <alc@FreeBSD.org>2004-05-22 04:53:51 +0000
commit5d0912f6d822aa43b6aee5b532f4748d03c89146 (patch)
tree6d85a1a2ab10a2464008e25a57d32d46bc5a5096 /sys/vm/vm_map.c
parent29c76b12014e9524479c1b3617da95f5acb719e3 (diff)
downloadFreeBSD-src-5d0912f6d822aa43b6aee5b532f4748d03c89146.zip
FreeBSD-src-5d0912f6d822aa43b6aee5b532f4748d03c89146.tar.gz
To date, unwiring a fictitious page has produced a panic. The reason
being that PHYS_TO_VM_PAGE() returns the wrong vm_page for fictitious pages but unwiring uses PHYS_TO_VM_PAGE(). The resulting panic reported an unexpected wired count. Rather than attempting to fix PHYS_TO_VM_PAGE(), this fix takes advantage of the properties of fictitious pages. Specifically, fictitious pages will never be completely unwired. Therefore, we can keep a fictitious page's wired count forever set to one and thereby avoid the use of PHYS_TO_VM_PAGE() when we know that we're working with a fictitious page, just not which one. In collaboration with: green@, tegge@ PR: kern/29915
Diffstat (limited to 'sys/vm/vm_map.c')
-rw-r--r--sys/vm/vm_map.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index a8b9e83..5324400 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -1726,7 +1726,9 @@ done:
/*
* Retain the map lock.
*/
- vm_fault_unwire(map, entry->start, entry->end);
+ vm_fault_unwire(map, entry->start, entry->end,
+ entry->object.vm_object != NULL &&
+ entry->object.vm_object->type == OBJT_DEVICE);
}
}
KASSERT(entry->eflags & MAP_ENTRY_IN_TRANSITION,
@@ -1758,7 +1760,7 @@ vm_map_wire(vm_map_t map, vm_offset_t start, vm_offset_t end,
vm_offset_t saved_end, saved_start;
unsigned int last_timestamp;
int rv;
- boolean_t need_wakeup, result, user_wire;
+ boolean_t fictitious, need_wakeup, result, user_wire;
user_wire = (flags & VM_MAP_WIRE_USER) ? TRUE : FALSE;
vm_map_lock(map);
@@ -1834,13 +1836,15 @@ vm_map_wire(vm_map_t map, vm_offset_t start, vm_offset_t end,
entry->wired_count++;
saved_start = entry->start;
saved_end = entry->end;
+ fictitious = entry->object.vm_object != NULL &&
+ entry->object.vm_object->type == OBJT_DEVICE;
/*
* Release the map lock, relying on the in-transition
* mark.
*/
vm_map_unlock(map);
rv = vm_fault_wire(map, saved_start, saved_end,
- user_wire);
+ user_wire, fictitious);
vm_map_lock(map);
if (last_timestamp + 1 != map->timestamp) {
/*
@@ -1924,7 +1928,9 @@ done:
/*
* Retain the map lock.
*/
- vm_fault_unwire(map, entry->start, entry->end);
+ vm_fault_unwire(map, entry->start, entry->end,
+ entry->object.vm_object != NULL &&
+ entry->object.vm_object->type == OBJT_DEVICE);
}
}
KASSERT(entry->eflags & MAP_ENTRY_IN_TRANSITION,
@@ -2048,7 +2054,9 @@ vm_map_sync(
static void
vm_map_entry_unwire(vm_map_t map, vm_map_entry_t entry)
{
- vm_fault_unwire(map, entry->start, entry->end);
+ vm_fault_unwire(map, entry->start, entry->end,
+ entry->object.vm_object != NULL &&
+ entry->object.vm_object->type == OBJT_DEVICE);
entry->wired_count = 0;
}
OpenPOWER on IntegriCloud