git: db08b0b04dec - main - tmpfs_vnops: move swap work to swap_pager
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 24 Oct 2024 19:26:05 UTC
The branch main has been updated by dougm:
URL: https://cgit.FreeBSD.org/src/commit/?id=db08b0b04deced766c3b5f07bcfb82333666226c
commit db08b0b04deced766c3b5f07bcfb82333666226c
Author: Doug Moore <dougm@FreeBSD.org>
AuthorDate: 2024-10-24 19:24:49 +0000
Commit: Doug Moore <dougm@FreeBSD.org>
CommitDate: 2024-10-24 19:24:49 +0000
tmpfs_vnops: move swap work to swap_pager
Two functions in tmpfs_vnops.c use an interface provided by
swap_pager.c. Move most of the implementation of those functions to
swap_pager.c so that they can be implemented more effectively, with
access to implementation details of the swap pager.
Reviewed by: kib
Differential Revision: https://reviews.freebsd.org/D47212
---
sys/fs/tmpfs/tmpfs_vnops.c | 60 ++++------------------------------------------
sys/vm/swap_pager.c | 58 +++++++++++++++++++++++++++++++++++++++-----
sys/vm/swap_pager.h | 3 ++-
3 files changed, 58 insertions(+), 63 deletions(-)
diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c
index c2559a61fe37..428c31f3c59a 100644
--- a/sys/fs/tmpfs/tmpfs_vnops.c
+++ b/sys/fs/tmpfs/tmpfs_vnops.c
@@ -2092,40 +2092,10 @@ tmpfs_setextattr(struct vop_setextattr_args *ap)
static off_t
tmpfs_seek_data_locked(vm_object_t obj, off_t noff)
{
- vm_page_t m;
- vm_pindex_t p, p_swp;
+ vm_pindex_t p;
- p = OFF_TO_IDX(noff);
- m = vm_page_find_least(obj, p);
-
- /*
- * Microoptimize the most common case for SEEK_DATA, where
- * there is no hole and the page is resident.
- */
- if (m != NULL && m->pindex == p && vm_page_any_valid(m))
- return (noff);
-
- p_swp = swap_pager_find_least(obj, p);
- if (p_swp == p)
- return (noff);
-
- /*
- * Find the first resident page after p, before p_swp.
- */
- while (m != NULL && m->pindex < p_swp) {
- if (vm_page_any_valid(m))
- return (IDX_TO_OFF(m->pindex));
- m = TAILQ_NEXT(m, listq);
- }
- if (p_swp == OBJ_MAX_SIZE)
- p_swp = obj->size;
- return (IDX_TO_OFF(p_swp));
-}
-
-static off_t
-tmpfs_seek_next(off_t noff)
-{
- return (noff + PAGE_SIZE - (noff & PAGE_MASK));
+ p = swap_pager_seek_data(obj, OFF_TO_IDX(noff));
+ return (p == OFF_TO_IDX(noff) ? noff : IDX_TO_OFF(p));
}
static int
@@ -2142,30 +2112,8 @@ tmpfs_seek_clamp(struct tmpfs_node *tn, off_t *noff, bool seekdata)
static off_t
tmpfs_seek_hole_locked(vm_object_t obj, off_t noff)
{
- vm_page_t m;
- vm_pindex_t p, p_swp;
-
- for (;; noff = tmpfs_seek_next(noff)) {
- /*
- * Walk over the largest sequential run of the valid pages.
- */
- for (m = vm_page_lookup(obj, OFF_TO_IDX(noff));
- m != NULL && vm_page_any_valid(m);
- m = vm_page_next(m), noff = tmpfs_seek_next(noff))
- ;
- /*
- * Found a hole in the object's page queue. Check if
- * there is a hole in the swap at the same place.
- */
- p = OFF_TO_IDX(noff);
- p_swp = swap_pager_find_least(obj, p);
- if (p_swp != p) {
- noff = IDX_TO_OFF(p);
- break;
- }
- }
- return (noff);
+ return (IDX_TO_OFF(swap_pager_seek_hole(obj, OFF_TO_IDX(noff))));
}
static int
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index 5eccc621bdae..90d44d3e7402 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -111,6 +111,7 @@
#include <vm/vm_pager.h>
#include <vm/vm_pageout.h>
#include <vm/vm_param.h>
+#include <vm/vm_radix.h>
#include <vm/swap_pager.h>
#include <vm/vm_extern.h>
#include <vm/uma.h>
@@ -2476,17 +2477,62 @@ swap_pager_iter_find_least(struct pctrie_iter *blks, vm_pindex_t pindex)
}
/*
- * Returns the least page index which is greater than or equal to the parameter
- * pindex and for which there is a swap block allocated. Returns OBJ_MAX_SIZE
- * if are no allocated swap blocks for the object after the requested pindex.
+ * Find the first index >= pindex that has either a valid page or a swap
+ * block.
*/
vm_pindex_t
-swap_pager_find_least(vm_object_t object, vm_pindex_t pindex)
+swap_pager_seek_data(vm_object_t object, vm_pindex_t pindex)
{
- struct pctrie_iter blks;
+ struct pctrie_iter blks, pages;
+ vm_page_t m;
+ vm_pindex_t swap_index;
+
+ VM_OBJECT_ASSERT_WLOCKED(object);
+ vm_page_iter_init(&pages, object);
+ m = vm_page_iter_lookup_ge(&pages, pindex);
+ if (m != NULL) {
+ if (!vm_page_any_valid(m))
+ m = NULL;
+ else if (pages.index == pindex)
+ return (pages.index);
+ }
+ swblk_iter_init_only(&blks, object);
+ swap_index = swap_pager_iter_find_least(&blks, pindex);
+ if (swap_index == pindex)
+ return (swap_index);
+ if (swap_index == OBJ_MAX_SIZE)
+ swap_index = object->size;
+ if (m == NULL)
+ return (swap_index);
+
+ while ((m = vm_radix_iter_step(&pages)) != NULL &&
+ pages.index < swap_index) {
+ if (vm_page_any_valid(m))
+ return (pages.index);
+ }
+ return (swap_index);
+}
+
+/*
+ * Find the first index >= pindex that has neither a valid page nor a swap
+ * block.
+ */
+vm_pindex_t
+swap_pager_seek_hole(vm_object_t object, vm_pindex_t pindex)
+{
+ struct pctrie_iter blks, pages;
+ struct swblk *sb;
+ vm_page_t m;
+ VM_OBJECT_ASSERT_WLOCKED(object);
+ vm_page_iter_init(&pages, object);
swblk_iter_init_only(&blks, object);
- return (swap_pager_iter_find_least(&blks, pindex));
+ while (((m = vm_page_iter_lookup(&pages, pindex)) != NULL &&
+ vm_page_any_valid(m)) ||
+ ((sb = swblk_iter_lookup(&blks, pindex)) != NULL &&
+ sb->d[pindex % SWAP_META_PAGES] != SWAPBLK_NONE))
+ pindex++;
+ return (pindex);
}
/*
diff --git a/sys/vm/swap_pager.h b/sys/vm/swap_pager.h
index ade94802b963..3287886026f7 100644
--- a/sys/vm/swap_pager.h
+++ b/sys/vm/swap_pager.h
@@ -74,8 +74,9 @@ extern int nsw_cluster_max;
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);
bool swap_pager_scan_all_shadowed(vm_object_t object);
+vm_pindex_t swap_pager_seek_data(vm_object_t object, vm_pindex_t pindex);
+vm_pindex_t swap_pager_seek_hole(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);