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-main
mailing list