Date: Sun, 1 Jan 2017 11:38:34 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r311008 - stable/11/sys/vm Message-ID: <201701011138.v01BcZRD058472@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201701011138.v01BcZRD058472>