svn commit: r311008 - stable/11/sys/vm
Konstantin Belousov
kib at FreeBSD.org
Sun Jan 1 11:38:36 UTC 2017
Author: kib
Date: Sun Jan 1 11:38:34 2017
New Revision: 311008
URL: https://svnweb.freebsd.org/changeset/base/311008
Log:
MFC r310234:
Improve vm_object_scan_all_shadowed() to also check swap backing objects.
Modified:
stable/11/sys/vm/swap_pager.c
stable/11/sys/vm/swap_pager.h
stable/11/sys/vm/vm_object.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/vm/swap_pager.c
==============================================================================
--- stable/11/sys/vm/swap_pager.c Sun Jan 1 11:19:17 2017 (r311007)
+++ stable/11/sys/vm/swap_pager.c Sun Jan 1 11:38:34 2017 (r311008)
@@ -2010,6 +2010,44 @@ swp_pager_meta_ctl(vm_object_t object, v
}
/*
+ * 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 object's size if the object's type is not swap or if there
+ * are no allocated swap blocks for the object after the requested
+ * pindex.
+ */
+vm_pindex_t
+swap_pager_find_least(vm_object_t object, vm_pindex_t pindex)
+{
+ struct swblock **pswap, *swap;
+ vm_pindex_t i, j, lim;
+ int idx;
+
+ VM_OBJECT_ASSERT_LOCKED(object);
+ if (object->type != OBJT_SWAP || object->un_pager.swp.swp_bcount == 0)
+ return (object->size);
+
+ mtx_lock(&swhash_mtx);
+ for (j = pindex; j < object->size; j = lim) {
+ pswap = swp_pager_hash(object, j);
+ lim = rounddown2(j + SWAP_META_PAGES, SWAP_META_PAGES);
+ if (lim > object->size)
+ lim = object->size;
+ if ((swap = *pswap) != NULL) {
+ for (idx = j & SWAP_META_MASK, i = j; i < lim;
+ i++, idx++) {
+ if (swap->swb_pages[idx] != SWAPBLK_NONE)
+ goto found;
+ }
+ }
+ }
+ i = object->size;
+found:
+ mtx_unlock(&swhash_mtx);
+ return (i);
+}
+
+/*
* System call swapon(name) enables swapping on device name,
* which must be in the swdevsw. Return EBUSY
* if already swapping on this device.
Modified: stable/11/sys/vm/swap_pager.h
==============================================================================
--- stable/11/sys/vm/swap_pager.h Sun Jan 1 11:19:17 2017 (r311007)
+++ stable/11/sys/vm/swap_pager.h Sun Jan 1 11:38:34 2017 (r311008)
@@ -79,6 +79,7 @@ extern int swap_pager_avail;
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, vm_pindex_t, vm_size_t);
void swap_pager_swap_init(void);
int swap_pager_isswapped(vm_object_t, struct swdevt *);
Modified: stable/11/sys/vm/vm_object.c
==============================================================================
--- stable/11/sys/vm/vm_object.c Sun Jan 1 11:19:17 2017 (r311007)
+++ stable/11/sys/vm/vm_object.c Sun Jan 1 11:38:34 2017 (r311008)
@@ -1464,36 +1464,40 @@ vm_object_scan_all_shadowed(vm_object_t
{
vm_object_t backing_object;
vm_page_t p, pp;
- vm_pindex_t backing_offset_index, new_pindex;
+ vm_pindex_t backing_offset_index, new_pindex, pi, ps;
VM_OBJECT_ASSERT_WLOCKED(object);
VM_OBJECT_ASSERT_WLOCKED(object->backing_object);
backing_object = object->backing_object;
- /*
- * Initial conditions:
- *
- * We do not want to have to test for the existence of cache or swap
- * pages in the backing object. XXX but with the new swapper this
- * would be pretty easy to do.
- */
- if (backing_object->type != OBJT_DEFAULT)
+ if (backing_object->type != OBJT_DEFAULT &&
+ backing_object->type != OBJT_SWAP)
return (false);
- backing_offset_index = OFF_TO_IDX(object->backing_object_offset);
+ pi = backing_offset_index = OFF_TO_IDX(object->backing_object_offset);
+ p = vm_page_find_least(backing_object, pi);
+ ps = swap_pager_find_least(backing_object, pi);
- for (p = TAILQ_FIRST(&backing_object->memq); p != NULL;
- p = TAILQ_NEXT(p, listq)) {
- new_pindex = p->pindex - backing_offset_index;
+ /*
+ * Only check pages inside the parent object's range and
+ * inside the parent object's mapping of the backing object.
+ */
+ for (;; pi++) {
+ if (p != NULL && p->pindex < pi)
+ p = TAILQ_NEXT(p, listq);
+ if (ps < pi)
+ ps = swap_pager_find_least(backing_object, pi);
+ if (p == NULL && ps >= backing_object->size)
+ break;
+ else if (p == NULL)
+ pi = ps;
+ else
+ pi = MIN(p->pindex, ps);
- /*
- * Ignore pages outside the parent object's range and outside
- * the parent object's mapping of the backing object.
- */
- if (p->pindex < backing_offset_index ||
- new_pindex >= object->size)
- continue;
+ new_pindex = pi - backing_offset_index;
+ if (new_pindex >= object->size)
+ break;
/*
* See if the parent has the page or if the parent's object
More information about the svn-src-stable
mailing list