Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 22 May 2021 09:46:33 GMT
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 2daf5ac2e53e - stable/13 - Add OBJT_SWAP_TMPFS pager
Message-ID:  <202105220946.14M9kXLH012522@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=2daf5ac2e53efeb799c5127f3579fb09bbfc5306

commit 2daf5ac2e53efeb799c5127f3579fb09bbfc5306
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2021-05-01 01:18:00 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2021-05-22 09:38:29 +0000

    Add OBJT_SWAP_TMPFS pager
    
    (cherry picked from commit 4b8365d752ef48c14f0584d21b719bb386a7be82)
---
 sys/fs/procfs/procfs_map.c  |  17 ++++---
 sys/fs/tmpfs/tmpfs_subr.c   |  11 ++---
 sys/fs/tmpfs/tmpfs_vfsops.c |  10 ++--
 sys/fs/tmpfs/tmpfs_vnops.c  |   5 +-
 sys/vm/swap_pager.c         | 114 ++++++++++++++++++++++++--------------------
 sys/vm/vm.h                 |   1 +
 sys/vm/vm_fault.c           |   2 +-
 sys/vm/vm_map.c             |   8 ++--
 sys/vm/vm_mmap.c            |   5 +-
 sys/vm/vm_object.c          |  24 ++++++----
 sys/vm/vm_object.h          |   2 +-
 sys/vm/vm_page.c            |   4 +-
 sys/vm/vm_pageout.c         |   5 +-
 sys/vm/vm_pager.c           |   1 +
 sys/vm/vm_pager.h           |   1 +
 15 files changed, 115 insertions(+), 95 deletions(-)

diff --git a/sys/fs/procfs/procfs_map.c b/sys/fs/procfs/procfs_map.c
index a9893e5e10f0..eaa1cf8d4d35 100644
--- a/sys/fs/procfs/procfs_map.c
+++ b/sys/fs/procfs/procfs_map.c
@@ -165,17 +165,16 @@ procfs_doprocmap(PFS_FILL_ARGS)
 				vp = lobj->handle;
 				vref(vp);
 				break;
