Page MenuHomeFreeBSD

D20833.id59422.diff
No OneTemporary

D20833.id59422.diff

Index: vm_map.c
===================================================================
--- vm_map.c
+++ vm_map.c
@@ -2837,6 +2837,61 @@
}
/*
+ * 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 unacceptable 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 in_entry, vm_map_entry_t *first_entry)
+{
+ vm_map_entry_t entry;
+ unsigned int last_timestamp;
+
+ entry = in_entry;
+ 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 (in_entry == NULL)
+ *first_entry = entry;
+ return (entry);
+ }
+
+ /*
+ * We have not yet clipped the entry.
+ */
+ start = MAX(start, entry->start);
+ entry->eflags |= MAP_ENTRY_NEEDS_WAKEUP;
+ last_timestamp = map->timestamp;
+ /* Allow interruption of user unwiring. */
+ vm_map_unlock_and_wait(map, 0);
+ 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 (in_entry != NULL)
+ *first_entry = NULL;
+ }
+}
+
+
+/*
* vm_map_unwire:
*
* Implements both kernel and user unwiring.
@@ -2845,9 +2900,7 @@
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;
bool holes_ok, need_wakeup, user_unwire;
@@ -2857,64 +2910,14 @@
user_unwire = (flags & VM_MAP_WIRE_USER) != 0;
vm_map_lock(map);
VM_MAP_RANGE_CHECK(map, start, end);
- if (!vm_map_lookup_entry(map, start, &first_entry)) {
- if (holes_ok)
- 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 (holes_ok)
- 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;
- break;
- }
- }
- 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);
/*
@@ -2931,7 +2934,7 @@
* If holes_ok, skip this check.
*/
if (!holes_ok &&
- (entry->end < end && entry->next->start > entry->end)) {
+ entry->end < end && entry->next->start > entry->end) {
end = entry->end;
rv = KERN_INVALID_ADDRESS;
break;
@@ -2945,7 +2948,12 @@
rv = KERN_INVALID_ARGUMENT;
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;
+ }
}
need_wakeup = false;
if (first_entry == NULL &&
@@ -3094,60 +3102,11 @@
holes_ok = (flags & VM_MAP_WIRE_HOLESOK) != 0;
user_wire = (flags & VM_MAP_WIRE_USER) != 0;
VM_MAP_RANGE_CHECK(map, start, end);
- if (!vm_map_lookup_entry(map, start, &first_entry)) {
- if (holes_ok)
- first_entry = first_entry->next;
- else
- return (KERN_INVALID_ADDRESS);
- }
- last_timestamp = map->timestamp;
- entry = first_entry;
+ entry = vm_map_get_avail_entry(map, start, &end, holes_ok,
+ NULL, &first_entry);
+ if (entry == NULL)
+ return (KERN_INVALID_ADDRESS);
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 (holes_ok)
- 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);
/*
@@ -3185,6 +3144,7 @@
*/
saved_start = entry->start;
saved_end = entry->end;
+ last_timestamp = map->timestamp;
vm_map_busy(map);
vm_map_unlock(map);
@@ -3230,7 +3190,6 @@
entry = entry->next;
}
}
- last_timestamp = map->timestamp;
if (rv != KERN_SUCCESS) {
vm_map_wire_entry_failure(map, entry, faddr);
if (user_wire)
@@ -3252,7 +3211,12 @@
rv = KERN_INVALID_ADDRESS;
goto done;
}
- 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;
+ goto done;
+ }
}
rv = KERN_SUCCESS;
done:

File Metadata

Mime Type
text/plain
Expires
Wed, Sep 2, 2:56 PM (19 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37977381
Default Alt Text
D20833.id59422.diff (6 KB)

Event Timeline