summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_fault.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_fault.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_fault.c')
-rw-r--r--sys/vm/vm_fault.c21
1 files changed, 10 insertions, 11 deletions
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 000e2a2..562d255 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)
OpenPOWER on IntegriCloud