bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC PATCH 5/7] vm: Eagerly release deallocated pages


From: Sergey Bugaev
Subject: [RFC PATCH 5/7] vm: Eagerly release deallocated pages
Date: Mon, 26 Jun 2023 14:26:54 +0300

If a deallocated VM map entry refers to an object that only has a single
reference and doesn't have a pager port, we can eagerly release any
physical pages that were contained in the deallocated range.

This is not a 100% solution: it is still possible to "leak" physical
pages that can never appear in virtual memory again by creating several
references to a memory object (perhaps by forking a VM map with
VM_INHERIT_SHARE) and deallocating the pages from all the maps referring
to the object. That being said, it should help to release the pages in
the common case sooner.
---

This is also probably fine to do if object->temporary, but let's stick
with !object->pager_created as a more conservative check.

 vm/vm_map.c | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/vm/vm_map.c b/vm/vm_map.c
index 0d3b11f2..97fc09ce 100644
--- a/vm/vm_map.c
+++ b/vm/vm_map.c
@@ -1902,11 +1902,13 @@ void vm_map_entry_delete(
        vm_map_entry_t  entry)
 {
        vm_offset_t             s, e;
+       vm_size_t               size;
        vm_object_t             object;
        extern vm_object_t      kernel_object;
 
        s = entry->vme_start;
        e = entry->vme_end;
+       size = e - s;
 
        /*Check if projected buffer*/
        if (map != kernel_map && entry->projected_on != 0) {
@@ -1945,15 +1947,29 @@ void vm_map_entry_delete(
            if (object == kernel_object) {
                vm_object_lock(object);
                vm_object_page_remove(object, entry->offset,
-                               entry->offset + (e - s));
+                               entry->offset + size);
                vm_object_unlock(object);
            } else if (entry->is_shared) {
                vm_object_pmap_remove(object,
                                 entry->offset,
-                                entry->offset + (e - s));
-           }
-           else {
+                                entry->offset + size);
+           } else {
                pmap_remove(map->pmap, s, e);
+               /*
+                *      If this object has no pager and our
+                *      reference to the object is the only
+                *      one, we can release the deleted pages
+                *      now.
+                */
+               vm_object_lock(object);
+               if ((!object->pager_created) &&
+                   (object->ref_count == 1) &&
+                   (object->paging_in_progress == 0)) {
+                       vm_object_page_remove(object,
+                               entry->offset,
+                               entry->offset + size);
+               }
+               vm_object_unlock(object);
            }
         }
 
@@ -1968,7 +1984,7 @@ void vm_map_entry_delete(
                vm_object_deallocate(entry->object.vm_object);
 
        vm_map_entry_unlink(map, entry);
-       map->size -= e - s;
+       map->size -= size;
 
        vm_map_entry_dispose(map, entry);
 }
-- 
2.41.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]