diff options
author | Alan Cox <alc@FreeBSD.org> | 2004-05-22 04:53:51 +0000 |
---|---|---|
committer | Alan Cox <alc@FreeBSD.org> | 2004-05-22 04:53:51 +0000 |
commit | 4be14af9cf8d09cab0c1bfb0f8557ee081444957 (patch) | |
tree | 6d85a1a2ab10a2464008e25a57d32d46bc5a5096 /sys/vm/vm_fault.c | |
parent | 55fe3a872f94635e9cbb27651665fbedd4d49afc (diff) | |
download | src-4be14af9cf8d09cab0c1bfb0f8557ee081444957.tar.gz src-4be14af9cf8d09cab0c1bfb0f8557ee081444957.zip |
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
Notes
Notes:
svn path=/head/; revision=129571
Diffstat (limited to 'sys/vm/vm_fault.c')
-rw-r--r-- | sys/vm/vm_fault.c | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 000e2a2c69c9..562d255f0b9f 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -1038,10 +1038,8 @@ vm_fault_quick(caddr_t v, int prot) * Wire down a range of virtual addresses in a map. */ int -vm_fault_wire(map, start, end, user_wire) - vm_map_t map; - vm_offset_t start, end; - boolean_t user_wire; +vm_fault_wire(vm_map_t map, vm_offset_t start, vm_offset_t end, + boolean_t user_wire, boolean_t fictitious) { vm_offset_t va; int rv; @@ -1057,7 +1055,7 @@ vm_fault_wire(map, start, end, user_wire) user_wire ? VM_FAULT_USER_WIRE : VM_FAULT_CHANGE_WIRING); if (rv) { if (va != start) - vm_fault_unwire(map, start, va); + vm_fault_unwire(map, start, va, fictitious); return (rv); } } @@ -1070,9 +1068,8 @@ vm_fault_wire(map, start, end, user_wire) * Unwire a range of virtual addresses in a map. */ void -vm_fault_unwire(map, start, end) - vm_map_t map; - vm_offset_t start, end; +vm_fault_unwire(vm_map_t map, vm_offset_t start, vm_offset_t end, + boolean_t fictitious) { vm_paddr_t pa; vm_offset_t va; @@ -1090,9 +1087,11 @@ vm_fault_unwire(map, start, end) pa = pmap_extract(pmap, va); if (pa != 0) { pmap_change_wiring(pmap, va, FALSE); - vm_page_lock_queues(); - vm_page_unwire(PHYS_TO_VM_PAGE(pa), 1); - vm_page_unlock_queues(); + if (!fictitious) { + vm_page_lock_queues(); + vm_page_unwire(PHYS_TO_VM_PAGE(pa), 1); + vm_page_unlock_queues(); + } } } if (pmap != kernel_pmap) |