From owner-svn-src-user@FreeBSD.ORG Wed Feb 6 14:29:06 2013 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 9128828E; Wed, 6 Feb 2013 14:29:06 +0000 (UTC) (envelope-from attilio@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 754DEE6B; Wed, 6 Feb 2013 14:29:06 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id r16ET6WX043721; Wed, 6 Feb 2013 14:29:06 GMT (envelope-from attilio@svn.freebsd.org) Received: (from attilio@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id r16ET5xn043716; Wed, 6 Feb 2013 14:29:05 GMT (envelope-from attilio@svn.freebsd.org) Message-Id: <201302061429.r16ET5xn043716@svn.freebsd.org> From: Attilio Rao Date: Wed, 6 Feb 2013 14:29:05 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r246407 - in user/attilio/vmc-playground/sys: fs/tmpfs vm X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 06 Feb 2013 14:29:06 -0000 Author: attilio Date: Wed Feb 6 14:29:05 2013 New Revision: 246407 URL: http://svnweb.freebsd.org/changeset/base/246407 Log: Reduce diffs against HEAD: Reimplement vm_page_cache_free() as a range operation. Modified: user/attilio/vmc-playground/sys/fs/tmpfs/tmpfs_vnops.c user/attilio/vmc-playground/sys/vm/vm_object.c user/attilio/vmc-playground/sys/vm/vm_page.c user/attilio/vmc-playground/sys/vm/vm_page.h user/attilio/vmc-playground/sys/vm/vnode_pager.c Modified: user/attilio/vmc-playground/sys/fs/tmpfs/tmpfs_vnops.c ============================================================================== --- user/attilio/vmc-playground/sys/fs/tmpfs/tmpfs_vnops.c Wed Feb 6 13:55:02 2013 (r246406) +++ user/attilio/vmc-playground/sys/fs/tmpfs/tmpfs_vnops.c Wed Feb 6 14:29:05 2013 (r246407) @@ -670,13 +670,8 @@ lookupvpg: VM_OBJECT_UNLOCK(vobj); error = uiomove_fromphys(&vpg, offset, tlen, uio); } else { - vpg = vm_page_is_cached(vobj, idx); - if (vpg != NULL) { - mtx_lock(&vm_page_queue_free_mtx); - if (vpg->object == vobj) - vm_page_cache_free(vpg); - mtx_unlock(&vm_page_queue_free_mtx); - } + if (vm_page_is_cached(vobj, idx)) + vm_page_cache_free(vobj, idx, idx + 1); VM_OBJECT_UNLOCK(vobj); vpg = NULL; } Modified: user/attilio/vmc-playground/sys/vm/vm_object.c ============================================================================== --- user/attilio/vmc-playground/sys/vm/vm_object.c Wed Feb 6 13:55:02 2013 (r246406) +++ user/attilio/vmc-playground/sys/vm/vm_object.c Wed Feb 6 14:29:05 2013 (r246407) @@ -674,8 +674,6 @@ void vm_object_terminate(vm_object_t object) { vm_page_t p, p_next; - vm_pindex_t start; - struct vnode *vp; VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); @@ -739,38 +737,6 @@ vm_object_terminate(vm_object_t object) vm_page_unlock(p); } vm_radix_reclaim_allnodes(&object->rtree); - vp = NULL; - if (!vm_object_cache_is_empty(object)) { - start = 0; - mtx_lock(&vm_page_queue_free_mtx); - while ((p = vm_radix_lookup_ge(&object->cache, - start)) != NULL) { - MPASS(p->object == object); - p->object = NULL; - p->valid = 0; - - /* Clear PG_CACHED and set PG_FREE. */ - p->flags ^= PG_CACHED | PG_FREE; - cnt.v_cache_count--; - cnt.v_free_count++; - - /* - * At least one cached page was removed and - * in the end all the cached pages will be - * reclaimed. If the object is a vnode, - * drop a reference to it. - */ - if (object->type == OBJT_VNODE) - vp = object->handle; - - /* Point to the next available index. */ - start = p->pindex + 1; - if (start < p->pindex) - break; - } - vm_radix_reclaim_allnodes(&object->cache); - mtx_unlock(&vm_page_queue_free_mtx); - } /* * If the object contained any pages, then reset it to an empty state. * None of the object's fields, including "resident_page_count", were @@ -782,13 +748,13 @@ vm_object_terminate(vm_object_t object) if (object->type == OBJT_VNODE) vdrop(object->handle); } - if (vp) - vdrop(vp); #if VM_NRESERVLEVEL > 0 if (__predict_false(!LIST_EMPTY(&object->rvq))) vm_reserv_break_all(object); #endif + if (!vm_object_cache_is_empty(object)) + vm_page_cache_free(object, 0, 0); /* * Let the pager know object is dead. @@ -1679,9 +1645,6 @@ vm_object_qcollapse(vm_object_t object) void vm_object_collapse(vm_object_t object) { - vm_page_t p; - vm_pindex_t start, tmpindex; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); while (TRUE) { @@ -1762,30 +1725,11 @@ vm_object_collapse(vm_object_t object) object, OFF_TO_IDX(object->backing_object_offset), TRUE); - if (!vm_object_cache_is_empty(backing_object)) { - - /* - * Free any cached pages from - * backing_object. - */ - start = 0; - mtx_lock(&vm_page_queue_free_mtx); - while ((p = - vm_radix_lookup_ge(&backing_object->cache, - start)) != NULL) { - tmpindex = p->pindex; - vm_page_cache_free(p); - - /* - * Point to the next available - * index. - */ - start = tmpindex + 1; - if (start < tmpindex) - break; - } - mtx_unlock(&vm_page_queue_free_mtx); - } + /* + * Free any cached pages from backing_object. + */ + if (!vm_object_cache_is_empty(object)) + vm_page_cache_free(backing_object, 0, 0); } /* * Object now shadows whatever backing_object did. @@ -1906,7 +1850,6 @@ void vm_object_page_remove(vm_object_t object, vm_pindex_t start, vm_pindex_t end, int options) { - struct vnode *vp; vm_page_t p, next; int wirings; @@ -1914,11 +1857,8 @@ vm_object_page_remove(vm_object_t object KASSERT((object->flags & OBJ_UNMANAGED) == 0 || (options & (OBJPR_CLEANONLY | OBJPR_NOTMAPPED)) == OBJPR_NOTMAPPED, ("vm_object_page_remove: illegal options for object %p", object)); - if (object->resident_page_count == 0) { - if (vm_object_cache_is_empty(object)) - return; + if (object->resident_page_count == 0) goto skipmemq; - } vm_object_pip_add(object, 1); again: p = vm_page_find_least(object, start); @@ -1990,22 +1930,8 @@ again: } vm_object_pip_wakeup(object); skipmemq: - vp = NULL; - if (!vm_object_cache_is_empty(object)) { - mtx_lock(&vm_page_queue_free_mtx); - while ((p = vm_radix_lookup_ge(&object->cache, - start)) != NULL) { - if (p->pindex >= end) - break; - vm_page_cache_free(p); - if (vm_object_cache_is_empty(object) && - object->type == OBJT_VNODE) - vp = object->handle; - } - mtx_unlock(&vm_page_queue_free_mtx); - } - if (vp) - vdrop(vp); + if (!vm_object_cache_is_empty(object)) + vm_page_cache_free(object, start, end); } /* Modified: user/attilio/vmc-playground/sys/vm/vm_page.c ============================================================================== --- user/attilio/vmc-playground/sys/vm/vm_page.c Wed Feb 6 13:55:02 2013 (r246406) +++ user/attilio/vmc-playground/sys/vm/vm_page.c Wed Feb 6 14:29:05 2013 (r246407) @@ -999,6 +999,47 @@ vm_page_rename(vm_page_t m, vm_object_t } /* + * Convert all of the given object's cached pages that have a + * pindex within the given range into free pages. If the value + * zero is given for "end", then the range's upper bound is + * infinity. If the given object is backed by a vnode and it + * transitions from having one or more cached pages to none, the + * vnode's hold count is reduced. + */ +void +vm_page_cache_free(vm_object_t object, vm_pindex_t start, vm_pindex_t end) +{ + vm_page_t m; + boolean_t empty; + + VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + + mtx_lock(&vm_page_queue_free_mtx); + if (vm_object_cache_is_empty(object)) { + mtx_unlock(&vm_page_queue_free_mtx); + return; + } + while ((m = vm_radix_lookup_ge(&object->cache, start)) != NULL) { + if (end != 0 && m->pindex >= end) + break; + vm_radix_remove(&object->cache, m->pindex); + m->object = NULL; + m->valid = 0; + + /* Clear PG_CACHED and set PG_FREE. */ + m->flags ^= PG_CACHED | PG_FREE; + KASSERT((m->flags & (PG_CACHED | PG_FREE)) == PG_FREE, + ("vm_page_cache_free: page %p has inconsistent flags", m)); + cnt.v_cache_count--; + cnt.v_free_count++; + } + empty = vm_object_cache_is_empty(object); + mtx_unlock(&vm_page_queue_free_mtx); + if (object->type == OBJT_VNODE && empty) + vdrop(object->handle); +} + +/* * Returns the cached page that is associated with the given * object and offset. If, however, none exists, returns NULL. * @@ -1034,36 +1075,6 @@ vm_page_cache_remove(vm_page_t m) } /* - * Move a given cached page from an object's cached pages to - * the free list. - * - * The free page queue mtx and object lock must be locked. - */ -void -vm_page_cache_free(vm_page_t m) -{ - vm_object_t object; - - object = m->object; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); - mtx_assert(&vm_page_queue_free_mtx, MA_OWNED); - KASSERT((m->flags & PG_CACHED) != 0, - ("vm_page_cache_free: page %p is not cached", m)); - - /* - * Replicate vm_page_cache_remove with a version that can collapse - * internal nodes since the object lock is held. - */ - vm_radix_remove(&object->cache, m->pindex); - m->object = NULL; - m->valid = 0; - /* Clear PG_CACHED and set PG_FREE. */ - m->flags ^= PG_CACHED | PG_FREE; - cnt.v_cache_count--; - cnt.v_free_count++; -} - -/* * Transfer all of the cached pages with offset greater than or * equal to 'offidxstart' from the original object's cache to the * new object's cache. However, any cached pages with offset Modified: user/attilio/vmc-playground/sys/vm/vm_page.h ============================================================================== --- user/attilio/vmc-playground/sys/vm/vm_page.h Wed Feb 6 13:55:02 2013 (r246406) +++ user/attilio/vmc-playground/sys/vm/vm_page.h Wed Feb 6 14:29:05 2013 (r246407) @@ -376,8 +376,8 @@ vm_page_t vm_page_alloc_contig(vm_object vm_page_t vm_page_alloc_freelist(int, int); vm_page_t vm_page_grab (vm_object_t, vm_pindex_t, int); void vm_page_cache(vm_page_t); +void vm_page_cache_free(vm_object_t, vm_pindex_t, vm_pindex_t); void vm_page_cache_transfer(vm_object_t, vm_pindex_t, vm_object_t); -void vm_page_cache_free(vm_page_t); int vm_page_try_to_cache (vm_page_t); int vm_page_try_to_free (vm_page_t); void vm_page_dontneed(vm_page_t); Modified: user/attilio/vmc-playground/sys/vm/vnode_pager.c ============================================================================== --- user/attilio/vmc-playground/sys/vm/vnode_pager.c Wed Feb 6 13:55:02 2013 (r246406) +++ user/attilio/vmc-playground/sys/vm/vnode_pager.c Wed Feb 6 14:29:05 2013 (r246407) @@ -373,7 +373,6 @@ vnode_pager_setsize(vp, nsize) vm_ooffset_t nsize; { vm_object_t object; - struct vnode *drop; vm_page_t m; vm_pindex_t nobjsize; @@ -439,23 +438,9 @@ vnode_pager_setsize(vp, nsize) */ vm_page_clear_dirty(m, base, PAGE_SIZE - base); } else if ((nsize & PAGE_MASK) && - (m = vm_page_is_cached(object, - OFF_TO_IDX(nsize))) != NULL) { - drop = NULL; - mtx_lock(&vm_page_queue_free_mtx); - if (m->object == object) { - - /* - * Eliminate any cached page as we would have - * to do too much work to save it. - */ - vm_page_cache_free(m); - if (vm_object_cache_is_empty(object)) - drop = vp; - } - mtx_unlock(&vm_page_queue_free_mtx); - if (drop) - vdrop(drop); + vm_page_is_cached(object, OFF_TO_IDX(nsize))) { + vm_page_cache_free(object, OFF_TO_IDX(nsize), + nobjsize); } } object->un_pager.vnp.vnp_size = nsize;