git: 192112b74fed - main - Add pgo_getvp method

Konstantin Belousov kib at FreeBSD.org
Fri May 7 14:08:22 UTC 2021


The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=192112b74fed56ca652cf1d70c11ba7e17bc1ce2

commit 192112b74fed56ca652cf1d70c11ba7e17bc1ce2
Author:     Konstantin Belousov <kib at FreeBSD.org>
AuthorDate: 2021-05-01 01:04:04 +0000
Commit:     Konstantin Belousov <kib at FreeBSD.org>
CommitDate: 2021-05-07 14:08:03 +0000

    Add pgo_getvp method
    
    This eliminates the staircase of conditions in vm_map_entry_set_vnode_text().
    
    Reviewed by:    markj
    Tested by:      pho
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D30070
---
 sys/vm/swap_pager.c  | 28 ++++++++++++++++++++++++++++
 sys/vm/vm_map.c      | 33 +--------------------------------
 sys/vm/vm_pager.c    | 11 +++++++++++
 sys/vm/vm_pager.h    | 20 ++++++++++++++++++++
 sys/vm/vnode_pager.c |  8 ++++++++
 5 files changed, 68 insertions(+), 32 deletions(-)

diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index 11e494d1ad05..294f61e22cb1 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -435,6 +435,8 @@ static void	swap_pager_release_writecount(vm_object_t object,
     vm_offset_t start, vm_offset_t end);
 static void	swap_pager_set_writeable_dirty(vm_object_t object);
 static bool	swap_pager_mightbedirty(vm_object_t object);
+static void	swap_pager_getvp(vm_object_t object, struct vnode **vpp,
+    bool *vp_heldp);
 
 struct pagerops swappagerops = {
 	.pgo_init =	swap_pager_init,	/* early system initialization of pager	*/
@@ -449,6 +451,7 @@ struct pagerops swappagerops = {
 	.pgo_release_writecount = swap_pager_release_writecount,
 	.pgo_set_writeable_dirty = swap_pager_set_writeable_dirty,
 	.pgo_mightbedirty = swap_pager_mightbedirty,
+	.pgo_getvp = swap_pager_getvp,
 };
 
 /*
@@ -3142,3 +3145,28 @@ swap_pager_mightbedirty(vm_object_t object)
 		return (vm_object_mightbedirty_(object));
 	return (false);
 }
+
+static void
+swap_pager_getvp(vm_object_t object, struct vnode **vpp, bool *vp_heldp)
+{
+	struct vnode *vp;
+
+	KASSERT((object->flags & OBJ_TMPFS_NODE) != 0,
+	    ("swap_pager_getvp: swap and !TMPFS obj %p", object));
+
+	/*
+	 * Tmpfs VREG node, which was reclaimed, has
+	 * OBJ_TMPFS_NODE flag set, but not OBJ_TMPFS.  In
+	 * this case there is no v_writecount to adjust.
+	 */
+	VM_OBJECT_RLOCK(object);
+	if ((object->flags & OBJ_TMPFS) != 0) {
+		vp = object->un_pager.swp.swp_tmpfs;
+		if (vp != NULL) {
+			vhold(vp);
+			*vpp = vp;
+			*vp_heldp = true;
+		}
+	}
+	VM_OBJECT_RUNLOCK(object);
+}
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index b3288fce5114..815775ee9740 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -561,38 +561,7 @@ vm_map_entry_set_vnode_text(vm_map_entry_t entry, bool add)
 	 * referenced by the entry we are processing, so it cannot go
 	 * away.
 	 */
