Changeset View
Changeset View
Standalone View
Standalone View
sys/vm/vm_map.c
Context not available. | |||||
* Initialize an existing vm_map structure | * Initialize an existing vm_map structure | ||||
* such as that in the vmspace structure. | * such as that in the vmspace structure. | ||||
*/ | */ | ||||
static void | static void | ||||
_vm_map_init(vm_map_t map, pmap_t pmap, vm_offset_t min, vm_offset_t max) | _vm_map_init(vm_map_t map, pmap_t pmap, vm_offset_t min, vm_offset_t max) | ||||
{ | { | ||||
map->header.next = map->header.prev = &map->header; | map->header.next = map->header.prev = &map->header; | ||||
map->header.eflags = MAP_ENTRY_HEADER; | map->header.eflags = MAP_ENTRY_HEADER; | ||||
map->needs_wakeup = FALSE; | map->needs_wakeup = FALSE; | ||||
map->system_map = 0; | map->system_map = 0; | ||||
map->pmap = pmap; | map->pmap = pmap; | ||||
map->header.end = min; | map->header.end = min; | ||||
map->header.start = max; | map->header.start = max; | ||||
map->flags = 0; | map->flags = 0; | ||||
map->root = NULL; | map->root = map->header.right = &map->header; | ||||
map->header.left = NULL; | |||||
map->header.adj_free = max - min; | |||||
map->header.max_free = map->header.adj_free; | |||||
map->timestamp = 0; | map->timestamp = 0; | ||||
map->busy = 0; | map->busy = 0; | ||||
} | } | ||||
void | void | ||||
vm_map_init(vm_map_t map, pmap_t pmap, vm_offset_t min, vm_offset_t max) | vm_map_init(vm_map_t map, pmap_t pmap, vm_offset_t min, vm_offset_t max) | ||||
{ | { | ||||
Show All 14 Lines | |||||
entry->max_free = entry->adj_free; | entry->max_free = entry->adj_free; | ||||
if (entry->left != NULL && entry->left->max_free > entry->max_free) | if (entry->left != NULL && entry->left->max_free > entry->max_free) | ||||
entry->max_free = entry->left->max_free; | entry->max_free = entry->left->max_free; | ||||
if (entry->right != NULL && entry->right->max_free > entry->max_free) | if (entry->right != NULL && entry->right->max_free > entry->max_free) | ||||
entry->max_free = entry->right->max_free; | entry->max_free = entry->right->max_free; | ||||
} | } | ||||
/* | /* | ||||
* vm_map_entry_splay: | * Walk down the tree until we find addr or a NULL pointer where addr would go, | ||||
* | * breaking off left and right subtrees of nodes less than, or greater than | ||||
* The Sleator and Tarjan top-down splay algorithm with the | * addr. llist and rlist are the two sides in reverse order (bottom-up), with | ||||
* following variation. Max_free must be computed bottom-up, so | * llist linked by the right pointer and rlist linked by the left pointer in the | ||||
* on the downward pass, maintain the left and right spines in | * vm_map_entry. | ||||
* reverse order. Then, make a second pass up each side to fix | |||||
* the pointers and compute max_free. The time bound is O(log n) | |||||
* amortized. | |||||
* | |||||
* The new root is the vm_map_entry containing "addr", or else an | |||||
* adjacent entry (lower or higher) if addr is not in the tree. | |||||
* | |||||
* The map must be locked, and leaves it so. | |||||
* | |||||
* Returns: the new root. | |||||
*/ | */ | ||||
static vm_map_entry_t | static vm_map_entry_t | ||||
vm_map_entry_splay(vm_offset_t addr, vm_map_entry_t root) | vm_map_entry_splay_split(vm_offset_t addr, vm_map_entry_t root, | ||||
vm_map_entry_t *out_llist, vm_map_entry_t *out_rlist) | |||||
{ | { | ||||
vm_map_entry_t llist, rlist; | vm_map_entry_t llist, rlist; | ||||
vm_map_entry_t ltree, rtree; | |||||
vm_map_entry_t y; | vm_map_entry_t y; | ||||
/* Special case of empty tree. */ | |||||
if (root == NULL) | |||||
return (root); | |||||
/* | |||||
* Pass One: Splay down the tree until we find addr or a NULL | |||||
* pointer where addr would go. llist and rlist are the two | |||||
* sides in reverse order (bottom-up), with llist linked by | |||||
* the right pointer and rlist linked by the left pointer in | |||||
* the vm_map_entry. Wait until Pass Two to set max_free on | |||||
* the two spines. | |||||
*/ | |||||
llist = NULL; | llist = NULL; | ||||
rlist = NULL; | rlist = NULL; | ||||
for (;;) { | for (;;) { | ||||
/* root is never NULL in here. */ | /* | ||||
if (addr < root->start) { | * Examine the start node of an entry before the end node if and | ||||
y = root->left; | * only if we arrive at the entry by following a right pointer. | ||||
if (y == NULL) | * Assume we arrive at the root via a left pointer. | ||||
break; | */ | ||||
if (addr < y->start && y->left != NULL) { | while (addr >= root->end) { | ||||
/* Rotate right and put y on rlist. */ | y = root->right; | ||||
root->left = y->right; | if (y != NULL && addr >= y->start) { | ||||
y->right = root; | /* Rotate left. */ | ||||
root->right = y->left; | |||||
y->left = root; | |||||
vm_map_entry_set_max_free(root); | vm_map_entry_set_max_free(root); | ||||
root = y->left; | |||||
y->left = rlist; | |||||
rlist = y; | |||||
} else { | |||||
/* Put root on rlist. */ | |||||
root->left = rlist; | |||||
rlist = root; | |||||
root = y; | root = y; | ||||
if (addr < root->end) | |||||
break; | |||||
y = root->right; | |||||
} | } | ||||
} else if (addr >= root->end) { | /* Put root on llist. */ | ||||
y = root->right; | root->right = llist; | ||||
if (y == NULL) | llist = root; | ||||
root = y; | |||||
if (root == NULL || addr < root->start) | |||||
break; | break; | ||||
if (addr >= y->end && y->right != NULL) { | } | ||||
/* Rotate left and put y on llist. */ | if (root == NULL || addr >= root->start) | ||||
root->right = y->left; | break; | ||||
y->left = root; | |||||
while (addr < root->start) { | |||||
y = root->left; | |||||
if (y != NULL && addr < y->end) { | |||||
/* Rotate right. */ | |||||
root->left = y->right; | |||||
y->right = root; | |||||
vm_map_entry_set_max_free(root); | vm_map_entry_set_max_free(root); | ||||
root = y->right; | |||||
y->right = llist; | |||||
llist = y; | |||||
} else { | |||||
/* Put root on llist. */ | |||||
root->right = llist; | |||||
llist = root; | |||||
root = y; | root = y; | ||||
if (addr >= root->start) | |||||
break; | |||||
y = root->left; | |||||
} | } | ||||
} else | /* Put root on rlist. */ | ||||
root->left = rlist; | |||||
rlist = root; | |||||
root = y; | |||||
if (root == NULL || addr >= root->end) | |||||
break; | |||||
} | |||||
if (root == NULL || addr < root->end) | |||||
break; | break; | ||||
} | } | ||||
*out_llist = llist; | |||||
*out_rlist = rlist; | |||||
return (root); | |||||
} | |||||
/* | |||||
* Walk back up the two spines, flip the pointers and set max_free. The | |||||
* subtrees of the root go at the bottom of llist and rlist. | |||||
*/ | |||||
static vm_map_entry_t | |||||
vm_map_entry_splay_merge(vm_map_entry_t root, | |||||
vm_map_entry_t llist, vm_map_entry_t rlist, | |||||
vm_map_entry_t ltree, vm_map_entry_t rtree) | |||||
{ | |||||
vm_map_entry_t y; | |||||
/* | |||||
* Pass Two: Walk back up the two spines, flip the pointers | |||||
* and set max_free. The subtrees of the root go at the | |||||
* bottom of llist and rlist. | |||||
*/ | |||||
ltree = root->left; | |||||
while (llist != NULL) { | while (llist != NULL) { | ||||
y = llist->right; | y = llist->right; | ||||
llist->right = ltree; | llist->right = ltree; | ||||
vm_map_entry_set_max_free(llist); | vm_map_entry_set_max_free(llist); | ||||
ltree = llist; | ltree = llist; | ||||
llist = y; | llist = y; | ||||
} | } | ||||
rtree = root->right; | |||||
while (rlist != NULL) { | while (rlist != NULL) { | ||||
y = rlist->left; | y = rlist->left; | ||||
rlist->left = rtree; | rlist->left = rtree; | ||||
vm_map_entry_set_max_free(rlist); | vm_map_entry_set_max_free(rlist); | ||||
rtree = rlist; | rtree = rlist; | ||||
rlist = y; | rlist = y; | ||||
} | } | ||||
/* | /* | ||||
* Final assembly: add ltree and rtree as subtrees of root. | * Final assembly: add ltree and rtree as subtrees of root. | ||||
*/ | */ | ||||
root->left = ltree; | root->left = ltree; | ||||
root->right = rtree; | root->right = rtree; | ||||
vm_map_entry_set_max_free(root); | vm_map_entry_set_max_free(root); | ||||
return (root); | return (root); | ||||
} | } | ||||
/* | |||||
* vm_map_entry_splay: | |||||
* | |||||
* The Sleator and Tarjan top-down splay algorithm with the | |||||
* following variation. Max_free must be computed bottom-up, so | |||||
* on the downward pass, maintain the left and right spines in | |||||
* reverse order. Then, make a second pass up each side to fix | |||||
* the pointers and compute max_free. The time bound is O(log n) | |||||
* amortized. | |||||
* | |||||
* The new root is the vm_map_entry containing "addr", or else | |||||
* the next lower entry if addr is not in the tree. | |||||
* | |||||
* The map must be locked, and leaves it so. | |||||
* | |||||
*/ | |||||
static vm_map_entry_t | |||||
vm_map_entry_splay(vm_offset_t addr, vm_map_entry_t root) | |||||
{ | |||||
vm_map_entry_t llist, rlist; | |||||
root = vm_map_entry_splay_split(addr, root, &llist, &rlist); | |||||
if (root == NULL) { | |||||
/* | |||||
* With no matching node found, and no new node to | |||||
* insert, recover the greatest node in the left | |||||
* subtree and make it the root. There is such a | |||||
* node, since map->header is in the tree and left of | |||||
* all addresses. | |||||
*/ | |||||
root = llist; | |||||
llist = root->right; | |||||
root->right = NULL; | |||||
} | |||||
return (vm_map_entry_splay_merge(root, llist, rlist, | |||||
root->left, root->right)); | |||||
} | |||||
/* | /* | ||||
* vm_map_entry_{un,}link: | * vm_map_entry_{un,}link: | ||||
* | * | ||||
* Insert/remove entries from maps. | * Insert/remove entries from maps. | ||||
*/ | */ | ||||
static void | static void | ||||
vm_map_entry_link(vm_map_t map, | vm_map_entry_link(vm_map_t map, | ||||
vm_map_entry_t after_where, | |||||
vm_map_entry_t entry) | vm_map_entry_t entry) | ||||
{ | { | ||||
vm_map_entry_t llist, rlist, root; | |||||
CTR4(KTR_VM, | CTR3(KTR_VM, | ||||
"vm_map_entry_link: map %p, nentries %d, entry %p, after %p", map, | "vm_map_entry_link: map %p, nentries %d, entry %p", map, | ||||
map->nentries, entry, after_where); | map->nentries, entry); | ||||
VM_MAP_ASSERT_LOCKED(map); | VM_MAP_ASSERT_LOCKED(map); | ||||
KASSERT(after_where->end <= entry->start, | |||||
("vm_map_entry_link: prev end %jx new start %jx overlap", | |||||
(uintmax_t)after_where->end, (uintmax_t)entry->start)); | |||||
KASSERT(entry->end <= after_where->next->start, | |||||
("vm_map_entry_link: new end %jx next start %jx overlap", | |||||
(uintmax_t)entry->end, (uintmax_t)after_where->next->start)); | |||||
map->nentries++; | map->nentries++; | ||||
entry->prev = after_where; | root = map->root; | ||||
entry->next = after_where->next; | root = vm_map_entry_splay_split(entry->start, root, &llist, &rlist); | ||||
entry->next->prev = entry; | KASSERT(root == NULL, | ||||
after_where->next = entry; | ("vm_map_entry_link: link object already mapped")); | ||||
entry->prev = llist; | |||||
if (after_where != &map->header) { | entry->next = rlist; | ||||
if (after_where != map->root) | llist->next = rlist->prev = entry; | ||||
vm_map_entry_splay(after_where->start, map->root); | llist->adj_free = entry->start - llist->end; | ||||
entry->right = after_where->right; | entry->adj_free = rlist->start - entry->end; | ||||
entry->left = after_where; | root = vm_map_entry_splay_merge(entry, llist, rlist, NULL, NULL); | ||||
after_where->right = NULL; | |||||
after_where->adj_free = entry->start - after_where->end; | |||||
vm_map_entry_set_max_free(after_where); | |||||
} else { | |||||
entry->right = map->root; | |||||
entry->left = NULL; | |||||
} | |||||
entry->adj_free = entry->next->start - entry->end; | |||||
vm_map_entry_set_max_free(entry); | |||||
map->root = entry; | map->root = entry; | ||||
} | } | ||||
static void | static void | ||||
vm_map_entry_unlink(vm_map_t map, | vm_map_entry_unlink(vm_map_t map, | ||||
vm_map_entry_t entry) | vm_map_entry_t entry) | ||||
{ | { | ||||
vm_map_entry_t next, prev, root; | vm_map_entry_t llist, root, rlist, tree, y; | ||||
VM_MAP_ASSERT_LOCKED(map); | VM_MAP_ASSERT_LOCKED(map); | ||||
if (entry != map->root) | root = vm_map_entry_splay_split(entry->start, map->root, &llist, &rlist); | ||||
vm_map_entry_splay(entry->start, map->root); | KASSERT(root != NULL, | ||||
if (entry->left == NULL) | ("vm_map_entry_unlink: unlink object not mapped")); | ||||
root = entry->right; | /* | ||||
else { | * Walk the left and right spines to reach the predecessor and successor | ||||
root = vm_map_entry_splay(entry->start, entry->left); | * of the found node. | ||||
root->right = entry->right; | */ | ||||
root->adj_free = entry->next->start - root->end; | tree = root->left; | ||||
vm_map_entry_set_max_free(root); | while (tree != NULL) { | ||||
if ((y = tree->right) != NULL) { | |||||
/* Rotate left. */ | |||||
tree->right = y->left; | |||||
y->left = tree; | |||||
vm_map_entry_set_max_free(tree); | |||||
tree = y; | |||||
} | |||||
/* Put tree on llist. */ | |||||
y = tree->right; | |||||
tree->right = llist; | |||||
llist = tree; | |||||
tree = y; | |||||
} | } | ||||
map->root = root; | tree = root->right; | ||||
while (tree != NULL) { | |||||
prev = entry->prev; | if ((y = tree->left) != NULL) { | ||||
next = entry->next; | /* Rotate right. */ | ||||
next->prev = prev; | tree->left = y->right; | ||||
prev->next = next; | y->right = tree; | ||||
vm_map_entry_set_max_free(tree); | |||||
tree = y; | |||||
} | |||||
/* Put tree on rlist. */ | |||||
y = tree->left; | |||||
tree->left = rlist; | |||||
rlist = tree; | |||||
tree = y; | |||||
} | |||||
rlist->prev = llist; | |||||
llist->next = rlist; | |||||
llist->adj_free = rlist->start - llist->end; | |||||
/* Make the new root the predecessor of the found node. */ | |||||
map->root = vm_map_entry_splay_merge(llist, llist->right, rlist, | |||||
llist->left, NULL); | |||||
map->nentries--; | map->nentries--; | ||||
CTR3(KTR_VM, "vm_map_entry_unlink: map %p, nentries %d, entry %p", map, | CTR3(KTR_VM, "vm_map_entry_unlink: map %p, nentries %d, entry %p", map, | ||||
map->nentries, entry); | map->nentries, entry); | ||||
} | } | ||||
/* | /* | ||||
* vm_map_entry_resize_free: | * vm_map_entry_resize_free: | ||||
* | * | ||||
Show All 14 Lines | |||||
* actually contained in the map. | * actually contained in the map. | ||||
*/ | */ | ||||
boolean_t | boolean_t | ||||
vm_map_lookup_entry( | vm_map_lookup_entry( | ||||
vm_map_t map, | vm_map_t map, | ||||
vm_offset_t address, | vm_offset_t address, | ||||
vm_map_entry_t *entry) /* OUT */ | vm_map_entry_t *entry) /* OUT */ | ||||
{ | { | ||||
vm_map_entry_t cur; | vm_map_entry_t cur, lbound; | ||||
boolean_t locked; | boolean_t locked; | ||||
/* | |||||
* If the address is out of range, fail immediately. | |||||
*/ | |||||
if (address < vm_map_min(map)) { | |||||
*entry = &map->header; | |||||
return (FALSE); | |||||
} | |||||
if (address >= vm_map_max(map)) { | |||||
*entry = map->header.prev; | |||||
return (FALSE); | |||||
} | |||||
/* | /* | ||||
* If the map is empty, then the map entry immediately preceding | * If the map is empty, then the map entry immediately preceding | ||||
* "address" is the map's header. | * "address" is the map's header. | ||||
*/ | */ | ||||
cur = map->root; | cur = map->root; | ||||
if (cur == NULL) | if (address >= cur->start && cur->end > address) { | ||||
*entry = &map->header; | |||||
else if (address >= cur->start && cur->end > address) { | |||||
*entry = cur; | *entry = cur; | ||||
return (TRUE); | return (TRUE); | ||||
} else if ((locked = vm_map_locked(map)) || | } | ||||
sx_try_upgrade(&map->lock)) { | if ((locked = vm_map_locked(map)) || sx_try_upgrade(&map->lock)) { | ||||
/* | /* | ||||
* Splay requires a write lock on the map. However, it only | * Splay requires a write lock on the map. However, it only | ||||
* restructures the binary search tree; it does not otherwise | * restructures the binary search tree; it does not otherwise | ||||
* change the map. Thus, the map's timestamp need not change | * change the map. Thus, the map's timestamp need not change | ||||
* on a temporary upgrade. | * on a temporary upgrade. | ||||
*/ | */ | ||||
map->root = cur = vm_map_entry_splay(address, cur); | map->root = cur = vm_map_entry_splay(address, cur); | ||||
if (!locked) | if (!locked) | ||||
sx_downgrade(&map->lock); | sx_downgrade(&map->lock); | ||||
} else { | |||||
/* | |||||
* If "address" is contained within a map entry, the new root | |||||
* is that map entry. Otherwise, the new root is a map entry | |||||
* immediately before or after "address". | |||||
*/ | |||||
if (address >= cur->start) { | |||||
*entry = cur; | |||||
if (cur->end > address) | |||||
return (TRUE); | |||||
} else | |||||
*entry = cur->prev; | |||||
} else | |||||
/* | /* | ||||
* Since the map is only locked for read access, perform a | * Since the map is only locked for read access, perform a | ||||
* standard binary search tree lookup for "address". | * standard binary search tree lookup for "address". | ||||
*/ | */ | ||||
lbound = NULL; | |||||
for (;;) { | for (;;) { | ||||
if (address < cur->start) { | /* | ||||
if (cur->left == NULL) { | * Examine the start node of an entry before the end | ||||
*entry = cur->prev; | * node if and only if we arrive at the entry by | ||||
* following a right pointer. Assume we arrive at the | |||||
* root via a left pointer. | |||||
*/ | |||||
while (address >= cur->end) { | |||||
lbound = cur; | |||||
cur = cur->right; | |||||
if (cur == NULL || address < cur->start) | |||||
break; | break; | ||||
} | } | ||||
if (cur == NULL || address >= cur->start) | |||||
break; | |||||
while (address < cur->start) { | |||||
cur = cur->left; | cur = cur->left; | ||||
} else if (cur->end > address) { | if (cur == NULL || address >= cur->end) | ||||
*entry = cur; | |||||
return (TRUE); | |||||
} else { | |||||
if (cur->right == NULL) { | |||||
*entry = cur; | |||||
break; | break; | ||||
} | |||||
cur = cur->right; | |||||
} | } | ||||
if (cur == NULL || address < cur->end) | |||||
break; | |||||
} | } | ||||
return (FALSE); | if (cur == NULL) | ||||
cur = lbound; | |||||
} | |||||
*entry = cur; | |||||
return (cur->end > address); | |||||
} | } | ||||
/* | /* | ||||
* vm_map_insert: | * vm_map_insert: | ||||
* | * | ||||
* Inserts the given whole VM object into the target | * Inserts the given whole VM object into the target | ||||
* map at the specified address range. The object's | * map at the specified address range. The object's | ||||
* size should match that of the address range. | * size should match that of the address range. | ||||
Show All 14 Lines | |||||
KASSERT(cred == NULL || !ENTRY_CHARGED(new_entry), | KASSERT(cred == NULL || !ENTRY_CHARGED(new_entry), | ||||
("overcommit: vm_map_insert leaks vm_map %p", new_entry)); | ("overcommit: vm_map_insert leaks vm_map %p", new_entry)); | ||||
new_entry->cred = cred; | new_entry->cred = cred; | ||||
/* | /* | ||||
* Insert the new entry into the list | * Insert the new entry into the list | ||||
*/ | */ | ||||
vm_map_entry_link(map, prev_entry, new_entry); | vm_map_entry_link(map, new_entry); | ||||
if ((new_entry->eflags & MAP_ENTRY_GUARD) == 0) | if ((new_entry->eflags & MAP_ENTRY_GUARD) == 0) | ||||
map->size += new_entry->end - new_entry->start; | map->size += new_entry->end - new_entry->start; | ||||
/* | /* | ||||
* Try to coalesce the new entry with both the previous and next | * Try to coalesce the new entry with both the previous and next | ||||
* entries in the list. Previously, we only attempted to coalesce | * entries in the list. Previously, we only attempted to coalesce | ||||
* with the previous entry when object is NULL. Here, we handle the | * with the previous entry when object is NULL. Here, we handle the | ||||
* other cases, which are less common. | * other cases, which are less common. | ||||
Show All 14 Lines | |||||
/* | /* | ||||
* Request must fit within min/max VM address and must avoid | * Request must fit within min/max VM address and must avoid | ||||
* address wrap. | * address wrap. | ||||
*/ | */ | ||||
start = MAX(start, vm_map_min(map)); | start = MAX(start, vm_map_min(map)); | ||||
if (start + length > vm_map_max(map) || start + length < start) | if (start + length > vm_map_max(map) || start + length < start) | ||||
return (1); | return (1); | ||||
/* Empty tree means wide open address space. */ | |||||
if (map->root == NULL) { | |||||
*addr = start; | |||||
return (0); | |||||
} | |||||
/* | |||||
* After splay, if start comes before root node, then there | |||||
* must be a gap from start to the root. | |||||
*/ | |||||
map->root = vm_map_entry_splay(start, map->root); | |||||
if (start + length <= map->root->start) { | |||||
*addr = start; | |||||
return (0); | |||||
} | |||||
/* | /* | ||||
* Root is the last node that might begin its gap before | * Root is the last node that might begin its gap before | ||||
* start, and this is the last comparison where address | * start, and this is the last comparison where address | ||||
* wrap might be a problem. | * wrap might be a problem. | ||||
*/ | */ | ||||
map->root = vm_map_entry_splay(start, map->root); | |||||
st = (start > map->root->end) ? start : map->root->end; | st = (start > map->root->end) ? start : map->root->end; | ||||
if (length <= map->root->end + map->root->adj_free - st) { | if (length <= map->root->end + map->root->adj_free - st) { | ||||
*addr = st; | *addr = st; | ||||
return (0); | return (0); | ||||
} | } | ||||
/* With max_free, can immediately tell if no solution. */ | /* With max_free, can immediately tell if no solution. */ | ||||
entry = map->root->right; | entry = map->root->right; | ||||
if (entry == NULL || length > entry->max_free) | if (entry == NULL || length > entry->max_free) | ||||
return (1); | return (1); | ||||
/* | /* | ||||
* Search the right subtree in the order: left subtree, root, | * Search the right subtree in the order: left subtree, root, | ||||
* right subtree (first fit). The previous splay implies that | * right subtree (first fit). The previous splay implies that | ||||
* all regions in the right subtree have addresses > start. | * all regions in the right subtree have addresses > start. | ||||
kib: Change the return type to bool ? | |||||
Done Inline Actions!= NULL kib: != NULL | |||||
Done Inline ActionsBlank line is needed before start of multi-line comment. kib: Blank line is needed before start of multi-line comment. | |||||
Done Inline ActionsAlmost all () there and below are excessive, and no need in space before the excessive '(' at this line. kib: Almost all () there and below are excessive, and no need in space before the excessive '(' at… | |||||
Done Inline ActionsNo need in additional space for indent. kib: No need in additional space for indent. | |||||
Context not available. | |||||
entry->object.vm_object->cred = entry->cred; | entry->object.vm_object->cred = entry->cred; | ||||
entry->object.vm_object->charge = entry->end - entry->start; | entry->object.vm_object->charge = entry->end - entry->start; | ||||
VM_OBJECT_WUNLOCK(entry->object.vm_object); | VM_OBJECT_WUNLOCK(entry->object.vm_object); | ||||
entry->cred = NULL; | entry->cred = NULL; | ||||
} | } | ||||
new_entry = vm_map_entry_create(map); | new_entry = vm_map_entry_create(map); | ||||
*new_entry = *entry; | *new_entry = *entry; | ||||
new_entry->end = start; | new_entry->end = start; | ||||
entry->offset += (start - entry->start); | entry->offset += (start - entry->start); | ||||
entry->start = start; | entry->start = start; | ||||
if (new_entry->cred != NULL) | if (new_entry->cred != NULL) | ||||
crhold(entry->cred); | crhold(entry->cred); | ||||
vm_map_entry_link(map, entry->prev, new_entry); | vm_map_entry_link(map, new_entry); | ||||
if ((entry->eflags & MAP_ENTRY_IS_SUB_MAP) == 0) { | if ((entry->eflags & MAP_ENTRY_IS_SUB_MAP) == 0) { | ||||
vm_object_reference(new_entry->object.vm_object); | vm_object_reference(new_entry->object.vm_object); | ||||
/* | /* | ||||
* The object->un_pager.vnp.writemappings for the | * The object->un_pager.vnp.writemappings for the | ||||
* object of MAP_ENTRY_VN_WRITECNT type entry shall be | * object of MAP_ENTRY_VN_WRITECNT type entry shall be | ||||
* kept as is here. The virtual pages are | * kept as is here. The virtual pages are | ||||
* re-distributed among the clipped entries, so the sum is | * re-distributed among the clipped entries, so the sum is | ||||
Show All 14 Lines | |||||
new_entry = vm_map_entry_create(map); | new_entry = vm_map_entry_create(map); | ||||
*new_entry = *entry; | *new_entry = *entry; | ||||
new_entry->start = entry->end = end; | new_entry->start = entry->end = end; | ||||
new_entry->offset += (end - entry->start); | new_entry->offset += (end - entry->start); | ||||
if (new_entry->cred != NULL) | if (new_entry->cred != NULL) | ||||
crhold(entry->cred); | crhold(entry->cred); | ||||
vm_map_entry_link(map, entry, new_entry); | vm_map_entry_link(map, new_entry); | ||||
if ((entry->eflags & MAP_ENTRY_IS_SUB_MAP) == 0) { | if ((entry->eflags & MAP_ENTRY_IS_SUB_MAP) == 0) { | ||||
vm_object_reference(new_entry->object.vm_object); | vm_object_reference(new_entry->object.vm_object); | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* vm_map_submap: [ kernel use only ] | * vm_map_submap: [ kernel use only ] | ||||
Show All 14 Lines | |||||
vnode_pager_update_writecount(object, | vnode_pager_update_writecount(object, | ||||
new_entry->start, new_entry->end); | new_entry->start, new_entry->end); | ||||
} | } | ||||
/* | /* | ||||
* Insert the entry into the new map -- we know we're | * Insert the entry into the new map -- we know we're | ||||
* inserting at the end of the new map. | * inserting at the end of the new map. | ||||
*/ | */ | ||||
vm_map_entry_link(new_map, new_map->header.prev, | vm_map_entry_link(new_map, new_entry); | ||||
new_entry); | |||||
vmspace_map_entry_forked(vm1, vm2, new_entry); | vmspace_map_entry_forked(vm1, vm2, new_entry); | ||||
/* | /* | ||||
* Update the physical map | * Update the physical map | ||||
*/ | */ | ||||
pmap_copy(new_map->pmap, old_map->pmap, | pmap_copy(new_map->pmap, old_map->pmap, | ||||
new_entry->start, | new_entry->start, | ||||
(old_entry->end - old_entry->start), | (old_entry->end - old_entry->start), | ||||
Show All 10 Lines | |||||
* Copied entry is COW over the old object. | * Copied entry is COW over the old object. | ||||
*/ | */ | ||||
new_entry->eflags &= ~(MAP_ENTRY_USER_WIRED | | new_entry->eflags &= ~(MAP_ENTRY_USER_WIRED | | ||||
MAP_ENTRY_IN_TRANSITION | MAP_ENTRY_VN_WRITECNT); | MAP_ENTRY_IN_TRANSITION | MAP_ENTRY_VN_WRITECNT); | ||||
new_entry->wiring_thread = NULL; | new_entry->wiring_thread = NULL; | ||||
new_entry->wired_count = 0; | new_entry->wired_count = 0; | ||||
new_entry->object.vm_object = NULL; | new_entry->object.vm_object = NULL; | ||||
new_entry->cred = NULL; | new_entry->cred = NULL; | ||||
vm_map_entry_link(new_map, new_map->header.prev, | vm_map_entry_link(new_map, new_entry); | ||||
new_entry); | |||||
vmspace_map_entry_forked(vm1, vm2, new_entry); | vmspace_map_entry_forked(vm1, vm2, new_entry); | ||||
vm_map_copy_entry(old_map, new_map, old_entry, | vm_map_copy_entry(old_map, new_map, old_entry, | ||||
new_entry, fork_charge); | new_entry, fork_charge); | ||||
break; | break; | ||||
case VM_INHERIT_ZERO: | case VM_INHERIT_ZERO: | ||||
/* | /* | ||||
* Create a new anonymous mapping entry modelled from | * Create a new anonymous mapping entry modelled from | ||||
* the old one. | * the old one. | ||||
*/ | */ | ||||
new_entry = vm_map_entry_create(new_map); | new_entry = vm_map_entry_create(new_map); | ||||
memset(new_entry, 0, sizeof(*new_entry)); | memset(new_entry, 0, sizeof(*new_entry)); | ||||
new_entry->start = old_entry->start; | new_entry->start = old_entry->start; | ||||
new_entry->end = old_entry->end; | new_entry->end = old_entry->end; | ||||
new_entry->eflags = old_entry->eflags & | new_entry->eflags = old_entry->eflags & | ||||
~(MAP_ENTRY_USER_WIRED | MAP_ENTRY_IN_TRANSITION | | ~(MAP_ENTRY_USER_WIRED | MAP_ENTRY_IN_TRANSITION | | ||||
MAP_ENTRY_VN_WRITECNT); | MAP_ENTRY_VN_WRITECNT); | ||||
new_entry->protection = old_entry->protection; | new_entry->protection = old_entry->protection; | ||||
new_entry->max_protection = old_entry->max_protection; | new_entry->max_protection = old_entry->max_protection; | ||||
new_entry->inheritance = VM_INHERIT_ZERO; | new_entry->inheritance = VM_INHERIT_ZERO; | ||||
vm_map_entry_link(new_map, new_map->header.prev, | vm_map_entry_link(new_map, new_entry); | ||||
new_entry); | |||||
vmspace_map_entry_forked(vm1, vm2, new_entry); | vmspace_map_entry_forked(vm1, vm2, new_entry); | ||||
new_entry->cred = curthread->td_ucred; | new_entry->cred = curthread->td_ucred; | ||||
crhold(new_entry->cred); | crhold(new_entry->cred); | ||||
*fork_charge += (new_entry->end - new_entry->start); | *fork_charge += (new_entry->end - new_entry->start); | ||||
break; | break; | ||||
} | } | ||||
old_entry = old_entry->next; | old_entry = old_entry->next; | ||||
} | } | ||||
/* | /* | ||||
* Use inlined vm_map_unlock() to postpone handling the deferred | * Use inlined vm_map_unlock() to postpone handling the deferred | ||||
* map entries, which cannot be done until both old_map and | * map entries, which cannot be done until both old_map and | ||||
* new_map locks are released. | * new_map locks are released. | ||||
*/ | */ | ||||
Context not available. |
Change the return type to bool ?