* vm_object_split: * * Split the pages in a map entry into a new object. This affords * easier removal of unused pages, and keeps object inheritance from * being a negative impact on memory usage. */
| 1495 | * being a negative impact on memory usage. |
| 1496 | */ |
| 1497 | void |
| 1498 | vm_object_split(vm_map_entry_t entry) |
| 1499 | { |
| 1500 | vm_page_t m, m_busy, m_next; |
| 1501 | vm_object_t orig_object, new_object, backing_object; |
| 1502 | vm_pindex_t idx, offidxstart; |
| 1503 | vm_size_t size; |
| 1504 | |
| 1505 | orig_object = entry->object.vm_object; |
| 1506 | KASSERT((orig_object->flags & OBJ_ONEMAPPING) != 0, |
| 1507 | ("vm_object_split: Splitting object with multiple mappings.")); |
| 1508 | if ((orig_object->flags & OBJ_ANON) == 0) |
| 1509 | return; |
| 1510 | if (orig_object->ref_count <= 1) |
| 1511 | return; |
| 1512 | VM_OBJECT_WUNLOCK(orig_object); |
| 1513 | |
| 1514 | offidxstart = OFF_TO_IDX(entry->offset); |
| 1515 | size = atop(entry->end - entry->start); |
| 1516 | |
| 1517 | /* |
| 1518 | * If swap_pager_copy() is later called, it will convert new_object |
| 1519 | * into a swap object. |
| 1520 | */ |
| 1521 | new_object = vm_object_allocate_anon(size, orig_object, |
| 1522 | orig_object->cred, ptoa(size)); |
| 1523 | |
| 1524 | /* |
| 1525 | * We must wait for the orig_object to complete any in-progress |
| 1526 | * collapse so that the swap blocks are stable below. The |
| 1527 | * additional reference on backing_object by new object will |
| 1528 | * prevent further collapse operations until split completes. |
| 1529 | */ |
| 1530 | VM_OBJECT_WLOCK(orig_object); |
| 1531 | vm_object_collapse_wait(orig_object); |
| 1532 | |
| 1533 | /* |
| 1534 | * At this point, the new object is still private, so the order in |
| 1535 | * which the original and new objects are locked does not matter. |
| 1536 | */ |
| 1537 | VM_OBJECT_WLOCK(new_object); |
| 1538 | new_object->domain = orig_object->domain; |
| 1539 | backing_object = orig_object->backing_object; |
| 1540 | if (backing_object != NULL) { |
| 1541 | vm_object_backing_insert_ref(new_object, backing_object); |
| 1542 | new_object->backing_object_offset = |
| 1543 | orig_object->backing_object_offset + entry->offset; |
| 1544 | } |
| 1545 | if (orig_object->cred != NULL) { |
| 1546 | crhold(orig_object->cred); |
| 1547 | KASSERT(orig_object->charge >= ptoa(size), |
| 1548 | ("orig_object->charge < 0")); |
| 1549 | orig_object->charge -= ptoa(size); |
| 1550 | } |
| 1551 | |
| 1552 | /* |
| 1553 | * Mark the split operation so that swap_pager_getpages() knows |
| 1554 | * that the object is in transition. |
no test coverage detected