-	vp = NULL;
-	vp_held = false;
-	if (object->type == OBJT_DEAD) {
-		/*
-		 * For OBJT_DEAD objects, v_writecount was handled in
-		 * vnode_pager_dealloc().
-		 */
-	} else if (object->type == OBJT_VNODE) {
-		vp = object->handle;
-	} else if (object->type == OBJT_SWAP) {
-		KASSERT((object->flags & OBJ_TMPFS_NODE) != 0,
-		    ("vm_map_entry_set_vnode_text: swap and !TMPFS "
-		    "entry %p, object %p, add %d", entry, object, add));
-		/*
-		 * Tmpfs VREG node, which was reclaimed, has
-		 * OBJ_TMPFS_NODE flag set, but not OBJ_TMPFS.  In
-		 * this case there is no v_writecount to adjust.
-		 */
-		VM_OBJECT_RLOCK(object);
-		if ((object->flags & OBJ_TMPFS) != 0) {
-			vp = object->un_pager.swp.swp_tmpfs;
-			if (vp != NULL) {
-				vhold(vp);
-				vp_held = true;
-			}
-		}
-		VM_OBJECT_RUNLOCK(object);
-	} else {
-		KASSERT(0,
-		    ("vm_map_entry_set_vnode_text: wrong object type, "
-		    "entry %p, object %p, add %d", entry, object, add));
-	}
+	vm_pager_getvp(object, &vp, &vp_held);
 	if (vp != NULL) {
 		if (add) {
 			VOP_SET_TEXT_CHECKED(vp);
diff --git a/sys/vm/vm_pager.c b/sys/vm/vm_pager.c
index b113ce569e14..587407a06291 100644
--- a/sys/vm/vm_pager.c
+++ b/sys/vm/vm_pager.c
@@ -100,6 +100,7 @@ static vm_object_t dead_pager_alloc(void *, vm_ooffset_t, vm_prot_t,
 static void dead_pager_putpages(vm_object_t, vm_page_t *, int, int, int *);
 static boolean_t dead_pager_haspage(vm_object_t, vm_pindex_t, int *, int *);
 static void dead_pager_dealloc(vm_object_t);
+static void dead_pager_getvp(vm_object_t, struct vnode **, bool *);
 
 static int
 dead_pager_getpages(vm_object_t obj, vm_page_t *ma, int count, int *rbehind,
@@ -144,12 +145,22 @@ dead_pager_dealloc(vm_object_t object)
 
 }
 
+static void
+dead_pager_getvp(vm_object_t object, struct vnode **vpp, bool *vp_heldp)
+{
+	/*
+	 * For OBJT_DEAD objects, v_writecount was handled in
+	 * vnode_pager_dealloc().
+	 */
+}
+
 static struct pagerops deadpagerops = {
 	.pgo_alloc = 	dead_pager_alloc,
 	.pgo_dealloc =	dead_pager_dealloc,
 	.pgo_getpages =	dead_pager_getpages,
 	.pgo_putpages =	dead_pager_putpages,
 	.pgo_haspage =	dead_pager_haspage,
+	.pgo_getvp =	dead_pager_getvp,
 };
 
 struct pagerops *pagertab[] = {
diff --git a/sys/vm/vm_pager.h b/sys/vm/vm_pager.h
index 014a67c2e055..cb2a896c8749 100644
--- a/sys/vm/vm_pager.h
+++ b/sys/vm/vm_pager.h
@@ -47,6 +47,7 @@
 #include <sys/queue.h>
 
 TAILQ_HEAD(pagerlst, vm_object);
+struct vnode;
 
 typedef void pgo_init_t(void);
 typedef vm_object_t pgo_alloc_t(void *, vm_ooffset_t, vm_prot_t, vm_ooffset_t,
@@ -64,6 +65,8 @@ typedef void pgo_pageunswapped_t(vm_page_t);
 typedef void pgo_writecount_t(vm_object_t, vm_offset_t, vm_offset_t);
 typedef void pgo_set_writeable_dirty_t(vm_object_t);
 typedef bool pgo_mightbedirty_t(vm_object_t);
+typedef void pgo_getvp_t(vm_object_t object, struct vnode **vpp,
+    bool *vp_heldp);
 
 struct pagerops {
 	pgo_init_t		*pgo_init;		/* Initialize pager. */
@@ -79,6 +82,7 @@ struct pagerops {
 	pgo_writecount_t	*pgo_release_writecount;
 	pgo_set_writeable_dirty_t *pgo_set_writeable_dirty;
 	pgo_mightbedirty_t	*pgo_mightbedirty;
+	pgo_getvp_t		*pgo_getvp;
 };
 
 extern struct pagerops defaultpagerops;
@@ -216,6 +220,22 @@ vm_pager_release_writecount(vm_object_t object, vm_offset_t start,
 		method(object, start, end);
 }
 
+static __inline void
+vm_pager_getvp(vm_object_t object, struct vnode **vpp, bool *vp_heldp)
+{
+	pgo_getvp_t *method;
+
+	*vpp = NULL;
+	*vp_heldp = false;
+	method = pagertab[object->type]->pgo_getvp;
+	if (method != NULL) {
+		method(object, vpp, vp_heldp);
+	} else {
+		KASSERT(0,
+		    ("vm_pager_getvp: wrong object type obj %p", object));
+	}
+}
+
 struct cdev_pager_ops {
 	int (*cdev_pg_fault)(vm_object_t vm_obj, vm_ooffset_t offset,
 	    int prot, vm_page_t *mres);
diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c
index 0ab018eda6ee..3d8288f7e72f 100644
--- a/sys/vm/vnode_pager.c
+++ b/sys/vm/vnode_pager.c
@@ -105,6 +105,7 @@ static void vnode_pager_update_writecount(vm_object_t, vm_offset_t,
     vm_offset_t);
 static void vnode_pager_release_writecount(vm_object_t, vm_offset_t,
     vm_offset_t);
+static void vnode_pager_getvp(vm_object_t, struct vnode **, bool *);
 
 struct pagerops vnodepagerops = {
 	.pgo_alloc =	vnode_pager_alloc,
@@ -117,6 +118,7 @@ struct pagerops vnodepagerops = {
 	.pgo_release_writecount = vnode_pager_release_writecount,
 	.pgo_set_writeable_dirty = vm_object_set_writeable_dirty_,
 	.pgo_mightbedirty = vm_object_mightbedirty_,
+	.pgo_getvp = vnode_pager_getvp,
 };
 
 static struct domainset *vnode_domainset = NULL;
@@ -1602,3 +1604,9 @@ vnode_pager_release_writecount(vm_object_t object, vm_offset_t start,
 	if (mp != NULL)
 		vn_finished_write(mp);
 }
+
+static void
+vnode_pager_getvp(vm_object_t object, struct vnode **vpp, bool *vp_heldp)
+{
+	*vpp = object->handle;
+}


More information about the dev-commits-src-all mailing list