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,
|
off_t src_offset,
|
||||||
size_t count,
|
size_t count,
|
||||||
size_t *nr_copied);
|
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)
|
DEFINE_OBJECT_LOCK_FUNCTION(vm_object, vo_base)
|
||||||
|
|
||||||
|
|||||||
@@ -780,3 +780,50 @@ kern_status_t vm_object_copy(
|
|||||||
|
|
||||||
return KERN_OK;
|
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