[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
- [RFC PATCH 0/7] Forward merging entries and other VM shenanigans, Sergey Bugaev, 2023/06/26
- [RFC PATCH 2/7] vm: Allow coalescing a VM object with itself, Sergey Bugaev, 2023/06/26
- [RFC PATCH 1/7] Shrink struct vm_page size, Sergey Bugaev, 2023/06/26
- [RFC PATCH 4/7] vm: Allow coalescing entries forward, Sergey Bugaev, 2023/06/26
- [RFC PATCH 3/7] vm: Allow coalescing null object with an internal object, Sergey Bugaev, 2023/06/26
- [RFC PATCH 7/7] vm: Coalesce map entries, Sergey Bugaev, 2023/06/26
- [RFC PATCH 6/7] vm: Add vm_map_coalesce_entry, Sergey Bugaev, 2023/06/26
- [RFC PATCH 5/7] vm: Eagerly release deallocated pages,
Sergey Bugaev <=