Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F169466079
D20833.id59422.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D20833.id59422.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D20833: factor out common wiring code
Attached
Detach File
Event Timeline
Log In to Comment