git: 4dcdf3987c1c - main - vfs: replace the MNTK_TEXT_REFS flag with VIRF_TEXT_REF

From: Mateusz Guzik <mjg_at_FreeBSD.org>
Date: Sat, 27 Nov 2021 23:19:31 UTC
The branch main has been updated by mjg:

URL: https://cgit.FreeBSD.org/src/commit/?id=4dcdf3987c1cc95d0d344468e8aa15452254691c

commit 4dcdf3987c1cc95d0d344468e8aa15452254691c
Author:     Mateusz Guzik <mjg@FreeBSD.org>
AuthorDate: 2021-05-18 10:47:21 +0000
Commit:     Mateusz Guzik <mjg@FreeBSD.org>
CommitDate: 2021-11-27 23:07:25 +0000

    vfs: replace the MNTK_TEXT_REFS flag with VIRF_TEXT_REF
    
    This allows to stop maintaing the VI_TEXT_REF flag and consequently
    opens up fully lockless v_writecount adjustment.
    
    Reviewed by:    kib
    Differential Revision:  https://reviews.freebsd.org/D33127
---
 sys/fs/tmpfs/tmpfs_subr.c   |  2 +-
 sys/fs/tmpfs/tmpfs_vfsops.c |  2 +-
 sys/kern/vfs_default.c      | 20 +++++++++-----------
 sys/kern/vfs_subr.c         |  8 ++++----
 sys/sys/mount.h             |  2 +-
 sys/sys/vnode.h             |  3 ++-
 6 files changed, 18 insertions(+), 19 deletions(-)

diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c
index 9810c1776314..41d9b6d5dcca 100644
--- a/sys/fs/tmpfs/tmpfs_subr.c
+++ b/sys/fs/tmpfs/tmpfs_subr.c
@@ -967,7 +967,7 @@ loop:
 		vp->v_object = object;
 		object->un_pager.swp.swp_tmpfs = vp;
 		vm_object_set_flag(object, OBJ_TMPFS);
-		vn_irflag_set_locked(vp, VIRF_PGREAD);
+		vn_irflag_set_locked(vp, VIRF_PGREAD | VIRF_TEXT_REF);
 		VI_UNLOCK(vp);
 		VM_OBJECT_WUNLOCK(object);
 		break;
diff --git a/sys/fs/tmpfs/tmpfs_vfsops.c b/sys/fs/tmpfs/tmpfs_vfsops.c
index b8ecedbb0348..7bd44decd830 100644
--- a/sys/fs/tmpfs/tmpfs_vfsops.c
+++ b/sys/fs/tmpfs/tmpfs_vfsops.c
@@ -469,7 +469,7 @@ tmpfs_mount(struct mount *mp)
 	MNT_ILOCK(mp);
 	mp->mnt_flag |= MNT_LOCAL;
 	mp->mnt_kern_flag |= MNTK_LOOKUP_SHARED | MNTK_EXTENDED_SHARED |
-	    MNTK_TEXT_REFS | MNTK_NOMSYNC;
+	    MNTK_NOMSYNC;
 	if (!nonc && (mp->mnt_flag & MNT_UNION) == 0)
 		mp->mnt_kern_flag |= MNTK_FPLOOKUP;
 	MNT_IUNLOCK(mp);
diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
index 50829ad3044e..1f5869bd8cf3 100644
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -1300,7 +1300,6 @@ int
 vop_stdset_text(struct vop_set_text_args *ap)
 {
 	struct vnode *vp;
-	struct mount *mp;
 	int error, n;
 
 	vp = ap->a_vp;
@@ -1326,12 +1325,10 @@ vop_stdset_text(struct vop_set_text_args *ap)
 		 * If requested by fs, keep a use reference to the
 		 * vnode until the last text reference is released.
 		 */
-		mp = vp->v_mount;
-		if (mp != NULL && (mp->mnt_kern_flag & MNTK_TEXT_REFS) != 0 &&
-		    vp->v_writecount == 0) {
-			VNPASS((vp->v_iflag & VI_TEXT_REF) == 0, vp);
-			vp->v_iflag |= VI_TEXT_REF;
-			vrefl(vp);
+		if ((vn_irflag_read(vp) & VIRF_TEXT_REF) != 0) {
+			if (vp->v_writecount == 0) {
+				vrefl(vp);
+			}
 		}
 
 		atomic_subtract_int(&vp->v_writecount, 1);
@@ -1366,11 +1363,12 @@ vop_stdunset_text(struct vop_unset_text_args *ap)
 	last = false;
 	VI_LOCK(vp);
 	if (vp->v_writecount < 0) {
-		if ((vp->v_iflag & VI_TEXT_REF) != 0 &&
-		    vp->v_writecount == -1) {
-			last = true;
-			vp->v_iflag &= ~VI_TEXT_REF;
+		if ((vn_irflag_read(vp) & VIRF_TEXT_REF) != 0) {
+			if (vp->v_writecount == -1) {
+				last = true;
+			}
 		}
+
 		atomic_add_int(&vp->v_writecount, 1);
 		error = 0;
 	} else {
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 65a9ebf304fe..06ca5dc7d93a 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -4122,7 +4122,9 @@ vn_printf(struct vnode *vp, const char *fmt, ...)
 		strlcat(buf, "|VIRF_PGREAD", sizeof(buf));
 	if (irflag & VIRF_MOUNTPOINT)
 		strlcat(buf, "|VIRF_MOUNTPOINT", sizeof(buf));
-	flags = irflag & ~(VIRF_DOOMED | VIRF_PGREAD | VIRF_MOUNTPOINT);
+	if (irflag & VIRF_TEXT_REF)
+		strlcat(buf, "|VIRF_TEXT_REF", sizeof(buf));
+	flags = irflag & ~(VIRF_DOOMED | VIRF_PGREAD | VIRF_MOUNTPOINT | VIRF_TEXT_REF);
 	if (flags != 0) {
 		snprintf(buf2, sizeof(buf2), "|VIRF(0x%lx)", flags);
 		strlcat(buf, buf2, sizeof(buf));
@@ -4163,8 +4165,6 @@ vn_printf(struct vnode *vp, const char *fmt, ...)
 		snprintf(buf2, sizeof(buf2), "|VV(0x%lx)", flags);
 		strlcat(buf, buf2, sizeof(buf));
 	}
-	if (vp->v_iflag & VI_TEXT_REF)
-		strlcat(buf, "|VI_TEXT_REF", sizeof(buf));
 	if (vp->v_iflag & VI_MOUNT)
 		strlcat(buf, "|VI_MOUNT", sizeof(buf));
 	if (vp->v_iflag & VI_DOINGINACT)
@@ -4175,7 +4175,7 @@ vn_printf(struct vnode *vp, const char *fmt, ...)
 		strlcat(buf, "|VI_DEFINACT", sizeof(buf));
 	if (vp->v_iflag & VI_FOPENING)
 		strlcat(buf, "|VI_FOPENING", sizeof(buf));
-	flags = vp->v_iflag & ~(VI_TEXT_REF | VI_MOUNT | VI_DOINGINACT |
+	flags = vp->v_iflag & ~(VI_MOUNT | VI_DOINGINACT |
 	    VI_OWEINACT | VI_DEFINACT | VI_FOPENING);
 	if (flags != 0) {
 		snprintf(buf2, sizeof(buf2), "|VI(0x%lx)", flags);
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index 1863a36738d1..d47d67f1156b 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -489,7 +489,7 @@ struct mntoptnames {
 #define	MNTK_LOOKUP_EXCL_DOTDOT	0x00000800
 #define	MNTK_UNMAPPED_BUFS	0x00002000
 #define	MNTK_USES_BCACHE	0x00004000 /* FS uses the buffer cache. */
-#define	MNTK_TEXT_REFS		0x00008000 /* Keep use ref for text */
+#define	MNTK_UNUSED0		0x00008000 /* unused */
 #define	MNTK_VMSETSIZE_BUG	0x00010000
 #define	MNTK_UNIONFS	0x00020000	/* A hack for F_ISUNIONSTACK */
 #define	MNTK_FPLOOKUP	0x00040000	/* fast path lookup is supported */
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index c84d015b011c..53b0a45064b9 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -251,8 +251,9 @@ struct xvnode {
 #define	VIRF_PGREAD	0x0002	/* Direct reads from the page cache are permitted,
 				   never cleared once set */
 #define	VIRF_MOUNTPOINT	0x0004	/* This vnode is mounted on */
+#define	VIRF_TEXT_REF	0x0008	/* Executable mappings ref the vnode */
 
-#define	VI_TEXT_REF	0x0001	/* Text ref grabbed use ref */
+#define	VI_UNUSED0	0x0001	/* unused */
 #define	VI_MOUNT	0x0002	/* Mount in progress */
 #define	VI_DOINGINACT	0x0004	/* VOP_INACTIVE is in progress */
 #define	VI_OWEINACT	0x0008	/* Need to call inactive */