Changeset View
Changeset View
Standalone View
Standalone View
sys/vm/vm_map.c
Show First 20 Lines • Show All 2,917 Lines • ▼ Show 20 Lines | vm_map_wire_entry_failure(vm_map_t map, vm_map_entry_t entry, | ||||
/* | /* | ||||
* Assign an out-of-range value to represent the failure to wire this | * Assign an out-of-range value to represent the failure to wire this | ||||
* entry. | * entry. | ||||
*/ | */ | ||||
entry->wired_count = -1; | entry->wired_count = -1; | ||||
} | } | ||||
static bool | |||||
vm_map_wire_user_count_adj(vm_offset_t start, vm_offset_t end, int flags) | |||||
{ | |||||
u_long npages, wired; | |||||
if ((flags & VM_MAP_WIRE_USER) == 0) | |||||
return (true); | |||||
npages = atop(end - start); | |||||
if ((flags & VM_MAP_WIRE_USER_NOLIM) != 0) { | |||||
atomic_add_long(&vm_user_wire_count, npages); | |||||
return (true); | |||||
} | |||||
wired = vm_user_wire_count; | |||||
do { | |||||
if (npages + wired > vm_page_max_user_wired) { | |||||
return (false); | |||||
} | |||||
} while (!atomic_fcmpset_long(&vm_user_wire_count, &wired, | |||||
npages + wired)); | |||||
return (true); | |||||
} | |||||
/* | /* | ||||
* vm_map_wire: | * vm_map_wire: | ||||
* | * | ||||
* Implements both kernel and user wiring. | * Implements both kernel and user wiring. | ||||
*/ | */ | ||||
int | int | ||||
vm_map_wire(vm_map_t map, vm_offset_t start, vm_offset_t end, | vm_map_wire(vm_map_t map, vm_offset_t start, vm_offset_t end, | ||||
int flags) | int flags) | ||||
{ | { | ||||
vm_map_entry_t entry, first_entry, tmp_entry; | vm_map_entry_t entry, first_entry, tmp_entry; | ||||
vm_offset_t faddr, saved_end, saved_start; | vm_offset_t faddr, saved_end, saved_start; | ||||
u_long size, wired; | |||||
u_int last_timestamp; | u_int last_timestamp; | ||||
int rv; | int rv; | ||||
boolean_t need_wakeup, result, user_wire; | boolean_t need_wakeup, result, user_wire; | ||||
vm_prot_t prot; | vm_prot_t prot; | ||||
if (start == end) | if (start == end) | ||||
return (KERN_SUCCESS); | return (KERN_SUCCESS); | ||||
prot = 0; | prot = 0; | ||||
▲ Show 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | if ((entry->protection & (VM_PROT_READ | VM_PROT_EXECUTE)) == 0 | ||||
} | } | ||||
goto next_entry; | goto next_entry; | ||||
} | } | ||||
if (entry->wired_count == 0) { | if (entry->wired_count == 0) { | ||||
entry->wired_count++; | entry->wired_count++; | ||||
saved_start = entry->start; | saved_start = entry->start; | ||||
saved_end = entry->end; | saved_end = entry->end; | ||||
if (user_wire) { | if (!vm_map_wire_user_count_adj(saved_start, saved_end, | ||||
size = atop(saved_end - saved_start); | flags)) { | ||||
wired = vm_user_wire_count; | |||||
do { | |||||
if (size + wired > | |||||
vm_page_max_user_wired) { | |||||
end = saved_start; | end = saved_start; | ||||
rv = KERN_RESOURCE_SHORTAGE; | rv = KERN_RESOURCE_SHORTAGE; | ||||
goto done; | goto done; | ||||
} | |||||
} while (!atomic_fcmpset_long( | |||||
&vm_user_wire_count, &wired, | |||||
size + wired)); | |||||
} | } | ||||
/* | /* | ||||
* Release the map lock, relying on the in-transition | * Release the map lock, relying on the in-transition | ||||
* mark. Mark the map busy for fork. | * mark. Mark the map busy for fork. | ||||
*/ | */ | ||||
vm_map_busy(map); | vm_map_busy(map); | ||||
vm_map_unlock(map); | vm_map_unlock(map); | ||||
▲ Show 20 Lines • Show All 1,732 Lines • Show Last 20 Lines |