From 79dee7a08b62c63cfeb1ff96403e7152a3aa840a Mon Sep 17 00:00:00 2001 From: NetBSD User Date: Sat, 24 Jun 2023 19:47:15 +0100 Subject: [PATCH] VM: Free objpages properly. --- kernel/vm/cleaner.c | 12 +++++++++++- kernel/vm/obj.c | 21 +++++++++++++++------ kernel/vm/vm_internal.h | 3 +++ 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/kernel/vm/cleaner.c b/kernel/vm/cleaner.c index 4e19aed..a1f4050 100644 --- a/kernel/vm/cleaner.c +++ b/kernel/vm/cleaner.c @@ -6,7 +6,7 @@ #include "kdk/amd64/vmamd64.h" #include "kdk/devmgr.h" #include "kdk/kernel.h" -#include "kdk/objhdr.h" +#include "kdk/kmem.h" #include "kdk/process.h" #include "kdk/vfs.h" #include "kdk/vm.h" @@ -226,3 +226,13 @@ vmp_objpage_dirty(vm_object_t *obj, struct vmp_objpage *opage) out: vmp_release_pfn_lock(ipl); } + +void +vmp_objpage_free(vm_map_t *map, struct vmp_objpage *opage) +{ + vmp_page_free(map, opage->page); + opage->page = NULL; + kassert(opage->stat == kVMPObjPageClean); + TAILQ_REMOVE(&dirty_queue, opage, dirtyqueue_entry); + kmem_free(opage, sizeof(*opage)); +} diff --git a/kernel/vm/obj.c b/kernel/vm/obj.c index 14f7ea9..7ec7635 100644 --- a/kernel/vm/obj.c +++ b/kernel/vm/obj.c @@ -30,17 +30,26 @@ vm_object_new_vnode(vm_object_t **out, struct vnode *vnode) int vm_object_free(vm_map_t *map, vm_object_t *obj) { - /* here, we know the object can't be mapped anywhere anymore */ + /* + * Acquire the object lock to prevent any unexpected pageouts. (todo!) + */ if (obj->is_anonymous) vmp_amap_free(map, &obj->amap); else { - struct vmp_objpage *objpage; - RB_FOREACH(objpage, vmp_objpage_rbtree ,&obj->page_rbtree ) { - /* todo(HIGH): !!! Come back to this ; queues? */ - vmp_page_free(map, objpage->page); - objpage->page = NULL; + struct vmp_objpage *opage, *tmp; + + /* + * Dirty object pages keep a reference to objects - if we are + * here, there cannot be any. + */ + + RB_FOREACH_SAFE (opage, vmp_objpage_rbtree, &obj->page_rbtree, + tmp) { + RB_REMOVE(vmp_objpage_rbtree, &obj->page_rbtree, opage); + vmp_objpage_free(map, opage); } + kmem_free(obj, sizeof(*obj)); } return 0; diff --git a/kernel/vm/vm_internal.h b/kernel/vm/vm_internal.h index 41ea1a5..781997a 100644 --- a/kernel/vm/vm_internal.h +++ b/kernel/vm/vm_internal.h @@ -147,6 +147,9 @@ void vmp_objpage_created(struct vmp_objpage *opage); /*! @brief Inform the cleaner an object page is potentially dirty. */ void vmp_objpage_dirty(vm_object_t *obj, struct vmp_objpage *opage); +/*! @brief Free an object page. Must be clean & object must be LOCKED. */ +void vmp_objpage_free(vm_map_t *map, struct vmp_objpage *opage); + /*! @brief Initialise an amap. */ int vmp_amap_init(vm_map_t *map, struct vm_amap *amap);