The branch main has been updated by kib:

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

commit 192112b74fed56ca652cf1d70c11ba7e17bc1ce2
Author:     Konstantin Belousov <k...@freebsd.org>
AuthorDate: 2021-05-01 01:04:04 +0000
Commit:     Konstantin Belousov <k...@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;
+}
_______________________________________________
dev-commits-src-main@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main
To unsubscribe, send any mail to "dev-commits-src-main-unsubscr...@freebsd.org"

Reply via email to