vm: implement lazy-attach cow-duplication of vm-objects attached to a controller
This commit is contained in:
+38
-5
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user