vm: implement lazy-attach cow-duplication of vm-objects attached to a controller

This commit is contained in:
2026-04-19 20:16:19 +01:00
parent b3be4c541b
commit 4a9e907a75
9 changed files with 332 additions and 72 deletions
+38 -5
View File
@@ -288,8 +288,10 @@ struct vm_object *vm_object_duplicate_cow(struct vm_object *vmo)
struct vm_object *out = VM_OBJECT_CAST(obj);
memcpy(out->vo_name, vmo->vo_name, sizeof out->vo_name);
out->vo_flags = vmo->vo_flags;
out->vo_flags = vmo->vo_flags | VMO_LAZY_ATTACH;
out->vo_ctrl = vmo->vo_ctrl;
out->vo_key = 0;
out->vo_src_key = vmo->vo_key;
out->vo_prot = vmo->vo_prot;
out->vo_size = vmo->vo_size;
memcpy(out->vo_name, vmo->vo_name, sizeof vmo->vo_name);
@@ -315,6 +317,37 @@ struct vm_object *vm_object_duplicate_cow(struct vm_object *vmo)
return out;
}
kern_status_t vm_object_attach_cow(
struct vm_object *vmo,
unsigned long *irq_flags)
{
struct vm_controller *ctrl = vmo->vo_ctrl;
struct vm_request req = {0};
req.req_status = VM_REQUEST_PENDING;
req.req_type = VM_REQUEST_ATTACH;
req.req_length = vm_page_order_to_bytes(VM_PAGE_4K);
req.req_sender = get_current_thread();
object_ref(&vmo->vo_base);
req.req_object = vmo;
vm_object_unlock_irqrestore(vmo, *irq_flags);
vm_controller_lock_irqsave(ctrl, irq_flags);
spin_lock(&req.req_lock);
kern_status_t status
= vm_controller_send_request(ctrl, &req, irq_flags);
put_current_thread(req.req_sender);
spin_unlock(&req.req_lock);
vm_controller_unlock_irqrestore(ctrl, *irq_flags);
object_unref(&vmo->vo_base);
vm_object_lock_irqsave(vmo, irq_flags);
return status;
}
static struct vm_page *alloc_page(struct vm_object *vo, off_t offset)
{
struct vm_page *page = NULL;
@@ -458,15 +491,15 @@ static kern_status_t request_page(
unsigned long *irq_flags)
{
struct vm_controller *ctrl = vo->vo_ctrl;
struct page_request req = {0};
req.req_status = PAGE_REQUEST_PENDING;
req.req_type = PAGE_REQUEST_READ;
struct vm_request req = {0};
req.req_status = VM_REQUEST_PENDING;
req.req_type = VM_REQUEST_READ;
req.req_offset = offset;
req.req_length = vm_page_order_to_bytes(VM_PAGE_4K);
req.req_sender = get_current_thread();
object_ref(&vo->vo_base);
req.req_object = vo->vo_key;
req.req_object = vo;
vm_object_unlock_irqrestore(vo, *irq_flags);
vm_controller_lock_irqsave(ctrl, irq_flags);