-			case OBJT_SWAP:
-				if ((lobj->flags & OBJ_TMPFS_NODE) != 0) {
-					type = "vnode";
-					if ((lobj->flags & OBJ_TMPFS) != 0) {
-						vp = lobj->un_pager.swp.swp_tmpfs;
-						vref(vp);
-					}
-				} else {
-					type = "swap";
+			case OBJT_SWAP_TMPFS:
+				type = "vnode";
+				if ((lobj->flags & OBJ_TMPFS) != 0) {
+					vp = lobj->un_pager.swp.swp_tmpfs;
+					vref(vp);
 				}
 				break;
+			case OBJT_SWAP:
+				type = "swap";
+				break;
 			case OBJT_SG:
 			case OBJT_DEVICE:
 				type = "device";
diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c
index 84473a439c43..1ea4cf23b314 100644
--- a/sys/fs/tmpfs/tmpfs_subr.c
+++ b/sys/fs/tmpfs/tmpfs_subr.c
@@ -364,12 +364,10 @@ tmpfs_alloc_node(struct mount *mp, struct tmpfs_mount *tmp, enum vtype type,
 
 	case VREG:
 		obj = nnode->tn_reg.tn_aobj =
-		    vm_pager_allocate(OBJT_SWAP, NULL, 0, VM_PROT_DEFAULT, 0,
+		    vm_pager_allocate(OBJT_SWAP_TMPFS, NULL, 0,
+			VM_PROT_DEFAULT, 0,
 			NULL /* XXXKIB - tmpfs needs swap reservation */);
-		VM_OBJECT_WLOCK(obj);
 		/* OBJ_TMPFS is set together with the setting of vp->v_object */
-		vm_object_set_flag(obj, OBJ_TMPFS_NODE);
-		VM_OBJECT_WUNLOCK(obj);
 		nnode->tn_reg.tn_tmp = tmp;
 		break;
 
@@ -1590,8 +1588,9 @@ tmpfs_check_mtime(struct vnode *vp)
 	if (vp->v_type != VREG)
 		return;
 	obj = vp->v_object;
-	KASSERT((obj->flags & (OBJ_TMPFS_NODE | OBJ_TMPFS)) ==
-	    (OBJ_TMPFS_NODE | OBJ_TMPFS), ("non-tmpfs obj"));
+	KASSERT(obj->type == OBJT_SWAP_TMPFS &&
+	    (obj->flags & (OBJ_SWAP | OBJ_TMPFS)) ==
+	    (OBJ_SWAP | OBJ_TMPFS), ("non-tmpfs obj"));
 	/* unlocked read */
 	if (obj->generation != obj->cleangeneration) {
 		VM_OBJECT_WLOCK(obj);
diff --git a/sys/fs/tmpfs/tmpfs_vfsops.c b/sys/fs/tmpfs/tmpfs_vfsops.c
index ba7c654d4f0a..51d097203135 100644
--- a/sys/fs/tmpfs/tmpfs_vfsops.c
+++ b/sys/fs/tmpfs/tmpfs_vfsops.c
@@ -120,8 +120,8 @@ tmpfs_update_mtime(struct mount *mp, bool lazy)
 			continue;
 		}
 		obj = vp->v_object;
-		KASSERT((obj->flags & (OBJ_TMPFS_NODE | OBJ_TMPFS)) ==
-		    (OBJ_TMPFS_NODE | OBJ_TMPFS), ("non-tmpfs obj"));
+		MPASS(obj->type == OBJT_SWAP_TMPFS);
+		MPASS((obj->flags & OBJ_TMPFS) != 0);
 
 		/*
 		 * In lazy case, do unlocked read, avoid taking vnode
@@ -225,8 +225,7 @@ again:
 			    (entry->max_protection & VM_PROT_WRITE) == 0)
 				continue;
 			object = entry->object.vm_object;
-			if (object == NULL || object->type != OBJT_SWAP ||
-			    (object->flags & OBJ_TMPFS_NODE) == 0)
+			if (object == NULL || object->type != OBJT_SWAP_TMPFS)
 				continue;
 			/*
 			 * No need to dig into shadow chain, mapping
@@ -239,8 +238,7 @@ again:
 				continue;
 			}
 			MPASS(object->ref_count > 1);
-			if ((object->flags & (OBJ_TMPFS_NODE | OBJ_TMPFS)) !=
-			    (OBJ_TMPFS_NODE | OBJ_TMPFS)) {
+			if ((object->flags & OBJ_TMPFS) == 0) {
 				VM_OBJECT_RUNLOCK(object);
 				continue;
 			}
diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c
index 94cb7fd868fa..401ee672b96a 100644
--- a/sys/fs/tmpfs/tmpfs_vnops.c
+++ b/sys/fs/tmpfs/tmpfs_vnops.c
@@ -623,8 +623,9 @@ tmpfs_read_pgcache(struct vop_read_pgcache_args *v)
 	if (object == NULL)
 		goto out_smr;
 
-	MPASS((object->flags & (OBJ_ANON | OBJ_DEAD | OBJ_TMPFS_NODE)) ==
-	    OBJ_TMPFS_NODE);
+	MPASS(object->type == OBJT_SWAP_TMPFS);
+	MPASS((object->flags & (OBJ_ANON | OBJ_DEAD | OBJ_SWAP)) ==
+	    OBJ_SWAP);
 	if (!VN_IS_DOOMED(vp)) {
 		/* size cannot become shorter due to rangelock. */
 		size = node->tn_size;
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index b81f73e41d05..2eaf1f746b58 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -418,6 +418,9 @@ static uma_zone_t swpctrie_zone;
 static vm_object_t
 		swap_pager_alloc(void *handle, vm_ooffset_t size,
 		    vm_prot_t prot, vm_ooffset_t offset, struct ucred *);
+static vm_object_t
+		swap_tmpfs_pager_alloc(void *handle, vm_ooffset_t size,
+		    vm_prot_t prot, vm_ooffset_t offset, struct ucred *);
 static void	swap_pager_dealloc(vm_object_t object);
 static int	swap_pager_getpages(vm_object_t, vm_page_t *, int, int *,
     int *);
@@ -433,9 +436,7 @@ static void	swap_pager_update_writecount(vm_object_t object,
     vm_offset_t start, vm_offset_t end);
 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,
+static void	swap_tmpfs_pager_getvp(vm_object_t object, struct vnode **vpp,
     bool *vp_heldp);
 static void	swap_pager_freespace(vm_object_t object, vm_pindex_t start,
     vm_size_t size);
@@ -451,9 +452,22 @@ struct pagerops swappagerops = {
 	.pgo_pageunswapped = swap_pager_unswapped, /* remove swap related to page */
 	.pgo_update_writecount = swap_pager_update_writecount,
 	.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,
+	.pgo_freespace = swap_pager_freespace,
+};
+
+struct pagerops swaptmpfspagerops = {
+	.pgo_alloc =	swap_tmpfs_pager_alloc,
+	.pgo_dealloc =	swap_pager_dealloc,
+	.pgo_getpages =	swap_pager_getpages,
+	.pgo_getpages_async = swap_pager_getpages_async,
+	.pgo_putpages =	swap_pager_putpages,
+	.pgo_haspage =	swap_pager_haspage,
+	.pgo_pageunswapped = swap_pager_unswapped,
+	.pgo_update_writecount = swap_pager_update_writecount,
+	.pgo_release_writecount = swap_pager_release_writecount,
+	.pgo_set_writeable_dirty = vm_object_set_writeable_dirty_,
+	.pgo_mightbedirty = vm_object_mightbedirty_,
+	.pgo_getvp = swap_tmpfs_pager_getvp,
 	.pgo_freespace = swap_pager_freespace,
 };
 
@@ -665,8 +679,8 @@ swap_pager_swap_init(void)
 }
 
 static vm_object_t
-swap_pager_alloc_init(void *handle, struct ucred *cred, vm_ooffset_t size,
-    vm_ooffset_t offset)
+swap_pager_alloc_init(objtype_t otype, void *handle, struct ucred *cred,
+    vm_ooffset_t size, vm_ooffset_t offset)
 {
 	vm_object_t object;
 
@@ -681,7 +695,7 @@ swap_pager_alloc_init(void *handle, struct ucred *cred, vm_ooffset_t size,
 	 * vm_object_allocate() to ensure the correct order of
 	 * visibility to other threads.
 	 */
-	object = vm_object_allocate(OBJT_SWAP, OFF_TO_IDX(offset +
+	object = vm_object_allocate(otype, OFF_TO_IDX(offset +
 	    PAGE_MASK + size));
 
 	object->un_pager.swp.writemappings = 0;
@@ -720,8 +734,8 @@ swap_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot,
 		sx_xlock(&sw_alloc_sx);
 		object = vm_pager_object_lookup(NOBJLIST(handle), handle);
 		if (object == NULL) {
-			object = swap_pager_alloc_init(handle, cred, size,
-			    offset);
+			object = swap_pager_alloc_init(OBJT_SWAP, handle, cred,
+			    size, offset);
 			if (object != NULL) {
 				TAILQ_INSERT_TAIL(NOBJLIST(object->handle),
 				    object, pager_object_list);
@@ -729,11 +743,24 @@ swap_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot,
 		}
 		sx_xunlock(&sw_alloc_sx);
 	} else {
-		object = swap_pager_alloc_init(handle, cred, size, offset);
+		object = swap_pager_alloc_init(OBJT_SWAP, handle, cred,
+		    size, offset);
 	}
 	return (object);
 }
 
+static vm_object_t
+swap_tmpfs_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot,
+    vm_ooffset_t offset, struct ucred *cred)
+{
+	vm_object_t object;
+
+	MPASS(handle == NULL);
+	object = swap_pager_alloc_init(OBJT_SWAP_TMPFS, handle, cred,
+	    size, offset);
+	return (object);
+}
+
 /*
  * SWAP_PAGER_DEALLOC() -	remove swap metadata from object
  *
@@ -775,6 +802,7 @@ swap_pager_dealloc(vm_object_t object)
 	swp_pager_meta_free_all(object);
 	object->handle = NULL;
 	object->type = OBJT_DEAD;
+	vm_object_clear_flag(object, OBJ_SWAP);
 }
 
 /************************************************************************
@@ -1003,9 +1031,9 @@ swp_pager_xfer_source(vm_object_t srcobject, vm_object_t dstobject,
 {
 	daddr_t dstaddr;
 
-	KASSERT(srcobject->type == OBJT_SWAP,
+	KASSERT((srcobject->flags & OBJ_SWAP) != 0,
 	    ("%s: Srcobject not swappable", __func__));
-	if (dstobject->type == OBJT_SWAP &&
+	if ((dstobject->flags & OBJ_SWAP) != 0 &&
 	    swp_pager_meta_lookup(dstobject, pindex) != SWAPBLK_NONE) {
 		/* Caller should destroy the source block. */
 		return (false);
@@ -1086,6 +1114,7 @@ swap_pager_copy(vm_object_t srcobject, vm_object_t dstobject,
 		 * queues.
 		 */
 		srcobject->type = OBJT_DEFAULT;
+		vm_object_clear_flag(srcobject, OBJ_SWAP);
 	}
 }
 
@@ -1107,7 +1136,7 @@ swap_pager_haspage(vm_object_t object, vm_pindex_t pindex, int *before,
 	int i;
 
 	VM_OBJECT_ASSERT_LOCKED(object);
-	KASSERT(object->type == OBJT_SWAP,
+	KASSERT((object->flags & OBJ_SWAP) != 0,
 	    ("%s: object not swappable", __func__));
 
 	/*
@@ -1203,7 +1232,7 @@ swap_pager_unswapped(vm_page_t m)
 	 * The meta data only exists if the object is OBJT_SWAP
 	 * and even then might not be allocated yet.
 	 */
-	KASSERT(m->object->type == OBJT_SWAP,
+	KASSERT((m->object->flags & OBJ_SWAP) != 0,
 	    ("Free object not swappable"));
 
 	sb = SWAP_PCTRIE_LOOKUP(&m->object->un_pager.swp.swp_blks,
@@ -1241,7 +1270,7 @@ swap_pager_getpages_locked(vm_object_t object, vm_page_t *ma, int count,
 	VM_OBJECT_ASSERT_WLOCKED(object);
 	reqcount = count;
 
-	KASSERT(object->type == OBJT_SWAP,
+	KASSERT((object->flags & OBJ_SWAP) != 0,
 	    ("%s: object not swappable", __func__));
 	if (!swap_pager_haspage(object, ma[0]->pindex, &maxbehind, &maxahead)) {
 		VM_OBJECT_WUNLOCK(object);
@@ -1475,7 +1504,7 @@ swap_pager_putpages(vm_object_t object, vm_page_t *ma, int count,
 	 *
 	 * Turn object into OBJT_SWAP.  Force sync if not a pageout process.
 	 */
-	if (object->type != OBJT_SWAP) {
+	if ((object->flags & OBJ_SWAP) == 0) {
 		addr = swp_pager_meta_build(object, 0, SWAPBLK_NONE);
 		KASSERT(addr == SWAPBLK_NONE,
 		    ("unexpected object swap block"));
@@ -1780,7 +1809,7 @@ swap_pager_swapped_pages(vm_object_t object)
 	int i;
 
 	VM_OBJECT_ASSERT_LOCKED(object);
-	if (object->type != OBJT_SWAP)
+	if ((object->flags & OBJ_SWAP) == 0)
 		return (0);
 
 	for (res = 0, pi = 0; (sb = SWAP_PCTRIE_LOOKUP_GE(
@@ -1809,7 +1838,7 @@ swap_pager_swapoff_object(struct swdevt *sp, vm_object_t object)
 	daddr_t blk;
 	int i, nv, rahead, rv;
 
-	KASSERT(object->type == OBJT_SWAP,
+	KASSERT((object->flags & OBJ_SWAP) != 0,
 	    ("%s: Object not swappable", __func__));
 
 	for (pi = 0; (sb = SWAP_PCTRIE_LOOKUP_GE(
@@ -1917,7 +1946,7 @@ swap_pager_swapoff(struct swdevt *sp)
 full_rescan:
 	mtx_lock(&vm_object_list_mtx);
 	TAILQ_FOREACH(object, &vm_object_list, object_list) {
-		if (object->type != OBJT_SWAP)
+		if ((object->flags & OBJ_SWAP) == 0)
 			continue;
 		mtx_unlock(&vm_object_list_mtx);
 		/* Depends on type-stability. */
@@ -1936,7 +1965,7 @@ full_rescan:
 		 * dead.
 		 */
 		atomic_thread_fence_acq();
-		if (object->type != OBJT_SWAP)
+		if ((object->flags & OBJ_SWAP) == 0)
 			goto next_obj;
 
 		swap_pager_swapoff_object(sp, object);
@@ -2031,7 +2060,7 @@ swp_pager_meta_build(vm_object_t object, vm_pindex_t pindex, daddr_t swapblk)
 	/*
 	 * Convert default object to swap object if necessary
 	 */
-	if (object->type != OBJT_SWAP) {
+	if ((object->flags & OBJ_SWAP) == 0) {
 		pctrie_init(&object->un_pager.swp.swp_blks);
 
 		/*
@@ -2041,6 +2070,7 @@ swp_pager_meta_build(vm_object_t object, vm_pindex_t pindex, daddr_t swapblk)
 		atomic_thread_fence_rel();
 
 		object->type = OBJT_SWAP;
+		vm_object_set_flag(object, OBJ_SWAP);
 		object->un_pager.swp.writemappings = 0;
 		KASSERT((object->flags & OBJ_ANON) != 0 ||
 		    object->handle == NULL,
@@ -2149,7 +2179,7 @@ swp_pager_meta_transfer(vm_object_t srcobject, vm_object_t dstobject,
 	int i, limit, start;
 
 	VM_OBJECT_ASSERT_WLOCKED(srcobject);
-	if (srcobject->type != OBJT_SWAP || count == 0)
+	if ((srcobject->flags & OBJ_SWAP) == 0 || count == 0)
 		return;
 
 	swp_pager_init_freerange(&s_free, &n_free);
@@ -2216,7 +2246,7 @@ swp_pager_meta_free_all(vm_object_t object)
 	int i;
 
 	VM_OBJECT_ASSERT_WLOCKED(object);
-	if (object->type != OBJT_SWAP)
+	if ((object->flags & OBJ_SWAP) == 0)
 		return;
 
 	swp_pager_init_freerange(&s_free, &n_free);
@@ -2256,7 +2286,7 @@ swp_pager_meta_lookup(vm_object_t object, vm_pindex_t pindex)
 	 * The meta data only exists if the object is OBJT_SWAP
 	 * and even then might not be allocated yet.
 	 */
-	KASSERT(object->type == OBJT_SWAP,
+	KASSERT((object->flags & OBJ_SWAP) != 0,
 	    ("Lookup object not swappable"));
 
 	sb = SWAP_PCTRIE_LOOKUP(&object->un_pager.swp.swp_blks,
@@ -2280,7 +2310,7 @@ swap_pager_find_least(vm_object_t object, vm_pindex_t pindex)
 	int i;
 
 	VM_OBJECT_ASSERT_LOCKED(object);
-	if (object->type != OBJT_SWAP)
+	if ((object->flags & OBJ_SWAP) == 0)
 		return (object->size);
 
 	sb = SWAP_PCTRIE_LOOKUP_GE(&object->un_pager.swp.swp_blks,
@@ -2739,10 +2769,10 @@ vmspace_swap_count(struct vmspace *vmspace)
 		if ((cur->eflags & MAP_ENTRY_IS_SUB_MAP) != 0)
 			continue;
 		object = cur->object.vm_object;
-		if (object == NULL || object->type != OBJT_SWAP)
+		if (object == NULL || (object->flags & OBJ_SWAP) == 0)
 			continue;
 		VM_OBJECT_RLOCK(object);
-		if (object->type != OBJT_SWAP)
+		if ((object->flags & OBJ_SWAP) == 0)
 			goto unlock;
 		pi = OFF_TO_IDX(cur->offset);
 		e = pi + OFF_TO_IDX(cur->end - cur->start);
@@ -3137,32 +3167,14 @@ swap_pager_release_writecount(vm_object_t object, vm_offset_t start,
 }
 
 static void
-swap_pager_set_writeable_dirty(vm_object_t object)
-{
-	if ((object->flags & OBJ_TMPFS_NODE) != 0)
-		vm_object_set_writeable_dirty_(object);
-}
-
-static bool
-swap_pager_mightbedirty(vm_object_t object)
-{
-	if ((object->flags & OBJ_TMPFS_NODE) != 0)
-		return (vm_object_mightbedirty_(object));
-	return (false);
-}
-
-static void
-swap_pager_getvp(vm_object_t object, struct vnode **vpp, bool *vp_heldp)
+swap_tmpfs_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.
+	 * Tmpfs VREG node, which was reclaimed, has OBJT_SWAP_TMPFS
+	 * type, but not OBJ_TMPFS flag.  In this case there is no
+	 * v_writecount to adjust.
 	 */
 	if (vp_heldp != NULL)
 		VM_OBJECT_RLOCK(object);
diff --git a/sys/vm/vm.h b/sys/vm/vm.h
index 78d4cbbb1fd3..10bf3d46f2c0 100644
--- a/sys/vm/vm.h
+++ b/sys/vm/vm.h
@@ -97,6 +97,7 @@ enum obj_type {
 	OBJT_DEAD,
 	OBJT_SG,
 	OBJT_MGTDEVICE,
+	OBJT_SWAP_TMPFS,
 };
 typedef u_char objtype_t;
 
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 0e8ff9b27ed1..03ca297ea683 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -1943,7 +1943,7 @@ vm_fault_copy_entry(vm_map_t dst_map, vm_map_t src_map,
 		crhold(dst_object->cred);
 		*fork_charge += dst_object->charge;
 	} else if ((dst_object->type == OBJT_DEFAULT ||
-	    dst_object->type == OBJT_SWAP) &&
+	    (dst_object->flags & OBJ_SWAP) != 0) &&
 	    dst_object->cred == NULL) {
 		KASSERT(dst_entry->cred != NULL, ("no cred for entry %p",
 		    dst_entry));
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 60c88a7b71bf..1ac4ccf72f11 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -2826,10 +2826,12 @@ again:
 			continue;
 		}
 
-		if (obj->type != OBJT_DEFAULT && obj->type != OBJT_SWAP)
+		if (obj->type != OBJT_DEFAULT &&
+		    (obj->flags & OBJ_SWAP) == 0)
 			continue;
 		VM_OBJECT_WLOCK(obj);
-		if (obj->type != OBJT_DEFAULT && obj->type != OBJT_SWAP) {
+		if (obj->type != OBJT_DEFAULT &&
+		    (obj->flags & OBJ_SWAP) == 0) {
 			VM_OBJECT_WUNLOCK(obj);
 			continue;
 		}
@@ -4140,7 +4142,7 @@ vm_map_copy_entry(
 		size = src_entry->end - src_entry->start;
 		if ((src_object = src_entry->object.vm_object) != NULL) {
 			if (src_object->type == OBJT_DEFAULT ||
-			    src_object->type == OBJT_SWAP) {
+			    (src_object->flags & OBJ_SWAP) != 0) {
 				vm_map_copy_swap_object(src_entry, dst_entry,
 				    size, fork_charge);
 				/* May have split/collapsed, reload obj. */
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index 30c485010ac8..adbecd01ef38 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -929,7 +929,7 @@ retry:
 					VM_OBJECT_WLOCK(object);
 				}
 				if (object->type == OBJT_DEFAULT ||
-				    object->type == OBJT_SWAP ||
+				    (object->flags & OBJ_SWAP) != 0 ||
 				    object->type == OBJT_VNODE) {
 					pindex = OFF_TO_IDX(current->offset +
 					    (addr - current->start));
@@ -1356,7 +1356,8 @@ vm_mmap_vnode(struct thread *td, vm_size_t objsize,
 			goto done;
 		}
 	} else {
-		KASSERT(obj->type == OBJT_DEFAULT || obj->type == OBJT_SWAP,
+		KASSERT(obj->type == OBJT_DEFAULT ||
+		    (obj->flags & OBJ_SWAP) != 0,
 		    ("wrong object type"));
 		vm_object_reference(obj);
 #if VM_NRESERVLEVEL > 0
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index bbcbad41f10c..1c4e879d82ea 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -240,7 +240,8 @@ _vm_object_allocate(objtype_t type, vm_pindex_t size, u_short flags,
 	LIST_INIT(&object->shadow_head);
 
 	object->type = type;
-	if (type == OBJT_SWAP)
+	object->flags = flags;
+	if ((flags & OBJ_SWAP) != 0)
 		pctrie_init(&object->un_pager.swp.swp_blks);
 
 	/*
@@ -251,7 +252,6 @@ _vm_object_allocate(objtype_t type, vm_pindex_t size, u_short flags,
 	atomic_thread_fence_rel();
 
 	object->pg_color = 0;
-	object->flags = flags;
 	object->size = size;
 	object->domain.dr_policy = NULL;
 	object->generation = 1;
@@ -337,6 +337,7 @@ vm_object_set_memattr(vm_object_t object, vm_memattr_t memattr)
 	case OBJT_PHYS:
 	case OBJT_SG:
 	case OBJT_SWAP:
+	case OBJT_SWAP_TMPFS:
 	case OBJT_VNODE:
 		if (!TAILQ_EMPTY(&object->memq))
 			return (KERN_FAILURE);
@@ -421,9 +422,12 @@ vm_object_allocate(objtype_t type, vm_pindex_t size)
 	case OBJT_DEAD:
 		panic("vm_object_allocate: can't create OBJT_DEAD");
 	case OBJT_DEFAULT:
-	case OBJT_SWAP:
 		flags = OBJ_COLORED;
 		break;
+	case OBJT_SWAP:
+	case OBJT_SWAP_TMPFS:
+		flags = OBJ_COLORED | OBJ_SWAP;
+		break;
 	case OBJT_DEVICE:
 	case OBJT_SG:
 		flags = OBJ_FICTITIOUS | OBJ_UNMANAGED;
@@ -573,7 +577,7 @@ vm_object_deallocate_anon(vm_object_t backing_object)
 	KASSERT(object != NULL && backing_object->shadow_count == 1,
 	    ("vm_object_anon_deallocate: ref_count: %d, shadow_count: %d",
 	    backing_object->ref_count, backing_object->shadow_count));
-	KASSERT((object->flags & (OBJ_TMPFS_NODE | OBJ_ANON)) == OBJ_ANON,
+	KASSERT((object->flags & OBJ_ANON) != 0,
 	    ("invalid shadow object %p", object));
 
 	if (!VM_OBJECT_TRYWLOCK(object)) {
@@ -677,7 +681,7 @@ vm_object_deallocate(vm_object_t object)
 		umtx_shm_object_terminated(object);
 		temp = object->backing_object;
 		if (temp != NULL) {
-			KASSERT((object->flags & OBJ_TMPFS_NODE) == 0,
+			KASSERT(object->type != OBJT_SWAP_TMPFS,
 			    ("shadowed tmpfs v_object 2 %p", object));
 			vm_object_backing_remove(object);
 		}
@@ -958,7 +962,7 @@ vm_object_terminate(vm_object_t object)
 #endif
 
 	KASSERT(object->cred == NULL || object->type == OBJT_DEFAULT ||
-	    object->type == OBJT_SWAP,
+	    object->type == OBJT_SWAP || object->type == OBJT_SWAP_TMPFS,
 	    ("%s: non-swap obj %p has cred", __func__, object));
 
 	/*
@@ -1627,7 +1631,7 @@ retry:
 		else if (m_busy == NULL)
 			m_busy = m;
 	}
-	if (orig_object->type == OBJT_SWAP) {
+	if ((orig_object->flags & OBJ_SWAP) != 0) {
 		/*
 		 * swap_pager_copy() can sleep, in which case the orig_object's
 		 * and new_object's locks are released and reacquired. 
@@ -1955,7 +1959,7 @@ vm_object_collapse(vm_object_t object)
 			/*
 			 * Move the pager from backing_object to object.
 			 */
-			if (backing_object->type == OBJT_SWAP) {
+			if ((backing_object->flags & OBJ_SWAP) != 0) {
 				/*
 				 * swap_pager_copy() can sleep, in which case
 				 * the backing_object's and object's locks are
@@ -2482,9 +2486,9 @@ vm_object_kvme_type(vm_object_t object, struct vnode **vpp)
 	case OBJT_VNODE:
 		return (KVME_TYPE_VNODE);
 	case OBJT_SWAP:
-		if ((object->flags & OBJ_TMPFS_NODE) != 0)
-			return (KVME_TYPE_VNODE);
 		return (KVME_TYPE_SWAP);
+	case OBJT_SWAP_TMPFS:
+		return (KVME_TYPE_VNODE);
 	case OBJT_DEVICE:
 		return (KVME_TYPE_DEVICE);
 	case OBJT_PHYS:
diff --git a/sys/vm/vm_object.h b/sys/vm/vm_object.h
index c7bbec0e7a86..749f33ee16c0 100644
--- a/sys/vm/vm_object.h
+++ b/sys/vm/vm_object.h
@@ -201,7 +201,7 @@ struct vm_object {
 #define	OBJ_UMTXDEAD	0x0020		/* umtx pshared was terminated */
 #define	OBJ_SIZEVNLOCK	0x0040		/* lock vnode to check obj size */
 #define	OBJ_PG_DTOR	0x0080		/* dont reset object, leave that for dtor */
-#define	OBJ_TMPFS_NODE	0x0200		/* object belongs to tmpfs VREG node */
+#define	OBJ_SWAP	0x0200		/* object swaps */
 #define	OBJ_SPLIT	0x0400		/* object is being split */
 #define	OBJ_COLLAPSING	0x0800		/* Parent of collapse. */
 #define	OBJ_COLORED	0x1000		/* pg_color is defined */
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index da62e6795c81..c7d548471e89 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -2639,7 +2639,7 @@ retry:
 			}
 			/* Don't care: PG_NODUMP, PG_ZERO. */
 			if (object->type != OBJT_DEFAULT &&
-			    object->type != OBJT_SWAP &&
+			    (object->flags & OBJ_SWAP) == 0 &&
 			    object->type != OBJT_VNODE) {
 				run_ext = 0;
 #if VM_NRESERVLEVEL > 0
@@ -2777,7 +2777,7 @@ vm_page_reclaim_run(int req_class, int domain, u_long npages, vm_page_t m_run,
 			/* Don't care: PG_NODUMP, PG_ZERO. */
 			if (m->object != object ||
 			    (object->type != OBJT_DEFAULT &&
-			    object->type != OBJT_SWAP &&
+			    (object->flags & OBJ_SWAP) == 0 &&
 			    object->type != OBJT_VNODE))
 				error = EINVAL;
 			else if (object->memattr != VM_MEMATTR_DEFAULT)
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index e49966102a9c..521fc4ce95f2 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -545,7 +545,7 @@ vm_pageout_flush(vm_page_t *mc, int count, int flags, int mreq, int *prunlen,
 			 * clog the laundry and inactive queues.  (We will try
 			 * paging it out again later.)
 			 */
-			if (object->type == OBJT_SWAP &&
+			if ((object->flags & OBJ_SWAP) != 0 &&
 			    pageout_status[i] == VM_PAGER_FAIL) {
 				vm_page_unswappable(mt);
 				numpagedout++;
@@ -897,7 +897,7 @@ free_page:
 			vm_page_free(m);
 			VM_CNT_INC(v_dfree);
 		} else if ((object->flags & OBJ_DEAD) == 0) {
-			if (object->type != OBJT_SWAP &&
+			if ((object->flags & OBJ_SWAP) == 0 &&
 			    object->type != OBJT_DEFAULT)
 				pageout_ok = true;
 			else if (disable_swap_pageouts)
@@ -1890,6 +1890,7 @@ vm_pageout_oom_pagecount(struct vmspace *vmspace)
 		switch (obj->type) {
 		case OBJT_DEFAULT:
 		case OBJT_SWAP:
+		case OBJT_SWAP_TMPFS:
 		case OBJT_PHYS:
 		case OBJT_VNODE:
 			res += obj->resident_page_count;
diff --git a/sys/vm/vm_pager.c b/sys/vm/vm_pager.c
index 8be344b7665b..30e84fa00a3e 100644
--- a/sys/vm/vm_pager.c
+++ b/sys/vm/vm_pager.c
@@ -172,6 +172,7 @@ struct pagerops *pagertab[] = {
 	[OBJT_DEAD] =		&deadpagerops,
 	[OBJT_SG] = 		&sgpagerops,
 	[OBJT_MGTDEVICE] = 	&mgtdevicepagerops,
+	[OBJT_SWAP_TMPFS] =	&swaptmpfspagerops,
 };
 
 void
diff --git a/sys/vm/vm_pager.h b/sys/vm/vm_pager.h
index 507123adb454..55d231a73f39 100644
--- a/sys/vm/vm_pager.h
+++ b/sys/vm/vm_pager.h
@@ -95,6 +95,7 @@ extern struct pagerops devicepagerops;
 extern struct pagerops physpagerops;
 extern struct pagerops sgpagerops;
 extern struct pagerops mgtdevicepagerops;
+extern struct pagerops swaptmpfspagerops;
 
 /*
  * get/put return values



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202105220946.14M9kXLH012522>