Page MenuHomeFreeBSD

D20833.id59316.diff
No OneTemporary

D20833.id59316.diff

Index: vm_map.c
===================================================================
--- vm_map.c
+++ vm_map.c
@@ -2839,6 +2839,64 @@
}
/*
+ * vm_map_get_avail_entry:
+ *
+ * Get the first entry not less than start, or entry->start,
+ * once that entry is not in transition. Return NULL and
+ * set end if the entry comes after an unacceptible hole.
+ */
+static vm_map_entry_t
+vm_map_get_avail_entry(vm_map_t map, vm_offset_t start, vm_offset_t *end,
+ bool holes_ok, vm_map_entry_t entry, vm_map_entry_t *first_entry)
+{
+ unsigned int last_timestamp;
+ bool first_call;
+
+ first_call = entry == NULL;
+ for (;;) {
+ if (entry == NULL) {
+ if (!vm_map_lookup_entry(map, start, &entry)) {
+ if (!holes_ok) {
+ *end = start;
+ return (NULL);
+ }
+ entry = entry->next;
+ }
+ }
+ if (entry->start >= *end ||
+ (entry->eflags & MAP_ENTRY_IN_TRANSITION) == 0) {
+ if (first_call)
+ *first_entry = entry;
+ return (entry);
+ }
+
+ /*
+ * We have not yet clipped the entry.
+ */
+ start = ulmax(start, entry->start);
+ entry->eflags |= MAP_ENTRY_NEEDS_WAKEUP;
+ last_timestamp = map->timestamp;
+ if (vm_map_unlock_and_wait(map, 0)) {
+ /*
+ * Allow interruption of user unwiring?
+ */
+ }
+ vm_map_lock(map);
+ if (last_timestamp+1 != map->timestamp) {
+ /*
+ * Look again for the entry because the map was
+ * modified while it was unlocked. Specifically, the
+ * entry may have been clipped, merged, or deleted.
+ */
+ entry = NULL;
+ }
+ if (!first_call)
+ *first_entry = NULL;
+ }
+}
+
+
+/*
* vm_map_unwire:
*
* Implements both kernel and user unwiring.
@@ -2847,74 +2905,25 @@
vm_map_unwire(vm_map_t map, vm_offset_t start, vm_offset_t end,
int flags)
{
- vm_map_entry_t entry, first_entry, tmp_entry;
- vm_offset_t saved_start;
- unsigned int last_timestamp;
+ vm_map_entry_t entry, first_entry;
int rv;
- boolean_t need_wakeup, result, user_unwire;
+ boolean_t result;
+ bool holes_ok, need_wakeup, user_unwire;
if (start == end)
return (KERN_SUCCESS);
- user_unwire = (flags & VM_MAP_WIRE_USER) ? TRUE : FALSE;
+ user_unwire = (flags & VM_MAP_WIRE_USER) != 0;
+ holes_ok = (flags & VM_MAP_WIRE_HOLESOK) != 0;
vm_map_lock(map);
VM_MAP_RANGE_CHECK(map, start, end);
- if (!vm_map_lookup_entry(map, start, &first_entry)) {
- if (flags & VM_MAP_WIRE_HOLESOK)
- first_entry = first_entry->next;
- else {
- vm_map_unlock(map);
- return (KERN_INVALID_ADDRESS);
- }
+ entry = vm_map_get_avail_entry(map, start, &end, holes_ok,
+ NULL, &first_entry);
+ if (entry == NULL) {
+ vm_map_unlock(map);
+ return (KERN_INVALID_ADDRESS);
}
- last_timestamp = map->timestamp;
- entry = first_entry;
+ rv = KERN_SUCCESS;
while (entry->start < end) {
- if (entry->eflags & MAP_ENTRY_IN_TRANSITION) {
- /*
- * We have not yet clipped the entry.
- */
- saved_start = (start >= entry->start) ? start :
- entry->start;
- entry->eflags |= MAP_ENTRY_NEEDS_WAKEUP;
- if (vm_map_unlock_and_wait(map, 0)) {
- /*
- * Allow interruption of user unwiring?
- */
- }
- vm_map_lock(map);
- if (last_timestamp+1 != map->timestamp) {
- /*
- * Look again for the entry because the map was
- * modified while it was unlocked.
- * Specifically, the entry may have been
- * clipped, merged, or deleted.
- */
- if (!vm_map_lookup_entry(map, saved_start,
- &tmp_entry)) {
- if (flags & VM_MAP_WIRE_HOLESOK)
- tmp_entry = tmp_entry->next;
- else {
- if (saved_start == start) {
- /*
- * First_entry has been deleted.
- */
- vm_map_unlock(map);
- return (KERN_INVALID_ADDRESS);
- }
- end = saved_start;
- rv = KERN_INVALID_ADDRESS;
- goto done;
- }
- }
- if (entry == first_entry)
- first_entry = tmp_entry;
- else
- first_entry = NULL;
- entry = tmp_entry;
- }
- last_timestamp = map->timestamp;
- continue;
- }
vm_map_clip_start(map, entry, start);
vm_map_clip_end(map, entry, end);
/*
@@ -2930,11 +2939,11 @@
* Check the map for holes in the specified region.
* If VM_MAP_WIRE_HOLESOK was specified, skip this check.
*/
- if (((flags & VM_MAP_WIRE_HOLESOK) == 0) &&
+ if ((!holes_ok) &&
(entry->end < end && entry->next->start > entry->end)) {
end = entry->end;
rv = KERN_INVALID_ADDRESS;
- goto done;
+ break;
}
/*
* If system unwiring, require that the entry is system wired.
@@ -2943,19 +2952,22 @@
vm_map_entry_system_wired_count(entry) == 0) {
end = entry->end;
rv = KERN_INVALID_ARGUMENT;
- goto done;
+ break;
}
- entry = entry->next;
+ entry = vm_map_get_avail_entry(map, start, &end, holes_ok,
+ entry->next, &first_entry);
+ if (entry == NULL) {
+ rv = KERN_INVALID_ADDRESS;
+ break;
+ }
}
- rv = KERN_SUCCESS;
-done:
- need_wakeup = FALSE;
+ need_wakeup = false;
if (first_entry == NULL) {
result = vm_map_lookup_entry(map, start, &first_entry);
- if (!result && (flags & VM_MAP_WIRE_HOLESOK))
+ if (!result) {
+ KASSERT(holes_ok, ("vm_map_unwire: lookup failed"));
first_entry = first_entry->next;
- else
- KASSERT(result, ("vm_map_unwire: lookup failed"));
+ }
}
for (entry = first_entry; entry->start < end; entry = entry->next) {
/*
@@ -2969,7 +2981,7 @@
*/
if ((entry->eflags & MAP_ENTRY_IN_TRANSITION) == 0 ||
entry->wiring_thread != curthread) {
- KASSERT((flags & VM_MAP_WIRE_HOLESOK) != 0,
+ KASSERT(holes_ok,
("vm_map_unwire: !HOLESOK and new/changed entry"));
continue;
}
@@ -2991,7 +3003,7 @@
entry->wiring_thread = NULL;
if (entry->eflags & MAP_ENTRY_NEEDS_WAKEUP) {
entry->eflags &= ~MAP_ENTRY_NEEDS_WAKEUP;
- need_wakeup = TRUE;
+ need_wakeup = true;
}
vm_map_simplify_entry(map, entry);
}
@@ -3085,7 +3097,8 @@
u_long npages;
u_int last_timestamp;
int rv;
- boolean_t need_wakeup, result, user_wire;
+ boolean_t result;
+ bool holes_ok, need_wakeup, user_wire;
vm_prot_t prot;
VM_MAP_ASSERT_LOCKED(map);
@@ -3095,62 +3108,16 @@
prot = 0;
if (flags & VM_MAP_WIRE_WRITE)
prot |= VM_PROT_WRITE;
- user_wire = (flags & VM_MAP_WIRE_USER) ? TRUE : FALSE;
+ user_wire = (flags & VM_MAP_WIRE_USER) != 0;
+ holes_ok = (flags & VM_MAP_WIRE_HOLESOK) != 0;
VM_MAP_RANGE_CHECK(map, start, end);
- if (!vm_map_lookup_entry(map, start, &first_entry)) {
- if (flags & VM_MAP_WIRE_HOLESOK)
- first_entry = first_entry->next;
- else
- return (KERN_INVALID_ADDRESS);
- }
+ entry = vm_map_get_avail_entry(map, start, &end, holes_ok,
+ NULL, &first_entry);
+ if (entry == NULL)
+ return (KERN_INVALID_ADDRESS);
+ rv = KERN_SUCCESS;
last_timestamp = map->timestamp;
- entry = first_entry;
while (entry->start < end) {
- if (entry->eflags & MAP_ENTRY_IN_TRANSITION) {
- /*
- * We have not yet clipped the entry.
- */
- saved_start = (start >= entry->start) ? start :
- entry->start;
- entry->eflags |= MAP_ENTRY_NEEDS_WAKEUP;
- if (vm_map_unlock_and_wait(map, 0)) {
- /*
- * Allow interruption of user wiring?
- */
- }
- vm_map_lock(map);
- if (last_timestamp + 1 != map->timestamp) {
- /*
- * Look again for the entry because the map was
- * modified while it was unlocked.
- * Specifically, the entry may have been
- * clipped, merged, or deleted.
- */
- if (!vm_map_lookup_entry(map, saved_start,
- &tmp_entry)) {
- if (flags & VM_MAP_WIRE_HOLESOK)
- tmp_entry = tmp_entry->next;
- else {
- if (saved_start == start) {
- /*
- * first_entry has been deleted.
- */
- return (KERN_INVALID_ADDRESS);
- }
- end = saved_start;
- rv = KERN_INVALID_ADDRESS;
- goto done;
- }
- }
- if (entry == first_entry)
- first_entry = tmp_entry;
- else
- first_entry = NULL;
- entry = tmp_entry;
- }
- last_timestamp = map->timestamp;
- continue;
- }
vm_map_clip_start(map, entry, start);
vm_map_clip_end(map, entry, end);
/*
@@ -3165,14 +3132,12 @@
if ((entry->protection & (VM_PROT_READ | VM_PROT_EXECUTE)) == 0
|| (entry->protection & prot) != prot) {
entry->eflags |= MAP_ENTRY_WIRE_SKIPPED;
- if ((flags & VM_MAP_WIRE_HOLESOK) == 0) {
+ if (!holes_ok) {
end = entry->end;
rv = KERN_INVALID_ADDRESS;
- goto done;
+ break;
}
- goto next_entry;
- }
- if (entry->wired_count == 0) {
+ } else if (entry->wired_count == 0) {
entry->wired_count++;
npages = atop(entry->end - entry->start);
@@ -3181,7 +3146,7 @@
entry->start);
end = entry->end;
rv = KERN_RESOURCE_SHORTAGE;
- goto done;
+ break;
}
/*
@@ -3240,7 +3205,7 @@
if (user_wire)
vm_map_wire_user_count_sub(npages);
end = entry->end;
- goto done;
+ break;
}
} else if (!user_wire ||
(entry->eflags & MAP_ENTRY_USER_WIRED) == 0) {
@@ -3250,24 +3215,27 @@
* Check the map for holes in the specified region.
* If VM_MAP_WIRE_HOLESOK was specified, skip this check.
*/
- next_entry:
- if ((flags & VM_MAP_WIRE_HOLESOK) == 0 &&
+ if (!holes_ok &&
entry->end < end && entry->next->start > entry->end) {
end = entry->end;
rv = KERN_INVALID_ADDRESS;
- goto done;
+ break;
}
- entry = entry->next;
+ entry = vm_map_get_avail_entry(map, start, &end, holes_ok,
+ entry->next, &first_entry);
+ if (entry == NULL) {
+ rv = KERN_INVALID_ADDRESS;
+ break;
+ }
+ last_timestamp = map->timestamp;
}
- rv = KERN_SUCCESS;
-done:
- need_wakeup = FALSE;
+ need_wakeup = false;
if (first_entry == NULL) {
result = vm_map_lookup_entry(map, start, &first_entry);
- if (!result && (flags & VM_MAP_WIRE_HOLESOK))
+ if (!result) {
+ KASSERT(holes_ok, ("vm_map_wire: lookup failed"));
first_entry = first_entry->next;
- else
- KASSERT(result, ("vm_map_wire: lookup failed"));
+ }
}
for (entry = first_entry; entry->start < end; entry = entry->next) {
/*
@@ -3281,15 +3249,14 @@
*/
if ((entry->eflags & MAP_ENTRY_IN_TRANSITION) == 0 ||
entry->wiring_thread != curthread) {
- KASSERT((flags & VM_MAP_WIRE_HOLESOK) != 0,
+ KASSERT(holes_ok,
("vm_map_wire: !HOLESOK and new/changed entry"));
continue;
}
- if ((entry->eflags & MAP_ENTRY_WIRE_SKIPPED) != 0)
- goto next_entry_done;
-
- if (rv == KERN_SUCCESS) {
+ if ((entry->eflags & MAP_ENTRY_WIRE_SKIPPED) != 0) {
+ /* do nothing */
+ } else if (rv == KERN_SUCCESS) {
if (user_wire)
entry->eflags |= MAP_ENTRY_USER_WIRED;
} else if (entry->wired_count == -1) {
@@ -3312,7 +3279,6 @@
} else
entry->wired_count--;
}
- next_entry_done:
KASSERT((entry->eflags & MAP_ENTRY_IN_TRANSITION) != 0,
("vm_map_wire: in-transition flag missing %p", entry));
KASSERT(entry->wiring_thread == curthread,
@@ -3322,7 +3288,7 @@
entry->wiring_thread = NULL;
if (entry->eflags & MAP_ENTRY_NEEDS_WAKEUP) {
entry->eflags &= ~MAP_ENTRY_NEEDS_WAKEUP;
- need_wakeup = TRUE;
+ need_wakeup = true;
}
vm_map_simplify_entry(map, entry);
}

File Metadata

Mime Type
text/plain
Expires
Mon, Mar 10, 12:32 AM (9 h, 33 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17077857
Default Alt Text
D20833.id59316.diff (10 KB)

Event Timeline