diff options
author | alc <alc@FreeBSD.org> | 2004-05-22 04:53:51 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2004-05-22 04:53:51 +0000 |
commit | 5d0912f6d822aa43b6aee5b532f4748d03c89146 (patch) | |
tree | 6d85a1a2ab10a2464008e25a57d32d46bc5a5096 /sys/vm/vm_map.c | |
parent | 29c76b12014e9524479c1b3617da95f5acb719e3 (diff) | |
download | FreeBSD-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.c | 18 |
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; } |