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@
-/* $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 $ */
/*
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);
-/* $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 $ */
/*
/*
* finally free the aobj itself
*/
+ uvm_obj_destroy(uobj);
pool_put(&uvm_aobj_pool, aobj);
}
-/* $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 $ */
/*
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);
/*
*/
if (lcv) {
mtx_leave(&udv_lock);
+ uvm_obj_destroy(&udv->u_obj);
free(udv, M_TEMP, sizeof(*udv));
continue;
}
* 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);
if (udv->u_flags & UVM_DEVICE_WANTED)
wakeup(udv);
mtx_leave(&udv_lock);
+
+ uvm_obj_destroy(uobj);
free(udv, M_TEMP, sizeof(*udv));
}
-/* $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.
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
-/* $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 $ */
/*
#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;