Date: Sat, 3 Dec 2011 23:36:36 +0000 (UTC) From: Alan Cox <alc@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r228248 - stable/8/sys/vm Message-ID: <201112032336.pB3Naamo061199@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: alc Date: Sat Dec 3 23:36:36 2011 New Revision: 228248 URL: http://svn.freebsd.org/changeset/base/228248 Log: MFC r215597 Optimize vm_object_terminate(). Modified: stable/8/sys/vm/vm_object.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) Modified: stable/8/sys/vm/vm_object.c ============================================================================== --- stable/8/sys/vm/vm_object.c Sat Dec 3 22:16:36 2011 (r228247) +++ stable/8/sys/vm/vm_object.c Sat Dec 3 23:36:36 2011 (r228248) @@ -679,7 +679,7 @@ vm_object_destroy(vm_object_t object) void vm_object_terminate(vm_object_t object) { - vm_page_t p; + vm_page_t p, p_next; VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); @@ -719,23 +719,41 @@ vm_object_terminate(vm_object_t object) object->ref_count)); /* - * Now free any remaining pages. For internal objects, this also - * removes them from paging queues. Don't free wired pages, just - * remove them from the object. + * Free any remaining pageable pages. This also removes them from the + * paging queues. However, don't free wired pages, just remove them + * from the object. Rather than incrementally removing each page from + * the object, the page and object are reset to any empty state. */ vm_page_lock_queues(); - while ((p = TAILQ_FIRST(&object->memq)) != NULL) { + TAILQ_FOREACH_SAFE(p, &object->memq, listq, p_next) { KASSERT(!p->busy && (p->oflags & VPO_BUSY) == 0, - ("vm_object_terminate: freeing busy page %p " - "p->busy = %d, p->oflags %x\n", p, p->busy, p->oflags)); + ("vm_object_terminate: freeing busy page %p", p)); + /* + * Optimize the page's removal from the object by resetting + * its "object" field. Specifically, if the page is not + * wired, then the effect of this assignment is that + * vm_page_free()'s call to vm_page_remove() will return + * immediately without modifying the page or the object. + */ + p->object = NULL; if (p->wire_count == 0) { vm_page_free(p); cnt.v_pfree++; - } else { - vm_page_remove(p); } } vm_page_unlock_queues(); + /* + * If the object contained any pages, then reset it to an empty state. + * None of the object's fields, including "resident_page_count", were + * modified by the preceding loop. + */ + if (object->resident_page_count != 0) { + object->root = NULL; + TAILQ_INIT(&object->memq); + object->resident_page_count = 0; + if (object->type == OBJT_VNODE) + vdrop(object->handle); + } #if VM_NRESERVLEVEL > 0 if (__predict_false(!LIST_EMPTY(&object->rvq)))
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201112032336.pB3Naamo061199>