diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index 6790a6ed02e8..f0fb75b52d6e 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -2177,95 +2177,6 @@ vm_map_check_protection(vm_map_t map, vm_offset_t start, vm_offset_t end, return (TRUE); } -/* - * 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. - */ -static void -vm_map_split(vm_map_entry_t entry) -{ - vm_page_t m; - vm_object_t orig_object, new_object, source; - vm_offset_t s, e; - vm_pindex_t offidxstart, offidxend, idx; - vm_size_t size; - vm_ooffset_t offset; - - GIANT_REQUIRED; - - orig_object = entry->object.vm_object; - if (orig_object->type != OBJT_DEFAULT && orig_object->type != OBJT_SWAP) - return; - if (orig_object->ref_count <= 1) - return; - - offset = entry->offset; - s = entry->start; - e = entry->end; - - offidxstart = OFF_TO_IDX(offset); - offidxend = offidxstart + OFF_TO_IDX(e - s); - size = offidxend - offidxstart; - - new_object = vm_pager_allocate(orig_object->type, - NULL, IDX_TO_OFF(size), VM_PROT_ALL, 0LL); - if (new_object == NULL) - return; - - source = orig_object->backing_object; - if (source != NULL) { - vm_object_reference(source); /* Referenced by new_object */ - TAILQ_INSERT_TAIL(&source->shadow_head, - new_object, shadow_list); - vm_object_clear_flag(source, OBJ_ONEMAPPING); - new_object->backing_object_offset = - orig_object->backing_object_offset + IDX_TO_OFF(offidxstart); - new_object->backing_object = source; - source->shadow_count++; - source->generation++; - } - for (idx = 0; idx < size; idx++) { - retry: - m = vm_page_lookup(orig_object, offidxstart + idx); - if (m == NULL) - continue; - - /* - * We must wait for pending I/O to complete before we can - * rename the page. - * - * We do not have to VM_PROT_NONE the page as mappings should - * not be changed by this operation. - */ - if (vm_page_sleep_busy(m, TRUE, "spltwt")) - goto retry; - - vm_page_busy(m); - vm_page_rename(m, new_object, idx); - /* page automatically made dirty by rename and cache handled */ - vm_page_busy(m); - } - if (orig_object->type == OBJT_SWAP) { - vm_object_pip_add(orig_object, 1); - /* - * copy orig_object pages into new_object - * and destroy unneeded pages in - * shadow object. - */ - swap_pager_copy(orig_object, new_object, offidxstart, 0); - vm_object_pip_wakeup(orig_object); - } - for (idx = 0; idx < size; idx++) { - m = vm_page_lookup(new_object, idx); - if (m != NULL) - vm_page_wakeup(m); - } - entry->object.vm_object = new_object; - entry->offset = 0LL; - vm_object_deallocate(orig_object); -} - /* * vm_map_copy_entry: * @@ -2307,7 +2218,7 @@ vm_map_copy_entry( src_object->type == OBJT_SWAP)) { vm_object_collapse(src_object); if ((src_object->flags & (OBJ_NOSPLIT|OBJ_ONEMAPPING)) == OBJ_ONEMAPPING) { - vm_map_split(src_entry); + vm_object_split(src_entry); src_object = src_entry->object.vm_object; } } diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index 2760eba72350..d04694153fba 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -1180,6 +1180,97 @@ vm_object_shadow( mtx_unlock(&Giant); } +/* + * 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. + */ +void +vm_object_split(vm_map_entry_t entry) +{ + vm_page_t m; + vm_object_t orig_object, new_object, source; + vm_offset_t s, e; + vm_pindex_t offidxstart, offidxend, idx; + vm_size_t size; + vm_ooffset_t offset; + + GIANT_REQUIRED; + + orig_object = entry->object.vm_object; + if (orig_object->type != OBJT_DEFAULT && orig_object->type != OBJT_SWAP) + return; + if (orig_object->ref_count <= 1) + return; + + offset = entry->offset; + s = entry->start; + e = entry->end; + + offidxstart = OFF_TO_IDX(offset); + offidxend = offidxstart + OFF_TO_IDX(e - s); + size = offidxend - offidxstart; + + new_object = vm_pager_allocate(orig_object->type, + NULL, IDX_TO_OFF(size), VM_PROT_ALL, 0LL); + if (new_object == NULL) + return; + + source = orig_object->backing_object; + if (source != NULL) { + vm_object_reference(source); /* Referenced by new_object */ + TAILQ_INSERT_TAIL(&source->shadow_head, + new_object, shadow_list); + vm_object_clear_flag(source, OBJ_ONEMAPPING); + new_object->backing_object_offset = + orig_object->backing_object_offset + IDX_TO_OFF(offidxstart); + new_object->backing_object = source; + source->shadow_count++; + source->generation++; + } + for (idx = 0; idx < size; idx++) { + retry: + m = vm_page_lookup(orig_object, offidxstart + idx); + if (m == NULL) + continue; + + /* + * We must wait for pending I/O to complete before we can + * rename the page. + * + * We do not have to VM_PROT_NONE the page as mappings should + * not be changed by this operation. + */ + if (vm_page_sleep_busy(m, TRUE, "spltwt")) + goto retry; + + vm_page_busy(m); + vm_page_rename(m, new_object, idx); + /* page automatically made dirty by rename and cache handled */ + vm_page_busy(m); + } + if (orig_object->type == OBJT_SWAP) { + vm_object_pip_add(orig_object, 1); + /* + * copy orig_object pages into new_object + * and destroy unneeded pages in + * shadow object. + */ + swap_pager_copy(orig_object, new_object, offidxstart, 0); + vm_object_pip_wakeup(orig_object); + } + for (idx = 0; idx < size; idx++) { + m = vm_page_lookup(new_object, idx); + if (m != NULL) + vm_page_wakeup(m); + } + entry->object.vm_object = new_object; + entry->offset = 0LL; + vm_object_deallocate(orig_object); +} + #define OBSC_TEST_ALL_SHADOWED 0x0001 #define OBSC_COLLAPSE_NOWAIT 0x0002 #define OBSC_COLLAPSE_WAIT 0x0004 diff --git a/sys/vm/vm_object.h b/sys/vm/vm_object.h index 707af0c94b3d..53db3191ae5c 100644 --- a/sys/vm/vm_object.h +++ b/sys/vm/vm_object.h @@ -198,6 +198,7 @@ void vm_object_pmap_copy_1 (vm_object_t, vm_pindex_t, vm_pindex_t); void vm_object_pmap_remove (vm_object_t, vm_pindex_t, vm_pindex_t); void vm_object_reference (vm_object_t); void vm_object_shadow (vm_object_t *, vm_ooffset_t *, vm_size_t); +void vm_object_split(vm_map_entry_t); void vm_object_madvise (vm_object_t, vm_pindex_t, int, int); void vm_object_init2 (void); #endif /* _KERNEL */