From 2c850ee81a4b41d844dad384f73c7c6bad609319 Mon Sep 17 00:00:00 2001 From: mpi Date: Sat, 23 Oct 2021 14:42:07 +0000 Subject: [PATCH] Sprinkle uvm_obj_destroy() over UVM object recycling code. For now, only assert that the tree of pages is empty in uvm_obj_destroy(). This will soon be used to free the per-UVM object lock. While here call uvm_obj_init() when new vnodes are allocated instead of in uvn_attach(). Because vnodes and there associated UVM object are currently never freed, it isn't easy to know where/when to garbage collect the associated lock. So simply check that the reference of a given object is 0 when uvn_attach(). Tested by many as part of a bigger diff. ok kettenis@ --- sys/kern/vfs_subr.c | 3 ++- sys/uvm/uvm_aobj.c | 3 ++- sys/uvm/uvm_device.c | 7 +++++-- sys/uvm/uvm_object.c | 6 +++++- sys/uvm/uvm_vnode.c | 5 +++-- 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index af78c42526e..88e00128892 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfs_subr.c,v 1.310 2021/10/23 14:08:46 mpi Exp $ */ +/* $OpenBSD: vfs_subr.c,v 1.311 2021/10/23 14:42:07 mpi Exp $ */ /* $NetBSD: vfs_subr.c,v 1.53 1996/04/22 01:39:13 christos Exp $ */ /* @@ -410,6 +410,7 @@ getnewvnode(enum vtagtype tag, struct mount *mp, const struct vops *vops, vp = pool_get(&vnode_pool, PR_WAITOK | PR_ZERO); vp->v_uvm = pool_get(&uvm_vnode_pool, PR_WAITOK | PR_ZERO); vp->v_uvm->u_vnode = vp; + uvm_obj_init(&vp->v_uvm->u_obj, &uvm_vnodeops, 0); RBT_INIT(buf_rb_bufs, &vp->v_bufs_tree); cache_tree_init(&vp->v_nc_tree); TAILQ_INIT(&vp->v_cache_dst); diff --git a/sys/uvm/uvm_aobj.c b/sys/uvm/uvm_aobj.c index 94649a9828e..70a848d0d75 100644 --- a/sys/uvm/uvm_aobj.c +++ b/sys/uvm/uvm_aobj.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_aobj.c,v 1.99 2021/06/28 11:19:01 mpi Exp $ */ +/* $OpenBSD: uvm_aobj.c,v 1.100 2021/10/23 14:42:07 mpi Exp $ */ /* $NetBSD: uvm_aobj.c,v 1.39 2001/02/18 21:19:08 chs Exp $ */ /* @@ -372,6 +372,7 @@ uao_free(struct uvm_aobj *aobj) /* * finally free the aobj itself */ + uvm_obj_destroy(uobj); pool_put(&uvm_aobj_pool, aobj); } diff --git a/sys/uvm/uvm_device.c b/sys/uvm/uvm_device.c index 0a8cf7b8560..e5d035f2947 100644 --- a/sys/uvm/uvm_device.c +++ b/sys/uvm/uvm_device.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_device.c,v 1.64 2021/06/29 01:46:35 jsg Exp $ */ +/* $OpenBSD: uvm_device.c,v 1.65 2021/10/23 14:42:08 mpi Exp $ */ /* $NetBSD: uvm_device.c,v 1.30 2000/11/25 06:27:59 chs Exp $ */ /* @@ -182,6 +182,7 @@ udv_attach(dev_t device, vm_prot_t accessprot, voff_t off, vsize_t size) mtx_leave(&udv_lock); /* NOTE: we could sleep in the following malloc() */ udv = malloc(sizeof(*udv), M_TEMP, M_WAITOK); + uvm_obj_init(&udv->u_obj, &uvm_deviceops, 1); mtx_enter(&udv_lock); /* @@ -199,6 +200,7 @@ udv_attach(dev_t device, vm_prot_t accessprot, voff_t off, vsize_t size) */ if (lcv) { mtx_leave(&udv_lock); + uvm_obj_destroy(&udv->u_obj); free(udv, M_TEMP, sizeof(*udv)); continue; } @@ -207,7 +209,6 @@ udv_attach(dev_t device, vm_prot_t accessprot, voff_t off, vsize_t size) * we have it! init the data structures, add to list * and return. */ - uvm_obj_init(&udv->u_obj, &uvm_deviceops, 1); udv->u_flags = 0; udv->u_device = device; LIST_INSERT_HEAD(&udv_list, udv, u_list); @@ -275,6 +276,8 @@ again: if (udv->u_flags & UVM_DEVICE_WANTED) wakeup(udv); mtx_leave(&udv_lock); + + uvm_obj_destroy(uobj); free(udv, M_TEMP, sizeof(*udv)); } diff --git a/sys/uvm/uvm_object.c b/sys/uvm/uvm_object.c index 20b57df0a97..675cd9de2da 100644 --- a/sys/uvm/uvm_object.c +++ b/sys/uvm/uvm_object.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_object.c,v 1.21 2021/10/12 18:16:51 kettenis Exp $ */ +/* $OpenBSD: uvm_object.c,v 1.22 2021/10/23 14:42:08 mpi Exp $ */ /* * Copyright (c) 2006 The NetBSD Foundation, Inc. @@ -66,9 +66,13 @@ uvm_obj_init(struct uvm_object *uobj, const struct uvm_pagerops *pgops, int refs uobj->uo_refs = refs; } +/* + * uvm_obj_destroy: destroy UVM memory object. + */ void uvm_obj_destroy(struct uvm_object *uo) { + KASSERT(RBT_EMPTY(uvm_objtree, &uo->memt)); } #ifndef SMALL_KERNEL diff --git a/sys/uvm/uvm_vnode.c b/sys/uvm/uvm_vnode.c index 7d5984403bf..3cbdd5222b6 100644 --- a/sys/uvm/uvm_vnode.c +++ b/sys/uvm/uvm_vnode.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_vnode.c,v 1.118 2021/10/20 06:35:40 semarie Exp $ */ +/* $OpenBSD: uvm_vnode.c,v 1.119 2021/10/23 14:42:08 mpi Exp $ */ /* $NetBSD: uvm_vnode.c,v 1.36 2000/11/24 20:34:01 chs Exp $ */ /* @@ -229,7 +229,8 @@ uvn_attach(struct vnode *vp, vm_prot_t accessprot) #endif /* now set up the uvn. */ - uvm_obj_init(&uvn->u_obj, &uvm_vnodeops, 1); + KASSERT(uvn->u_obj.uo_refs == 0); + uvn->u_obj.uo_refs++; oldflags = uvn->u_flags; uvn->u_flags = UVM_VNODE_VALID|UVM_VNODE_CANPERSIST; uvn->u_nio = 0; -- 2.20.1