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);
|
vm_page_free(m);
|
||||||
return;
|
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;
|
m->flags |= PG_CACHED;
|
||||||
cnt.v_cache_count++;
|
cnt.v_cache_count++;
|
||||||
PCPU_INC(cnt.v_tcached);
|
PCPU_INC(cnt.v_tcached);
|
||||||
|
@ -431,6 +431,21 @@ restart:
|
|||||||
return (0);
|
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,
|
* Returns the value stored at the index. If the index is not present,
|
||||||
* NULL is returned.
|
* NULL is returned.
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
|
|
||||||
void vm_radix_init(void);
|
void vm_radix_init(void);
|
||||||
int vm_radix_insert(struct vm_radix *rtree, vm_page_t page);
|
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(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_ge(struct vm_radix *rtree, vm_pindex_t index);
|
||||||
vm_page_t vm_radix_lookup_le(struct vm_radix *rtree, vm_pindex_t index);
|
vm_page_t vm_radix_lookup_le(struct vm_radix *rtree, vm_pindex_t index);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user