Page MenuHomeFreeBSD

D13346.id36119.diff
No OneTemporary

D13346.id36119.diff

Index: vm/vm_map.c
===================================================================
--- vm/vm_map.c
+++ vm/vm_map.c
@@ -1498,8 +1498,8 @@
vm_size_t length, vm_offset_t max_addr, int find_space,
vm_prot_t prot, vm_prot_t max, int cow)
{
- vm_offset_t alignment, initial_addr, start;
- int result;
+ vm_offset_t aligned_addr, alignment, min_addr, orig_addr;
+ int rv;
KASSERT((cow & (MAP_STACK_GROWS_DOWN | MAP_STACK_GROWS_UP)) == 0 ||
object == NULL,
@@ -1512,50 +1512,76 @@
alignment = (vm_offset_t)1 << (find_space >> 8);
} else
alignment = 0;
- initial_addr = *addr;
vm_map_lock(map);
+ if (find_space != VMFS_NO_SPACE) {
+ min_addr = *addr;
again:
- start = initial_addr;
- do {
- if (find_space != VMFS_NO_SPACE) {
- if (vm_map_findspace(map, start, length, addr) ||
+ if (vm_map_findspace(map, min_addr, length, addr) ||
+ (max_addr != 0 && *addr + length > max_addr)) {
+ rv = KERN_NO_SPACE;
+ goto done;
+ }
+ while (find_space != VMFS_ANY_SPACE) {
+ /*
+ * At the start of every iteration, the free space at
+ * address "*addr" is at least "length" bytes.
+ */
+ orig_addr = *addr;
+ if (find_space == VMFS_SUPER_SPACE ||
+ find_space == VMFS_OPTIMAL_SPACE) {
+ pmap_align_superpage(object, offset, addr,
+ length);
+ } else if ((*addr & (alignment - 1)) != 0) {
+ *addr &= ~(alignment - 1);
+ *addr += alignment;
+ }
+ aligned_addr = *addr;
+ if (aligned_addr == orig_addr) {
+ /*
+ * Alignment did not change "*addr", so
+ * "*addr" must still provide sufficient
+ * free space.
+ */
+ break;
+ }
+
+ /*
+ * Test for address wrap on "*addr". A wrapped
+ * "*addr" could be a valid address, in which case
+ * vm_map_findspace() cannot be relied upon to fail.
+ */
+ if (aligned_addr < orig_addr ||
+ vm_map_findspace(map, aligned_addr, length,
+ addr) ||
(max_addr != 0 && *addr + length > max_addr)) {
if (find_space == VMFS_OPTIMAL_SPACE) {
find_space = VMFS_ANY_SPACE;
goto again;
}
- vm_map_unlock(map);
- return (KERN_NO_SPACE);
+ rv = KERN_NO_SPACE;
+ goto done;
}
- switch (find_space) {
- case VMFS_SUPER_SPACE:
- case VMFS_OPTIMAL_SPACE:
- pmap_align_superpage(object, offset, addr,
- length);
+ if (*addr == aligned_addr) {
+ /*
+ * If a successful call to vm_map_findspace()
+ * did not change "*addr", then "*addr" must
+ * still be aligned and provide sufficient
+ * free space.
+ */
break;
- case VMFS_ANY_SPACE:
- break;
- default:
- if ((*addr & (alignment - 1)) != 0) {
- *addr &= ~(alignment - 1);
- *addr += alignment;
- }
- break;
}
-
- start = *addr;
}
- if ((cow & (MAP_STACK_GROWS_DOWN | MAP_STACK_GROWS_UP)) != 0) {
- result = vm_map_stack_locked(map, start, length,
- sgrowsiz, prot, max, cow);
- } else {
- result = vm_map_insert(map, object, offset, start,
- start + length, prot, max, cow);
- }
- } while (result == KERN_NO_SPACE && find_space != VMFS_NO_SPACE &&
- find_space != VMFS_ANY_SPACE);
+ }
+ if ((cow & (MAP_STACK_GROWS_DOWN | MAP_STACK_GROWS_UP)) != 0) {
+ rv = vm_map_stack_locked(map, *addr, length, sgrowsiz, prot,
+ max, cow);
+ } else {
+ rv = vm_map_insert(map, object, offset, *addr, *addr + length,
+ prot, max, cow);
+ }
+done:
vm_map_unlock(map);
- return (result);
+ return (rv);
}
int

File Metadata

Mime Type
text/plain
Expires
Sun, Mar 29, 11:00 PM (13 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30559851
Default Alt Text
D13346.id36119.diff (3 KB)

Event Timeline