Module Name:    src
Committed By:   ad
Date:           Thu Feb 27 22:12:55 UTC 2020

Modified Files:
        src/sys/fs/msdosfs: msdosfs_vfsops.c
        src/sys/fs/puffs: puffs_vfsops.c
        src/sys/fs/smbfs: smbfs_vfsops.c
        src/sys/fs/udf: udf_subr.c
        src/sys/kern: vfs_subr.c vfs_vnode.c vfs_vnops.c
        src/sys/miscfs/genfs: genfs_io.c
        src/sys/nfs: nfs_vfsops.c
        src/sys/sys: vnode.h
        src/sys/ufs/ext2fs: ext2fs_vfsops.c
        src/sys/ufs/ffs: ffs_vfsops.c
        src/sys/uvm: uvm_page.c uvm_vnode.c

Log Message:
Tighten up the locking around vp->v_iflag a little more after the recent
split of vmobjlock & v_interlock.


To generate a diff of this commit:
cvs rdiff -u -r1.131 -r1.132 src/sys/fs/msdosfs/msdosfs_vfsops.c
cvs rdiff -u -r1.124 -r1.125 src/sys/fs/puffs/puffs_vfsops.c
cvs rdiff -u -r1.107 -r1.108 src/sys/fs/smbfs/smbfs_vfsops.c
cvs rdiff -u -r1.148 -r1.149 src/sys/fs/udf/udf_subr.c
cvs rdiff -u -r1.481 -r1.482 src/sys/kern/vfs_subr.c
cvs rdiff -u -r1.112 -r1.113 src/sys/kern/vfs_vnode.c
cvs rdiff -u -r1.206 -r1.207 src/sys/kern/vfs_vnops.c
cvs rdiff -u -r1.87 -r1.88 src/sys/miscfs/genfs/genfs_io.c
cvs rdiff -u -r1.238 -r1.239 src/sys/nfs/nfs_vfsops.c
cvs rdiff -u -r1.289 -r1.290 src/sys/sys/vnode.h
cvs rdiff -u -r1.215 -r1.216 src/sys/ufs/ext2fs/ext2fs_vfsops.c
cvs rdiff -u -r1.364 -r1.365 src/sys/ufs/ffs/ffs_vfsops.c
cvs rdiff -u -r1.227 -r1.228 src/sys/uvm/uvm_page.c
cvs rdiff -u -r1.106 -r1.107 src/sys/uvm/uvm_vnode.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/fs/msdosfs/msdosfs_vfsops.c
diff -u src/sys/fs/msdosfs/msdosfs_vfsops.c:1.131 src/sys/fs/msdosfs/msdosfs_vfsops.c:1.132
--- src/sys/fs/msdosfs/msdosfs_vfsops.c:1.131	Fri Jan 17 20:08:07 2020
+++ src/sys/fs/msdosfs/msdosfs_vfsops.c	Thu Feb 27 22:12:53 2020
@@ -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 <sys/cdefs.h>
-__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 v
 	    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;
 }

Index: src/sys/fs/puffs/puffs_vfsops.c
diff -u src/sys/fs/puffs/puffs_vfsops.c:1.124 src/sys/fs/puffs/puffs_vfsops.c:1.125
--- src/sys/fs/puffs/puffs_vfsops.c:1.124	Fri Jan 17 20:08:08 2020
+++ src/sys/fs/puffs/puffs_vfsops.c	Thu Feb 27 22:12:53 2020
@@ -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 <sys/cdefs.h>
-__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 <sys/param.h>
 #include <sys/kernel.h>
@@ -517,7 +517,9 @@ pageflush_selector(void *cl, struct vnod
 	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

Index: src/sys/fs/smbfs/smbfs_vfsops.c
diff -u src/sys/fs/smbfs/smbfs_vfsops.c:1.107 src/sys/fs/smbfs/smbfs_vfsops.c:1.108
--- src/sys/fs/smbfs/smbfs_vfsops.c:1.107	Fri Jan 17 20:08:08 2020
+++ src/sys/fs/smbfs/smbfs_vfsops.c	Thu Feb 27 22:12:54 2020
@@ -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 <sys/cdefs.h>
-__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 <sys/param.h>
 #include <sys/systm.h>
@@ -406,7 +406,7 @@ smbfs_sync_selector(void *cl, struct vno
 
 	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;

Index: src/sys/fs/udf/udf_subr.c
diff -u src/sys/fs/udf/udf_subr.c:1.148 src/sys/fs/udf/udf_subr.c:1.149
--- src/sys/fs/udf/udf_subr.c:1.148	Fri Jan 17 20:08:08 2020
+++ src/sys/fs/udf/udf_subr.c	Thu Feb 27 22:12:54 2020
@@ -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 <sys/cdefs.h>
 #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
 		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;

Index: src/sys/kern/vfs_subr.c
diff -u src/sys/kern/vfs_subr.c:1.481 src/sys/kern/vfs_subr.c:1.482
--- src/sys/kern/vfs_subr.c:1.481	Sun Feb 23 22:14:03 2020
+++ src/sys/kern/vfs_subr.c	Thu Feb 27 22:12:54 2020
@@ -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 <sys/cdefs.h>
-__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
 	 */
 	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);
 		}

