diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c index 156239eb67b4..9040d44526b9 100644 --- a/sys/fs/msdosfs/msdosfs_vfsops.c +++ b/sys/fs/msdosfs/msdosfs_vfsops.c @@ -1,4 +1,4 @@ -/* $NetBSD: msdosfs_vfsops.c,v 1.131 2020/01/17 20:08:07 ad Exp $ */ +/* $NetBSD: msdosfs_vfsops.c,v 1.132 2020/02/27 22:12:53 ad Exp $ */ /*- * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank. @@ -48,7 +48,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: msdosfs_vfsops.c,v 1.131 2020/01/17 20:08:07 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: msdosfs_vfsops.c,v 1.132 2020/02/27 22:12:53 ad Exp $"); #if defined(_KERNEL_OPT) #include "opt_compat_netbsd.h" @@ -1008,7 +1008,7 @@ msdosfs_sync_selector(void *cl, struct vnode *vp) dep == NULL || (((dep->de_flag & (DE_ACCESS | DE_CREATE | DE_UPDATE | DE_MODIFIED)) == 0) && (LIST_EMPTY(&vp->v_dirtyblkhd) && - UVM_OBJ_IS_CLEAN(&vp->v_uobj)))) + (vp->v_iflag & VI_ONWORKLST) == 0))) return false; return true; } diff --git a/sys/fs/puffs/puffs_vfsops.c b/sys/fs/puffs/puffs_vfsops.c index 02bb3f9282d8..888edb1c8a2e 100644 --- a/sys/fs/puffs/puffs_vfsops.c +++ b/sys/fs/puffs/puffs_vfsops.c @@ -1,4 +1,4 @@ -/* $NetBSD: puffs_vfsops.c,v 1.124 2020/01/17 20:08:08 ad Exp $ */ +/* $NetBSD: puffs_vfsops.c,v 1.125 2020/02/27 22:12:53 ad Exp $ */ /* * Copyright (c) 2005, 2006 Antti Kantee. All Rights Reserved. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: puffs_vfsops.c,v 1.124 2020/01/17 20:08:08 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: puffs_vfsops.c,v 1.125 2020/02/27 22:12:53 ad Exp $"); #include #include @@ -517,7 +517,9 @@ pageflush_selector(void *cl, struct vnode *vp) KASSERT(mutex_owned(vp->v_interlock)); return vp->v_type == VREG && - !(LIST_EMPTY(&vp->v_dirtyblkhd) && UVM_OBJ_IS_CLEAN(&vp->v_uobj)); + !(LIST_EMPTY(&vp->v_dirtyblkhd) && + (vp->v_iflag & VI_ONWORKLST) == 0); + } static int diff --git a/sys/fs/smbfs/smbfs_vfsops.c b/sys/fs/smbfs/smbfs_vfsops.c index f80cb6a8005f..9b8c2d6d3597 100644 --- a/sys/fs/smbfs/smbfs_vfsops.c +++ b/sys/fs/smbfs/smbfs_vfsops.c @@ -1,4 +1,4 @@ -/* $NetBSD: smbfs_vfsops.c,v 1.107 2020/01/17 20:08:08 ad Exp $ */ +/* $NetBSD: smbfs_vfsops.c,v 1.108 2020/02/27 22:12:54 ad Exp $ */ /* * Copyright (c) 2000-2001, Boris Popov @@ -35,7 +35,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: smbfs_vfsops.c,v 1.107 2020/01/17 20:08:08 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: smbfs_vfsops.c,v 1.108 2020/02/27 22:12:54 ad Exp $"); #include #include @@ -406,7 +406,7 @@ smbfs_sync_selector(void *cl, struct vnode *vp) if ((vp->v_type == VNON || (np->n_flag & NMODIFIED) == 0) && LIST_EMPTY(&vp->v_dirtyblkhd) && - UVM_OBJ_IS_CLEAN(&vp->v_uobj)) + (vp->v_iflag & VI_ONWORKLST) == 0) return false; return true; diff --git a/sys/fs/udf/udf_subr.c b/sys/fs/udf/udf_subr.c index 1fc7aa25ee60..1ae40ed76daa 100644 --- a/sys/fs/udf/udf_subr.c +++ b/sys/fs/udf/udf_subr.c @@ -1,4 +1,4 @@ -/* $NetBSD: udf_subr.c,v 1.148 2020/01/17 20:08:08 ad Exp $ */ +/* $NetBSD: udf_subr.c,v 1.149 2020/02/27 22:12:54 ad Exp $ */ /* * Copyright (c) 2006, 2008 Reinoud Zandijk @@ -29,7 +29,7 @@ #include #ifndef lint -__KERNEL_RCSID(0, "$NetBSD: udf_subr.c,v 1.148 2020/01/17 20:08:08 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: udf_subr.c,v 1.149 2020/02/27 22:12:54 ad Exp $"); #endif /* not lint */ @@ -6448,7 +6448,7 @@ udf_sync_selector(void *cl, struct vnode *vp) return false; if ((udf_node->i_flags & (IN_ACCESSED | IN_UPDATE | IN_MODIFIED)) == 0) return false; - if (LIST_EMPTY(&vp->v_dirtyblkhd) && UVM_OBJ_IS_CLEAN(&vp->v_uobj)) + if (LIST_EMPTY(&vp->v_dirtyblkhd) && (vp->v_iflag & VI_ONWORKLST) == 0) return false; return true; diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index adbb42dece41..d25911abd950 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_subr.c,v 1.481 2020/02/23 22:14:03 ad Exp $ */ +/* $NetBSD: vfs_subr.c,v 1.482 2020/02/27 22:12:54 ad Exp $ */ /*- * Copyright (c) 1997, 1998, 2004, 2005, 2007, 2008, 2019, 2020 @@ -69,7 +69,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.481 2020/02/23 22:14:03 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.482 2020/02/27 22:12:54 ad Exp $"); #ifdef _KERNEL_OPT #include "opt_ddb.h" @@ -421,8 +421,13 @@ brelvp(struct buf *bp) if (LIST_NEXT(bp, b_vnbufs) != NOLIST) bufremvn(bp); - if (vp->v_uobj.uo_npages == 0 && (vp->v_iflag & VI_ONWORKLST) && + if ((vp->v_iflag & (VI_ONWORKLST | VI_PAGES)) == VI_ONWORKLST && LIST_FIRST(&vp->v_dirtyblkhd) == NULL) { + /* + * Okay to clear VI_WRMAPDIRTY without the uvm_object locked + * here, because new pages can't be inserted without first + * taking v_interlock (which is held here). + */ vp->v_iflag &= ~VI_WRMAPDIRTY; vn_syncer_remove_from_worklist(vp); } @@ -461,9 +466,15 @@ reassignbuf(struct buf *bp, struct vnode *vp) */ if ((bp->b_oflags & BO_DELWRI) == 0) { listheadp = &vp->v_cleanblkhd; - if (vp->v_uobj.uo_npages == 0 && - (vp->v_iflag & VI_ONWORKLST) && + if ((vp->v_iflag & (VI_ONWORKLST | VI_PAGES)) == + VI_ONWORKLST && LIST_FIRST(&vp->v_dirtyblkhd) == NULL) { + /* + * Okay to clear VI_WRMAPDIRTY without the + * uvm_object locked here, because new pages can't + * be inserted without first taking v_interlock + * (which is held here). + */ vp->v_iflag &= ~VI_WRMAPDIRTY; vn_syncer_remove_from_worklist(vp); } diff --git a/sys/kern/vfs_vnode.c b/sys/kern/vfs_vnode.c index 587fd11acfa3..69944ab8569c 100644 --- a/sys/kern/vfs_vnode.c +++ b/sys/kern/vfs_vnode.c @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_vnode.c,v 1.112 2020/02/23 22:14:04 ad Exp $ */ +/* $NetBSD: vfs_vnode.c,v 1.113 2020/02/27 22:12:54 ad Exp $ */ /*- * Copyright (c) 1997-2011, 2019, 2020 The NetBSD Foundation, Inc. @@ -155,7 +155,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.112 2020/02/23 22:14:04 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.113 2020/02/27 22:12:54 ad Exp $"); #ifdef _KERNEL_OPT #include "opt_pax.h" @@ -843,20 +843,18 @@ vrelel(vnode_t *vp, int flags, int lktype) VOP_INACTIVE(vp, &recycle); if (!recycle) VOP_UNLOCK(vp); + rw_enter(vp->v_uobj.vmobjlock, RW_WRITER); mutex_enter(vp->v_interlock); VSTATE_CHANGE(vp, VS_BLOCKED, VS_LOADED); if (!recycle) { if (vtryrele(vp)) { mutex_exit(vp->v_interlock); + rw_exit(vp->v_uobj.vmobjlock); return; } } - /* - * Take care of space accounting. We hold the last ref so - * it's OK to update VM related fields in v_iflag without - * holding vmobjlock: nobody else will be looking at them. - */ + /* Take care of space accounting. */ if ((vp->v_iflag & VI_EXECMAP) != 0 && vp->v_uobj.uo_npages != 0) { cpu_count(CPU_COUNT_EXECPAGES, -vp->v_uobj.uo_npages); @@ -864,6 +862,7 @@ vrelel(vnode_t *vp, int flags, int lktype) } vp->v_iflag &= ~(VI_TEXT|VI_EXECMAP|VI_WRMAP); vp->v_vflag &= ~VV_MAPPED; + rw_exit(vp->v_uobj.vmobjlock); /* * Recycle the vnode if the file is now unused (unlinked), @@ -1728,7 +1727,7 @@ vcache_reclaim(vnode_t *vp) } KASSERT(vp->v_data == NULL); - KASSERT(vp->v_uobj.uo_npages == 0); + KASSERT((vp->v_iflag & VI_PAGES) == 0); if (vp->v_type == VREG && vp->v_ractx != NULL) { uvm_ra_freectx(vp->v_ractx); diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 541a052cf5ee..b8b1171c8bd2 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_vnops.c,v 1.206 2020/02/23 15:46:41 ad Exp $ */ +/* $NetBSD: vfs_vnops.c,v 1.207 2020/02/27 22:12:54 ad Exp $ */ /*- * Copyright (c) 2009 The NetBSD Foundation, Inc. @@ -66,7 +66,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.206 2020/02/23 15:46:41 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.207 2020/02/27 22:12:54 ad Exp $"); #include "veriexec.h" @@ -339,6 +339,7 @@ vn_markexec(struct vnode *vp) return; } + rw_enter(vp->v_uobj.vmobjlock, RW_WRITER); mutex_enter(vp->v_interlock); if ((vp->v_iflag & VI_EXECMAP) == 0) { cpu_count(CPU_COUNT_FILEPAGES, -vp->v_uobj.uo_npages); @@ -346,6 +347,7 @@ vn_markexec(struct vnode *vp) vp->v_iflag |= VI_EXECMAP; } mutex_exit(vp->v_interlock); + rw_exit(vp->v_uobj.vmobjlock); } /* @@ -361,10 +363,12 @@ vn_marktext(struct vnode *vp) return (0); } + rw_enter(vp->v_uobj.vmobjlock, RW_WRITER); mutex_enter(vp->v_interlock); if (vp->v_writecount != 0) { KASSERT((vp->v_iflag & VI_TEXT) == 0); mutex_exit(vp->v_interlock); + rw_exit(vp->v_uobj.vmobjlock); return (ETXTBSY); } if ((vp->v_iflag & VI_EXECMAP) == 0) { @@ -373,6 +377,7 @@ vn_marktext(struct vnode *vp) } vp->v_iflag |= (VI_TEXT | VI_EXECMAP); mutex_exit(vp->v_interlock); + rw_exit(vp->v_uobj.vmobjlock); return (0); } @@ -979,9 +984,11 @@ vn_mmap(struct file *fp, off_t *offp, size_t size, int prot, int *flagsp, vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); vp->v_vflag |= VV_MAPPED; if (needwritemap) { + rw_enter(vp->v_uobj.vmobjlock, RW_WRITER); mutex_enter(vp->v_interlock); vp->v_iflag |= VI_WRMAP; mutex_exit(vp->v_interlock); + rw_exit(vp->v_uobj.vmobjlock); } VOP_UNLOCK(vp); } diff --git a/sys/miscfs/genfs/genfs_io.c b/sys/miscfs/genfs/genfs_io.c index fafd9d423b2f..273791f53ea3 100644 --- a/sys/miscfs/genfs/genfs_io.c +++ b/sys/miscfs/genfs/genfs_io.c @@ -1,4 +1,4 @@ -/* $NetBSD: genfs_io.c,v 1.87 2020/02/24 20:49:51 ad Exp $ */ +/* $NetBSD: genfs_io.c,v 1.88 2020/02/27 22:12:54 ad Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -31,7 +31,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: genfs_io.c,v 1.87 2020/02/24 20:49:51 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: genfs_io.c,v 1.88 2020/02/27 22:12:54 ad Exp $"); #include #include @@ -87,7 +87,7 @@ static void genfs_markdirty(struct vnode *vp) { - KASSERT(rw_lock_held(vp->v_uobj.vmobjlock)); + KASSERT(rw_write_held(vp->v_uobj.vmobjlock)); mutex_enter(vp->v_interlock); if ((vp->v_iflag & VI_ONWORKLST) == 0) { diff --git a/sys/nfs/nfs_vfsops.c b/sys/nfs/nfs_vfsops.c index fdfe91833f4d..40175f8bde60 100644 --- a/sys/nfs/nfs_vfsops.c +++ b/sys/nfs/nfs_vfsops.c @@ -1,4 +1,4 @@ -/* $NetBSD: nfs_vfsops.c,v 1.238 2020/01/17 20:08:09 ad Exp $ */ +/* $NetBSD: nfs_vfsops.c,v 1.239 2020/02/27 22:12:54 ad Exp $ */ /* * Copyright (c) 1989, 1993, 1995 @@ -35,7 +35,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: nfs_vfsops.c,v 1.238 2020/01/17 20:08:09 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nfs_vfsops.c,v 1.239 2020/02/27 22:12:54 ad Exp $"); #if defined(_KERNEL_OPT) #include "opt_nfs.h" @@ -963,7 +963,8 @@ nfs_sync_selector(void *cl, struct vnode *vp) KASSERT(mutex_owned(vp->v_interlock)); - return !LIST_EMPTY(&vp->v_dirtyblkhd) || !UVM_OBJ_IS_CLEAN(&vp->v_uobj); + return !LIST_EMPTY(&vp->v_dirtyblkhd) || + (vp->v_iflag & VI_ONWORKLST) != 0; } /* diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 8cec185049e9..23317bdc7eea 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -1,4 +1,4 @@ -/* $NetBSD: vnode.h,v 1.289 2020/02/23 22:14:04 ad Exp $ */ +/* $NetBSD: vnode.h,v 1.290 2020/02/27 22:12:54 ad Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -212,6 +212,7 @@ typedef struct vnode vnode_t; #define VI_WRMAP 0x00000400 /* might have PROT_WRITE u. mappings */ #define VI_WRMAPDIRTY 0x00000800 /* might have dirty pages */ #define VI_ONWORKLST 0x00004000 /* On syncer work-list */ +#define VI_PAGES 0x00008000 /* UVM object has >0 pages */ /* * The third set are locked by the underlying file system. diff --git a/sys/ufs/ext2fs/ext2fs_vfsops.c b/sys/ufs/ext2fs/ext2fs_vfsops.c index 2b4fec1e7c5f..191fe379c42c 100644 --- a/sys/ufs/ext2fs/ext2fs_vfsops.c +++ b/sys/ufs/ext2fs/ext2fs_vfsops.c @@ -1,4 +1,4 @@ -/* $NetBSD: ext2fs_vfsops.c,v 1.215 2020/01/17 20:08:10 ad Exp $ */ +/* $NetBSD: ext2fs_vfsops.c,v 1.216 2020/02/27 22:12:54 ad Exp $ */ /* * Copyright (c) 1989, 1991, 1993, 1994 @@ -60,7 +60,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ext2fs_vfsops.c,v 1.215 2020/01/17 20:08:10 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ext2fs_vfsops.c,v 1.216 2020/02/27 22:12:54 ad Exp $"); #if defined(_KERNEL_OPT) #include "opt_compat_netbsd.h" @@ -895,7 +895,7 @@ ext2fs_sync_selector(void *cl, struct vnode *vp) if (((ip->i_flag & (IN_CHANGE | IN_UPDATE | IN_MODIFIED)) == 0 && LIST_EMPTY(&vp->v_dirtyblkhd) && - UVM_OBJ_IS_CLEAN(&vp->v_uobj))) + (vp->v_iflag & VI_ONWORKLST) == 0)) return false; return true; } diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index 1f8cd53e8e29..48567a8b4065 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -1,4 +1,4 @@ -/* $NetBSD: ffs_vfsops.c,v 1.364 2020/02/23 15:46:42 ad Exp $ */ +/* $NetBSD: ffs_vfsops.c,v 1.365 2020/02/27 22:12:54 ad Exp $ */ /*- * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. @@ -61,7 +61,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.364 2020/02/23 15:46:42 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.365 2020/02/27 22:12:54 ad Exp $"); #if defined(_KERNEL_OPT) #include "opt_ffs.h" @@ -1864,7 +1864,7 @@ ffs_sync_selector(void *cl, struct vnode *vp) if ((ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE | IN_MODIFY | IN_MODIFIED | IN_ACCESSED)) == 0 && (c->waitfor == MNT_LAZY || (LIST_EMPTY(&vp->v_dirtyblkhd) && - UVM_OBJ_IS_CLEAN(&vp->v_uobj)))) + (vp->v_iflag & VI_ONWORKLST) == 0))) return false; return true; diff --git a/sys/uvm/uvm_page.c b/sys/uvm/uvm_page.c index 9c7497052cc7..35d251e7986e 100644 --- a/sys/uvm/uvm_page.c +++ b/sys/uvm/uvm_page.c @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_page.c,v 1.227 2020/02/23 23:54:52 ad Exp $ */ +/* $NetBSD: uvm_page.c,v 1.228 2020/02/27 22:12:54 ad Exp $ */ /*- * Copyright (c) 2019, 2020 The NetBSD Foundation, Inc. @@ -95,7 +95,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.227 2020/02/23 23:54:52 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.228 2020/02/27 22:12:54 ad Exp $"); #include "opt_ddb.h" #include "opt_uvm.h" @@ -225,7 +225,12 @@ uvm_pageinsert_object(struct uvm_object *uobj, struct vm_page *pg) if (!isaobj) { KASSERT((pg->flags & PG_FILE) != 0); if (uobj->uo_npages == 0) { - vhold((struct vnode *)uobj); + struct vnode *vp = (struct vnode *)uobj; + mutex_enter(vp->v_interlock); + KASSERT((vp->v_iflag & VI_PAGES) == 0); + vp->v_iflag |= VI_PAGES; + vholdl(vp); + mutex_exit(vp->v_interlock); } kpreempt_disable(); if (UVM_OBJ_IS_VTEXT(uobj)) { @@ -285,7 +290,12 @@ uvm_pageremove_object(struct uvm_object *uobj, struct vm_page *pg) if (!isaobj) { KASSERT((pg->flags & PG_FILE) != 0); if (uobj->uo_npages == 1) { - holdrele((struct vnode *)uobj); + struct vnode *vp = (struct vnode *)uobj; + mutex_enter(vp->v_interlock); + KASSERT((vp->v_iflag & VI_PAGES) != 0); + vp->v_iflag &= ~VI_PAGES; + holdrelel(vp); + mutex_exit(vp->v_interlock); } kpreempt_disable(); if (UVM_OBJ_IS_VTEXT(uobj)) { diff --git a/sys/uvm/uvm_vnode.c b/sys/uvm/uvm_vnode.c index c8e01c0ef826..4f3a4203f90c 100644 --- a/sys/uvm/uvm_vnode.c +++ b/sys/uvm/uvm_vnode.c @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_vnode.c,v 1.106 2020/02/23 15:46:43 ad Exp $ */ +/* $NetBSD: uvm_vnode.c,v 1.107 2020/02/27 22:12:54 ad Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -45,7 +45,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: uvm_vnode.c,v 1.106 2020/02/23 15:46:43 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvm_vnode.c,v 1.107 2020/02/27 22:12:54 ad Exp $"); #ifdef _KERNEL_OPT #include "opt_uvmhist.h" @@ -465,15 +465,19 @@ uvn_text_p(struct uvm_object *uobj) { struct vnode *vp = (struct vnode *)uobj; + /* + * v_interlock is not held here, but VI_EXECMAP is only ever changed + * with the vmobjlock held too. + */ return (vp->v_iflag & VI_EXECMAP) != 0; } bool uvn_clean_p(struct uvm_object *uobj) { - struct vnode *vp = (struct vnode *)uobj; - return (vp->v_iflag & VI_ONWORKLST) == 0; + return radix_tree_empty_tagged_tree_p(&uobj->uo_pages, + UVM_PAGE_DIRTY_TAG); } bool @@ -481,6 +485,11 @@ uvn_needs_writefault_p(struct uvm_object *uobj) { struct vnode *vp = (struct vnode *)uobj; + /* + * v_interlock is not held here, but VI_WRMAP and VI_WRMAPDIRTY are + * only ever changed with the vmobjlock held too, or when it's known + * the uvm_object contains no pages (VI_PAGES clear). + */ return uvn_clean_p(uobj) || (vp->v_iflag & (VI_WRMAP|VI_WRMAPDIRTY)) == VI_WRMAP; }