Page MenuHomeFreeBSD

D47212.diff
No OneTemporary

D47212.diff

diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c
--- a/sys/fs/tmpfs/tmpfs_vnops.c
+++ b/sys/fs/tmpfs/tmpfs_vnops.c
@@ -2092,40 +2092,10 @@
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 @@
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.h b/sys/vm/swap_pager.h
--- a/sys/vm/swap_pager.h
+++ b/sys/vm/swap_pager.h
@@ -74,8 +74,9 @@
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);
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
--- 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 @@
}
/*
- * 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);
}
/*

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 22, 4:01 PM (7 h, 26 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14771899
Default Alt Text
D47212.diff (4 KB)

Event Timeline