svn commit: r357991 - head/sys/kern
Mateusz Guzik
mjg at FreeBSD.org
Sun Feb 16 03:33:35 UTC 2020
Author: mjg
Date: Sun Feb 16 03:33:34 2020
New Revision: 357991
URL: https://svnweb.freebsd.org/changeset/base/357991
Log:
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
Modified:
head/sys/kern/vfs_subr.c
Modified: head/sys/kern/vfs_subr.c
==============================================================================
--- head/sys/kern/vfs_subr.c Sun Feb 16 03:16:28 2020 (r357990)
+++ head/sys/kern/vfs_subr.c Sun Feb 16 03:33:34 2020 (r357991)
@@ -1100,6 +1100,7 @@ vlrureclaim(bool reclaim_nc_src, int trigger, u_long t
{
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);
More information about the svn-src-all
mailing list