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
This commit is contained in:
parent
e9e439afa6
commit
1a535523cd
@ -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);
|
||||
|
@ -431,6 +431,21 @@ vm_radix_insert(struct vm_radix *rtree, vm_page_t page)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user