vm: object: implement transferring pages between objects
This commit is contained in:
@@ -85,6 +85,13 @@ extern kern_status_t vm_object_copy(
|
||||
off_t src_offset,
|
||||
size_t count,
|
||||
size_t *nr_copied);
|
||||
extern kern_status_t vm_object_transfer(
|
||||
struct vm_object *dst,
|
||||
off_t dst_offset,
|
||||
struct vm_object *src,
|
||||
off_t src_offset,
|
||||
size_t count,
|
||||
size_t *nr_moved);
|
||||
|
||||
DEFINE_OBJECT_LOCK_FUNCTION(vm_object, vo_base)
|
||||
|
||||
|
||||
@@ -780,3 +780,50 @@ kern_status_t vm_object_copy(
|
||||
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
kern_status_t vm_object_transfer(
|
||||
struct vm_object *dst,
|
||||
off_t dst_offset,
|
||||
struct vm_object *src,
|
||||
off_t src_offset,
|
||||
size_t count,
|
||||
size_t *nr_moved)
|
||||
{
|
||||
dst_offset &= ~VM_PAGE_MASK;
|
||||
src_offset &= ~VM_PAGE_MASK;
|
||||
|
||||
if (count & VM_PAGE_MASK) {
|
||||
count &= ~VM_PAGE_MASK;
|
||||
count += VM_PAGE_SIZE;
|
||||
}
|
||||
|
||||
size_t moved = 0;
|
||||
for (size_t i = 0; i < count; i += VM_PAGE_SIZE) {
|
||||
struct vm_page *src_pg
|
||||
= vm_object_get_page(src, src_offset + i);
|
||||
if (!src_pg) {
|
||||
continue;
|
||||
}
|
||||
|
||||
btree_delete(&src->vo_pages, &src_pg->p_bnode);
|
||||
|
||||
struct vm_page *dst_pg
|
||||
= vm_object_get_page(src, dst_offset + i);
|
||||
if (dst_pg) {
|
||||
vm_page_free(src_pg);
|
||||
continue;
|
||||
}
|
||||
|
||||
put_page(dst, src_pg, dst_offset + i);
|
||||
moved += VM_PAGE_SIZE;
|
||||
}
|
||||
|
||||
/* TODO evict all page table entries that reference the transferred
|
||||
* pages in `src` */
|
||||
|
||||
if (nr_moved) {
|
||||
*nr_moved = moved;
|
||||
}
|
||||
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user