git: baa1ccceefdf - main - Make swap_pager_freespace() global

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Fri, 09 Dec 2022 12:17:35 UTC
The branch main has been updated by kib:

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

commit baa1ccceefdf4954a88e54ca18c6ab1762faa326
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2022-10-26 22:13:27 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2022-12-09 12:15:37 +0000

    Make swap_pager_freespace() global
    
    also make it return the count of the swap pages freed, which are not
    simultaneously resident in the object.
    
    Reviewed by:    markj
    Tested by:      pho
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D37097
---
 sys/vm/swap_pager.c | 54 +++++++++++++++++++++++++++++++++++++++++------------
 sys/vm/swap_pager.h |  2 ++
 2 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index bcf9a24d400d..163e0c42d30d 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -436,7 +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_freespace(vm_object_t object, vm_pindex_t start,
+static void	swap_pager_freespace_pgo(vm_object_t object, vm_pindex_t start,
     vm_size_t size);
 
 const struct pagerops swappagerops = {
@@ -451,7 +451,7 @@ const 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_freespace = swap_pager_freespace,
+	.pgo_freespace = swap_pager_freespace_pgo,
 };
 
 /*
@@ -483,9 +483,10 @@ static daddr_t	swp_pager_getswapspace(int *npages);
  * Metadata functions
  */
 static daddr_t swp_pager_meta_build(vm_object_t, vm_pindex_t, daddr_t);
-static void swp_pager_meta_free(vm_object_t, vm_pindex_t, vm_pindex_t);
+static void swp_pager_meta_free(vm_object_t, vm_pindex_t, vm_size_t,
+    vm_size_t *);
 static void swp_pager_meta_transfer(vm_object_t src, vm_object_t dst,
-    vm_pindex_t pindex, vm_pindex_t count);
+    vm_pindex_t pindex, vm_pindex_t count, vm_size_t *freed);
 static void swp_pager_meta_free_all(vm_object_t);
 static daddr_t swp_pager_meta_lookup(vm_object_t, vm_pindex_t);
 
@@ -980,11 +981,21 @@ sysctl_swap_fragmentation(SYSCTL_HANDLER_ARGS)
  *
  *	The object must be locked.
  */
+void
+swap_pager_freespace(vm_object_t object, vm_pindex_t start, vm_size_t size,
+    vm_size_t *freed)
+{
+	MPASS((object->flags & OBJ_SWAP) != 0);
+
+	swp_pager_meta_free(object, start, size, freed);
+}
+
 static void
-swap_pager_freespace(vm_object_t object, vm_pindex_t start, vm_size_t size)
+swap_pager_freespace_pgo(vm_object_t object, vm_pindex_t start, vm_size_t size)
 {
+	MPASS((object->flags & OBJ_SWAP) != 0);
 
-	swp_pager_meta_free(object, start, size);
+	swp_pager_meta_free(object, start, size, NULL);
 }
 
 /*
@@ -1008,7 +1019,7 @@ swap_pager_reserve(vm_object_t object, vm_pindex_t start, vm_pindex_t size)
 		n = MIN(size - i, INT_MAX);
 		blk = swp_pager_getswapspace(&n);
 		if (blk == SWAPBLK_NONE) {
-			swp_pager_meta_free(object, start, i);
+			swp_pager_meta_free(object, start, i, NULL);
 			VM_OBJECT_WUNLOCK(object);
 			return (-1);
 		}
@@ -1096,7 +1107,8 @@ swap_pager_copy(vm_object_t srcobject, vm_object_t dstobject,
 	/*
 	 * Transfer source to destination.
 	 */
-	swp_pager_meta_transfer(srcobject, dstobject, offset, dstobject->size);
+	swp_pager_meta_transfer(srcobject, dstobject, offset, dstobject->size,
+	    NULL);
 
 	/*
 	 * Free left over swap blocks in source.
@@ -2119,16 +2131,22 @@ allocated:
  */
 static void
 swp_pager_meta_transfer(vm_object_t srcobject, vm_object_t dstobject,
-    vm_pindex_t pindex, vm_pindex_t count)
+    vm_pindex_t pindex, vm_pindex_t count, vm_size_t *moved)
 {
 	struct swblk *sb;
+	vm_page_t m;
 	daddr_t n_free, s_free;
 	vm_pindex_t offset, last;
+	vm_size_t mc;
 	int i, limit, start;
 
 	VM_OBJECT_ASSERT_WLOCKED(srcobject);
+	MPASS(moved == NULL || dstobject == NULL);
+
+	mc = 0;
+	m = NULL;
 	if (count == 0 || pctrie_is_empty(&srcobject->un_pager.swp.swp_blks))
-		return;
+		goto out;
 
 	swp_pager_init_freerange(&s_free, &n_free);
 	offset = pindex;
@@ -2150,6 +2168,14 @@ swp_pager_meta_transfer(vm_object_t srcobject, vm_object_t dstobject,
 				swp_pager_update_freerange(&s_free, &n_free,
 				    sb->d[i]);
 			}
+			if (moved != NULL) {
+				if (m != NULL && m->pindex != pindex + i - 1)
+					m = NULL;
+				m = m != NULL ? vm_page_next(m) :
+				    vm_page_lookup(srcobject, pindex + i);
+				if (m == NULL || vm_page_none_valid(m))
+					mc++;
+			}
 			sb->d[i] = SWAPBLK_NONE;
 		}
 		pindex = sb->p + SWAP_META_PAGES;
@@ -2161,6 +2187,9 @@ swp_pager_meta_transfer(vm_object_t srcobject, vm_object_t dstobject,
 		}
 	}
 	swp_pager_freeswapspace(s_free, n_free);
+out:
+	if (moved != NULL)
+		*moved = mc;
 }
 
 /*
@@ -2174,9 +2203,10 @@ swp_pager_meta_transfer(vm_object_t srcobject, vm_object_t dstobject,
  *	with resident pages.
  */
 static void
-swp_pager_meta_free(vm_object_t object, vm_pindex_t pindex, vm_pindex_t count)
+swp_pager_meta_free(vm_object_t object, vm_pindex_t pindex, vm_pindex_t count,
+    vm_size_t *freed)
 {
-	swp_pager_meta_transfer(object, NULL, pindex, count);
+	swp_pager_meta_transfer(object, NULL, pindex, count, freed);
 }
 
 /*
diff --git a/sys/vm/swap_pager.h b/sys/vm/swap_pager.h
index 395fbc9957c4..58fd98c3e452 100644
--- a/sys/vm/swap_pager.h
+++ b/sys/vm/swap_pager.h
@@ -78,6 +78,8 @@ struct xswdev;
 int swap_dev_info(int name, struct xswdev *xs, char *devname, size_t len);
 void swap_pager_copy(vm_object_t, vm_object_t, vm_pindex_t, int);
 vm_pindex_t swap_pager_find_least(vm_object_t object, vm_pindex_t pindex);
+void swap_pager_freespace(vm_object_t object, vm_pindex_t start,
+    vm_size_t size, vm_size_t *freed);
 void swap_pager_swap_init(void);
 int swap_pager_nswapdev(void);
 int swap_pager_reserve(vm_object_t, vm_pindex_t, vm_pindex_t);