vm: controller: add an auto-detach flag for vm-objects

This commit is contained in:
2026-03-24 20:24:12 +00:00
parent 4daffa804c
commit a0a6a061a4
3 changed files with 36 additions and 8 deletions

View File

@@ -14,19 +14,25 @@ enum vm_object_flags {
VMO_IN_PLACE = 0x01u,
/* this vm-object is/was attached to a vm-controller */
VMO_CONTROLLER = 0x02u,
/* when a vm-object is attached to a controller, and the ref-count of
* the object falls to one (i.e. the last reference is the handle to
* the object held by the server that created it), the object will
* be detached, allowing the server to close the last handle to the
* object and dispose of it. */
VMO_AUTO_DETACH = 0x04u,
/* these flags are for use with vm_object_get_page */
/**************************************************/
/* if the relevant page hasn't been allocated yet, it will be allocated
* and returned. if this flag isn't specified, NULL will be returned. */
VMO_ALLOCATE_MISSING_PAGE = 0x04u,
VMO_ALLOCATE_MISSING_PAGE = 0x08u,
/* if the vm-object is attached to a vm-controller, and the relevant
* page is uncommitted, send a request to the vm-controller to provide
* the missing page. will result in the vm-object being unlocked and
* the current thread sleeping until the request is fulfilled. the
* vm-object will be re-locked before the function returns. */
VMO_REQUEST_MISSING_PAGE = 0x08u,
VMO_REQUEST_MISSING_PAGE = 0x10u,
};
struct vm_object {

View File

@@ -7,6 +7,7 @@
#include <kernel/sched.h>
#include <kernel/task.h>
#include <kernel/util.h>
#include <kernel/vm-controller.h>
#include <kernel/vm-object.h>
#include <mango/status.h>
@@ -721,6 +722,9 @@ kern_status_t address_space_map(
}
tracek("address_space_map(%zx, %zx)", map_address, length);
if (map_address == 0xc6a55000) {
printk("break");
}
if (!root || !object) {
tracek("null pointer");
@@ -838,7 +842,7 @@ static kern_status_t split_area(
put_entry(&root->s_mappings, right);
for (size_t i = unmap_base; i < unmap_limit; i += VM_PAGE_SIZE) {
tracek("unmapping %zx", i);
tracek("pmap_remove %zx", i);
pmap_remove(root->s_pmap, i);
}
@@ -875,7 +879,7 @@ static kern_status_t left_reduce_area(
return KERN_OK;
}
tracek(" unmapping %zx-%zx (%zx bytes)", base, base + length, length);
tracek(" pmap_remove %zx-%zx (%zx bytes)", base, base + length, length);
for (size_t i = base; i < limit; i += VM_PAGE_SIZE) {
pmap_remove(root->s_pmap, i);
}
@@ -912,7 +916,7 @@ static kern_status_t right_reduce_area(
return KERN_OK;
}
tracek(" unmapping %zx-%zx (%zx bytes)", base, base + length, length);
tracek(" pmap_remove %zx-%zx (%zx bytes)", base, base + length, length);
for (size_t i = base; i < limit; i += VM_PAGE_SIZE) {
pmap_remove(root->s_pmap, i);
}
@@ -930,9 +934,10 @@ static kern_status_t delete_area(
return KERN_OK;
}
tracek("delete mapping [%zx-%zx]",
tracek("delete mapping [%zx-%zx] (%zx bytes)",
mapping->vma_base,
mapping->vma_limit);
mapping->vma_limit,
mapping->vma_limit - mapping->vma_base);
for (size_t i = mapping->vma_base; i < mapping->vma_limit;
i += VM_PAGE_SIZE) {
@@ -946,7 +951,23 @@ static kern_status_t delete_area(
&mapping->vma_object->vo_mappings,
&mapping->vma_object_entry);
mapping->vma_object = NULL;
/* if the object is attached to a controller and the ref-count is 2,
* then the only other remaining reference to this object is held by
* the controller. */
struct vm_controller *ctrl = object->vo_ctrl;
bool detach = ctrl != NULL && object->vo_base.ob_refcount == 2
&& (object->vo_flags & VMO_AUTO_DETACH);
vm_object_unlock_irqrestore(object, flags);
if (detach) {
/* TODO find a better way to achieve this, and/or give the
* server that created the object more control over when it
* should be detached */
vm_controller_lock_irqsave(ctrl, &flags);
vm_controller_detach_object(ctrl, object);
vm_controller_unlock_irqrestore(ctrl, flags);
}
object_unref(&object->vo_base);
/* don't actually delete the mapping yet. that will be done by

View File

@@ -198,7 +198,8 @@ kern_status_t vm_controller_create_object(
object_ref(&ctrl->vc_base);
vmo->vo_flags |= VMO_CONTROLLER;
/* TODO expose the VMO_AUTO_DETACH flag to userspace */
vmo->vo_flags |= VMO_CONTROLLER | VMO_AUTO_DETACH;
vmo->vo_ctrl = ctrl;
vmo->vo_key = key;