Page MenuHomeFreeBSD

D13155.1789771668.diff
No OneTemporary

Size
4 KB
Referenced Files
None
Subscribers
None

D13155.1789771668.diff

Index: sys/vm/vm_map.c
===================================================================
--- sys/vm/vm_map.c
+++ sys/vm/vm_map.c
@@ -1483,50 +1483,24 @@
return (result);
}
-/*
- * vm_map_find finds an unallocated region in the target address
- * map with the given length. The search is defined to be
- * first-fit from the specified address; the region found is
- * returned in the same parameter.
- *
- * If object is non-NULL, ref count must be bumped by caller
- * prior to making call to account for the new entry.
- */
-int
-vm_map_find(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
- vm_offset_t *addr, /* IN/OUT */
- vm_size_t length, vm_offset_t max_addr, int find_space,
- vm_prot_t prot, vm_prot_t max, int cow)
+static int
+vm_map_find_locked(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
+ vm_offset_t *addr, vm_size_t length, vm_offset_t max_addr, int find_space,
+ vm_offset_t alignment, vm_prot_t prot, vm_prot_t max, int cow)
{
- vm_offset_t alignment, initial_addr, start;
+ vm_offset_t start;
+#ifdef INVARIANTS
+ vm_offset_t prev_start;
+#endif
int result;
- KASSERT((cow & (MAP_STACK_GROWS_DOWN | MAP_STACK_GROWS_UP)) == 0 ||
- object == NULL,
- ("vm_map_find: non-NULL backing object for stack"));
- if (find_space == VMFS_OPTIMAL_SPACE && (object == NULL ||
- (object->flags & OBJ_COLORED) == 0))
- find_space = VMFS_ANY_SPACE;
- if (find_space >> 8 != 0) {
- KASSERT((find_space & 0xff) == 0, ("bad VMFS flags"));
- alignment = (vm_offset_t)1 << (find_space >> 8);
- } else
- alignment = 0;
- initial_addr = *addr;
- vm_map_lock(map);
-again:
- start = initial_addr;
+ start = *addr;
+ result = KERN_SUCCESS;
do {
if (find_space != VMFS_NO_SPACE) {
if (vm_map_findspace(map, start, 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);
+ (max_addr != 0 && *addr + length > max_addr))
return (KERN_NO_SPACE);
- }
switch (find_space) {
case VMFS_SUPER_SPACE:
case VMFS_OPTIMAL_SPACE:
@@ -1542,9 +1516,13 @@
}
break;
}
-
+ if (*addr < start || *addr + length < *addr ||
+ *addr + length < length ||
+ (max_addr != 0 && *addr + length > max_addr))
+ return (KERN_NO_SPACE);
start = *addr;
}
+ MPASS(result == KERN_SUCCESS || prev_start < start);
if ((cow & (MAP_STACK_GROWS_DOWN | MAP_STACK_GROWS_UP)) != 0) {
result = vm_map_stack_locked(map, start, length,
sgrowsiz, prot, max, cow);
@@ -1552,12 +1530,68 @@
result = vm_map_insert(map, object, offset, start,
start + length, prot, max, cow);
}
+#ifdef INVARIANTS
+ prev_start = start;
+#endif
} while (result == KERN_NO_SPACE && find_space != VMFS_NO_SPACE &&
find_space != VMFS_ANY_SPACE);
+ return (result);
+}
+
+
+/*
+ * vm_map_find finds an unallocated region in the target address
+ * map with the given length. The search is defined to be
+ * first-fit from the specified address; the region found is
+ * returned in the same parameter.
+ *
+ * If object is non-NULL, ref count must be bumped by caller
+ * prior to making call to account for the new entry.
+ */
+int
+vm_map_find(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
+ vm_offset_t *addr /* IN/OUT */, 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;
+ int result;
+
+ KASSERT((cow & (MAP_STACK_GROWS_DOWN | MAP_STACK_GROWS_UP)) == 0 ||
+ object == NULL,
+ ("vm_map_find: non-NULL backing object for stack"));
+ if (find_space == VMFS_OPTIMAL_SPACE && (object == NULL ||
+ (object->flags & OBJ_COLORED) == 0))
+ find_space = VMFS_ANY_SPACE;
+ if (find_space >> 8 != 0) {
+ KASSERT((find_space & 0xff) == 0, ("bad VMFS flags"));
+ alignment = (vm_offset_t)1 << (find_space >> 8);
+ } else
+ alignment = 0;
+ initial_addr = *addr;
+ vm_map_lock(map);
+ for (;;) {
+ result = vm_map_find_locked(map, object, offset, addr, length,
+ max_addr, find_space, alignment, prot, max, cow);
+ if (result == KERN_SUCCESS || find_space != VMFS_OPTIMAL_SPACE)
+ break;
+ find_space = VMFS_ANY_SPACE;
+ *addr = initial_addr;
+ }
vm_map_unlock(map);
return (result);
}
+/*
+ * vm_map_find_min: A wrapper around vm_map_find(). It treats
+ * the passed address (*addr) as the hint and not as the absolute
+ * minimal address of the range where the mapping is created.
+ *
+ * Function works in two phases. First, try to allocate above
+ * the hint. If that fails, do the second pass with less
+ * restrictive constraints for the start of allocation by
+ * specifying minimal allocation address as the start, if this
+ * limit is less than hint.
+ */
int
vm_map_find_min(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
vm_offset_t *addr, vm_size_t length, vm_offset_t min_addr,

File Metadata

Mime Type
text/plain
Expires
Fri, Sep 18, 10:47 PM (1 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29763764
Default Alt Text
D13155.1789771668.diff (4 KB)

Event Timeline