Diff below is extracted from the current UVM unlocking diff. It adds a
couple of uvm_obj_destroy() and move some uvm_obj_init() around.
uvm_obj_destroy() will be used to release the memory of the, possibly
shared, lock allocated in uvm_obj_init(). When it is call the object
should no longer have any paged attached to it, that's why I added the
corresponding KASSERT().
uvm_obj_init() have been moved to satisfy lock assertions and reduce
differences with NetBSD. The tricky one is for vnode which are never
freed.
Comments? Oks?
Index: kern/vfs_subr.c
===================================================================
RCS file: /cvs/src/sys/kern/vfs_subr.c,v
retrieving revision 1.309
diff -u -p -r1.309 vfs_subr.c
--- kern/vfs_subr.c 21 Oct 2021 09:59:14 -0000 1.309
+++ kern/vfs_subr.c 23 Oct 2021 09:53:48 -0000
@@ -410,6 +410,7 @@ getnewvnode(enum vtagtype tag, struct mo
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);
Index: uvm/uvm_aobj.c
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_aobj.c,v
retrieving revision 1.99
diff -u -p -r1.99 uvm_aobj.c
--- uvm/uvm_aobj.c 28 Jun 2021 11:19:01 -0000 1.99
+++ uvm/uvm_aobj.c 23 Oct 2021 09:52:02 -0000
@@ -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);
}
Index: uvm/uvm_device.c
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_device.c,v
retrieving revision 1.64
diff -u -p -r1.64 uvm_device.c
--- uvm/uvm_device.c 29 Jun 2021 01:46:35 -0000 1.64
+++ uvm/uvm_device.c 23 Oct 2021 09:49:16 -0000
@@ -182,6 +182,7 @@ udv_attach(dev_t device, vm_prot_t acces
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 acces
*/
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 acces
* 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));
}
Index: uvm/uvm_object.c
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_object.c,v
retrieving revision 1.21
diff -u -p -r1.21 uvm_object.c
--- uvm/uvm_object.c 12 Oct 2021 18:16:51 -0000 1.21
+++ uvm/uvm_object.c 23 Oct 2021 09:49:57 -0000
@@ -66,9 +66,13 @@ uvm_obj_init(struct uvm_object *uobj, co
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
Index: uvm/uvm_vnode.c
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_vnode.c,v
retrieving revision 1.118
diff -u -p -r1.118 uvm_vnode.c
--- uvm/uvm_vnode.c 20 Oct 2021 06:35:40 -0000 1.118
+++ uvm/uvm_vnode.c 23 Oct 2021 09:56:32 -0000
@@ -229,7 +229,8 @@ uvn_attach(struct vnode *vp, vm_prot_t a
#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;