vfs: fix vlrureclaim ->v_object access
The routine was checking for ->v_type == VBAD. Since vgone drops the interlock early sets this type at the end of the process of dooming a vnode, this opens a time window where it can clear the pointer while the inerlock-holders is accessing it. Another note is that the code was: (vp->v_object != NULL && vp->v_object->resident_page_count > trigger) With the compiler being fully allowed to emit another read to get the pointer, and in fact it did on the kernel used by pho. Use atomic_load_ptr and remember the result. Note that this depends on type-safety of vm_object. Reported by: pho
This commit is contained in:
parent
c615009461
commit
3403d5245e
@ -1100,6 +1100,7 @@ vlrureclaim(bool reclaim_nc_src, int trigger, u_long target)
|
||||
{
|
||||
struct vnode *vp, *mvp;
|
||||
struct mount *mp;
|
||||
struct vm_object *object;
|
||||
u_long done;
|
||||
bool retried;
|
||||
|
||||
@ -1137,12 +1138,17 @@ restart:
|
||||
|
||||
if (vp->v_usecount > 0 || vp->v_holdcnt == 0 ||
|
||||
(!reclaim_nc_src && !LIST_EMPTY(&vp->v_cache_src)) ||
|
||||
vp->v_type == VBAD || vp->v_type == VNON ||
|
||||
(vp->v_object != NULL &&
|
||||
vp->v_object->resident_page_count > trigger)) {
|
||||
VN_IS_DOOMED(vp) || vp->v_type == VNON) {
|
||||
VI_UNLOCK(vp);
|
||||
goto next_iter;
|
||||
}
|
||||
|
||||
object = atomic_load_ptr(&vp->v_object);
|
||||
if (object == NULL || object->resident_page_count > trigger) {
|
||||
VI_UNLOCK(vp);
|
||||
goto next_iter;
|
||||
}
|
||||
|
||||
vholdl(vp);
|
||||
VI_UNLOCK(vp);
|
||||
TAILQ_REMOVE(&vnode_list, mvp, v_vnodelist);
|
||||
|
Loading…
x
Reference in New Issue
Block a user