Index: src/sys/kern/vfs_vnode.c
diff -u src/sys/kern/vfs_vnode.c:1.112 src/sys/kern/vfs_vnode.c:1.113
--- src/sys/kern/vfs_vnode.c:1.112	Sun Feb 23 22:14:04 2020
+++ src/sys/kern/vfs_vnode.c	Thu Feb 27 22:12:54 2020
@@ -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 <sys/cdefs.h>
-__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 lktyp
 		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 lktyp
 		}
 		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);

Index: src/sys/kern/vfs_vnops.c
diff -u src/sys/kern/vfs_vnops.c:1.206 src/sys/kern/vfs_vnops.c:1.207
--- src/sys/kern/vfs_vnops.c:1.206	Sun Feb 23 15:46:41 2020
+++ src/sys/kern/vfs_vnops.c	Thu Feb 27 22:12:54 2020
@@ -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 <sys/cdefs.h>
-__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, si
 		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);
 	}

Index: src/sys/miscfs/genfs/genfs_io.c
diff -u src/sys/miscfs/genfs/genfs_io.c:1.87 src/sys/miscfs/genfs/genfs_io.c:1.88
--- src/sys/miscfs/genfs/genfs_io.c:1.87	Mon Feb 24 20:49:51 2020
+++ src/sys/miscfs/genfs/genfs_io.c	Thu Feb 27 22:12:54 2020
@@ -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 <sys/cdefs.h>
-__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 <sys/param.h>
 #include <sys/systm.h>
@@ -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) {

Index: src/sys/nfs/nfs_vfsops.c
diff -u src/sys/nfs/nfs_vfsops.c:1.238 src/sys/nfs/nfs_vfsops.c:1.239
--- src/sys/nfs/nfs_vfsops.c:1.238	Fri Jan 17 20:08:09 2020
+++ src/sys/nfs/nfs_vfsops.c	Thu Feb 27 22:12:54 2020
@@ -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 <sys/cdefs.h>
-__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
 
 	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;
 }
 
 /*

Index: src/sys/sys/vnode.h
diff -u src/sys/sys/vnode.h:1.289 src/sys/sys/vnode.h:1.290
--- src/sys/sys/vnode.h:1.289	Sun Feb 23 22:14:04 2020
+++ src/sys/sys/vnode.h	Thu Feb 27 22:12:54 2020
@@ -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.

Index: src/sys/ufs/ext2fs/ext2fs_vfsops.c
diff -u src/sys/ufs/ext2fs/ext2fs_vfsops.c:1.215 src/sys/ufs/ext2fs/ext2fs_vfsops.c:1.216
--- src/sys/ufs/ext2fs/ext2fs_vfsops.c:1.215	Fri Jan 17 20:08:10 2020
+++ src/sys/ufs/ext2fs/ext2fs_vfsops.c	Thu Feb 27 22:12:54 2020
@@ -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 <sys/cdefs.h>
-__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 vn
 	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;
 }

Index: src/sys/ufs/ffs/ffs_vfsops.c
diff -u src/sys/ufs/ffs/ffs_vfsops.c:1.364 src/sys/ufs/ffs/ffs_vfsops.c:1.365
--- src/sys/ufs/ffs/ffs_vfsops.c:1.364	Sun Feb 23 15:46:42 2020
+++ src/sys/ufs/ffs/ffs_vfsops.c	Thu Feb 27 22:12:54 2020
@@ -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 <sys/cdefs.h>
-__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
 	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;

Index: src/sys/uvm/uvm_page.c
diff -u src/sys/uvm/uvm_page.c:1.227 src/sys/uvm/uvm_page.c:1.228
--- src/sys/uvm/uvm_page.c:1.227	Sun Feb 23 23:54:52 2020
+++ src/sys/uvm/uvm_page.c	Thu Feb 27 22:12:54 2020
@@ -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 <sys/cdefs.h>
-__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 
 		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 
 		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)) {

Index: src/sys/uvm/uvm_vnode.c
diff -u src/sys/uvm/uvm_vnode.c:1.106 src/sys/uvm/uvm_vnode.c:1.107
--- src/sys/uvm/uvm_vnode.c:1.106	Sun Feb 23 15:46:43 2020
+++ src/sys/uvm/uvm_vnode.c	Thu Feb 27 22:12:54 2020
@@ -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 <sys/cdefs.h>
-__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
 {
 	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;
 }

Reply via email to