From owner-svn-src-head@FreeBSD.ORG Fri Aug 23 17:27:13 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id D8687A53; Fri, 23 Aug 2013 17:27:13 +0000 (UTC) (envelope-from alc@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id ABF4D25C8; Fri, 23 Aug 2013 17:27:13 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r7NHRDHl077454; Fri, 23 Aug 2013 17:27:13 GMT (envelope-from alc@svn.freebsd.org) Received: (from alc@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r7NHRDUI077451; Fri, 23 Aug 2013 17:27:13 GMT (envelope-from alc@svn.freebsd.org) Message-Id: <201308231727.r7NHRDUI077451@svn.freebsd.org> From: Alan Cox Date: Fri, 23 Aug 2013 17:27:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r254719 - head/sys/vm X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 23 Aug 2013 17:27:13 -0000 Author: alc Date: Fri Aug 23 17:27:12 2013 New Revision: 254719 URL: http://svnweb.freebsd.org/changeset/base/254719 Log: Addendum to r254141: The call to vm_radix_insert() in vm_page_cache() can reclaim the last preexisting cached page in the object, resulting in a call to vdrop(). Detect this scenario so that the vnode's hold count is correctly maintained. Otherwise, we panic. Reported by: scottl Tested by: pho Discussed with: attilio, jeff, kib Modified: head/sys/vm/vm_page.c head/sys/vm/vm_radix.c head/sys/vm/vm_radix.h Modified: head/sys/vm/vm_page.c ============================================================================== --- head/sys/vm/vm_page.c Fri Aug 23 17:03:43 2013 (r254718) +++ head/sys/vm/vm_page.c Fri Aug 23 17:27:12 2013 (r254719) @@ -2558,6 +2558,15 @@ vm_page_cache(vm_page_t m) vm_page_free(m); return; } + + /* + * The above call to vm_radix_insert() could reclaim the one pre- + * existing cached page from this object, resulting in a call to + * vdrop(). + */ + if (!cache_was_empty) + cache_was_empty = vm_radix_is_singleton(&object->cache); + m->flags |= PG_CACHED; cnt.v_cache_count++; PCPU_INC(cnt.v_tcached); Modified: head/sys/vm/vm_radix.c ============================================================================== --- head/sys/vm/vm_radix.c Fri Aug 23 17:03:43 2013 (r254718) +++ head/sys/vm/vm_radix.c Fri Aug 23 17:27:12 2013 (r254719) @@ -432,6 +432,21 @@ restart: } /* + * Returns TRUE if the specified radix tree contains a single leaf and FALSE + * otherwise. + */ +boolean_t +vm_radix_is_singleton(struct vm_radix *rtree) +{ + struct vm_radix_node *rnode; + + rnode = vm_radix_getroot(rtree); + if (rnode == NULL) + return (FALSE); + return (vm_radix_isleaf(rnode)); +} + +/* * Returns the value stored at the index. If the index is not present, * NULL is returned. */ Modified: head/sys/vm/vm_radix.h ============================================================================== --- head/sys/vm/vm_radix.h Fri Aug 23 17:03:43 2013 (r254718) +++ head/sys/vm/vm_radix.h Fri Aug 23 17:27:12 2013 (r254719) @@ -37,6 +37,7 @@ void vm_radix_init(void); int vm_radix_insert(struct vm_radix *rtree, vm_page_t page); +boolean_t vm_radix_is_singleton(struct vm_radix *rtree); vm_page_t vm_radix_lookup(struct vm_radix *rtree, vm_pindex_t index); vm_page_t vm_radix_lookup_ge(struct vm_radix *rtree, vm_pindex_t index); vm_page_t vm_radix_lookup_le(struct vm_radix *rtree, vm_pindex_t index);