svn commit: r254719 - head/sys/vm
Alan Cox
alc at FreeBSD.org
Fri Aug 23 17:27:13 UTC 2013
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);
More information about the svn-src-head
mailing list