* vm_map_entry_{un,}link: * * Insert/remove entries from maps. On linking, if new entry clips * existing entry, trim existing entry to avoid overlap, and manage * offsets. On unlinking, merge disappearing entry with neighbor, if * called for, and manage offsets. Callers should not modify fields in * entries already mapped. */
| 1415 | * entries already mapped. |
| 1416 | */ |
| 1417 | static void |
| 1418 | vm_map_entry_link(vm_map_t map, vm_map_entry_t entry) |
| 1419 | { |
| 1420 | vm_map_entry_t header, llist, rlist, root; |
| 1421 | vm_size_t max_free_left, max_free_right; |
| 1422 | |
| 1423 | CTR3(KTR_VM, |
| 1424 | "vm_map_entry_link: map %p, nentries %d, entry %p", map, |
| 1425 | map->nentries, entry); |
| 1426 | VM_MAP_ASSERT_LOCKED(map); |
| 1427 | map->nentries++; |
| 1428 | header = &map->header; |
| 1429 | root = vm_map_splay_split(map, entry->start, 0, &llist, &rlist); |
| 1430 | if (root == NULL) { |
| 1431 | /* |
| 1432 | * The new entry does not overlap any existing entry in the |
| 1433 | * map, so it becomes the new root of the map tree. |
| 1434 | */ |
| 1435 | max_free_left = vm_map_splay_merge_pred(header, entry, llist); |
| 1436 | max_free_right = vm_map_splay_merge_succ(header, entry, rlist); |
| 1437 | } else if (entry->start == root->start) { |
| 1438 | /* |
| 1439 | * The new entry is a clone of root, with only the end field |
| 1440 | * changed. The root entry will be shrunk to abut the new |
| 1441 | * entry, and will be the right child of the new root entry in |
| 1442 | * the modified map. |
| 1443 | */ |
| 1444 | KASSERT(entry->end < root->end, |
| 1445 | ("%s: clip_start not within entry", __func__)); |
| 1446 | vm_map_splay_findprev(root, &llist); |
| 1447 | root->offset += entry->end - root->start; |
| 1448 | root->start = entry->end; |
| 1449 | max_free_left = vm_map_splay_merge_pred(header, entry, llist); |
| 1450 | max_free_right = root->max_free = vm_size_max( |
| 1451 | vm_map_splay_merge_pred(entry, root, entry), |
| 1452 | vm_map_splay_merge_right(header, root, rlist)); |
| 1453 | } else { |
| 1454 | /* |
| 1455 | * The new entry is a clone of root, with only the start field |
| 1456 | * changed. The root entry will be shrunk to abut the new |
| 1457 | * entry, and will be the left child of the new root entry in |
| 1458 | * the modified map. |
| 1459 | */ |
| 1460 | KASSERT(entry->end == root->end, |
| 1461 | ("%s: clip_start not within entry", __func__)); |
| 1462 | vm_map_splay_findnext(root, &rlist); |
| 1463 | entry->offset += entry->start - root->start; |
| 1464 | root->end = entry->start; |
| 1465 | max_free_left = root->max_free = vm_size_max( |
| 1466 | vm_map_splay_merge_left(header, root, llist), |
| 1467 | vm_map_splay_merge_succ(entry, root, entry)); |
| 1468 | max_free_right = vm_map_splay_merge_succ(header, entry, rlist); |
| 1469 | } |
| 1470 | entry->max_free = vm_size_max(max_free_left, max_free_right); |
| 1471 | map->root = entry; |
| 1472 | VM_MAP_ASSERT_CONSISTENT(map); |
| 1473 | } |
| 1474 |
no test coverage detected