The branch main has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=1d5e4020e36e1cc9e906200c9c3c784ef43d977e

commit 1d5e4020e36e1cc9e906200c9c3c784ef43d977e
Author:     Konstantin Belousov <[email protected]>
AuthorDate: 2026-04-24 01:31:27 +0000
Commit:     Konstantin Belousov <[email protected]>
CommitDate: 2026-05-10 17:43:46 +0000

    vnode: add VIRF_KNOTE flag
    
    to indicate non-empty vnode knote list.  Use it instead of
    VN_KNLIST_EMPTY() and guard note activations with it.
    
    Reviewed by:    markj
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D56611
---
 sys/kern/vfs_subr.c | 14 ++++++++++----
 sys/sys/mount.h     | 12 ++++++++++--
 sys/sys/vnode.h     | 29 ++++++++++++-----------------
 3 files changed, 32 insertions(+), 23 deletions(-)

diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 48bfea2f5bf9..f46c666b115c 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -6090,7 +6090,7 @@ vop_create_post(void *ap, int rc)
        a = ap;
        dvp = a->a_dvp;
        vn_seqc_write_end(dvp);
-       if (!rc) {
+       if (rc == 0) {
                VFS_KNOTE_LOCKED(dvp, NOTE_WRITE);
                INOTIFY_NAME(*a->a_vpp, dvp, a->a_cnp, IN_CREATE);
        }
@@ -6244,7 +6244,7 @@ vop_mknod_post(void *ap, int rc)
        a = ap;
        dvp = a->a_dvp;
        vn_seqc_write_end(dvp);
-       if (!rc) {
+       if (rc == 0) {
                VFS_KNOTE_LOCKED(dvp, NOTE_WRITE);
                INOTIFY_NAME(*a->a_vpp, dvp, a->a_cnp, IN_CREATE);
        }
@@ -6512,7 +6512,7 @@ vop_read_pgcache_post(void *ap, int rc)
 {
        struct vop_read_pgcache_args *a = ap;
 
-       if (!rc)
+       if (rc == 0)
                VFS_KNOTE_UNLOCKED(a->a_vp, NOTE_READ);
 }
 
@@ -6659,6 +6659,8 @@ vfs_knlunlock(void *arg)
 {
        struct vnode *vp = arg;
 
+       if (KNLIST_EMPTY(&vp->v_pollinfo->vpi_selinfo.si_note))
+               vn_irflag_unset(vp, VIRF_KNOTE);
        VOP_UNLOCK(vp);
 }
 
@@ -6706,7 +6708,11 @@ vfs_kqfilter(struct vop_kqfilter_args *ap)
                return (ENOMEM);
        knl = &vp->v_pollinfo->vpi_selinfo.si_note;
        vhold(vp);
-       knlist_add(knl, kn, 0);
+       vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+       knlist_add(knl, kn, 1);
+       if ((vn_irflag_read(vp) & VIRF_KNOTE) == 0)
+               vn_irflag_set(vp, VIRF_KNOTE);
+       VOP_UNLOCK(vp);
 
        return (0);
 }
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index f99d0856f16e..480a6c16badf 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -952,14 +952,22 @@ vfs_statfs_t      __vfs_statfs;
        }                                                               \
 } while (0)
 
+#include <sys/vnode.h>
+
 #define VFS_KNOTE_LOCKED(vp, hint) do                                  \
 {                                                                      \
-       VN_KNOTE((vp), (hint), KNF_LISTLOCKED);                         \
+       if ((vn_irflag_read(vp) & VIRF_KNOTE) != 0) {                   \
+               KNOTE_LOCKED(&vp->v_pollinfo->vpi_selinfo.si_note,      \
+                   hint);                                              \
+       }                                                               \
 } while (0)
 
 #define VFS_KNOTE_UNLOCKED(vp, hint) do                                        
\
 {                                                                      \
-       VN_KNOTE((vp), (hint), 0);                                      \
+       if ((vn_irflag_read(vp) & VIRF_KNOTE) != 0) {                   \
+               KNOTE_UNLOCKED(&vp->v_pollinfo->vpi_selinfo.si_note,    \
+                   hint);                                              \
+       }                                                               \
 } while (0)
 
 #include <sys/module.h>
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index 3fd2c770cda1..d1d20778a8ec 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -224,18 +224,14 @@ _Static_assert(sizeof(struct vnode) <= 448, "vnode size 
crosses 448 bytes");
 /* XXX: These are temporary to avoid a source sweep at this time */
 #define v_object       v_bufobj.bo_object
 
-/* We don't need to lock the knlist */
-#define        VN_KNLIST_EMPTY(vp) ((vp)->v_pollinfo == NULL ||        \
-           KNLIST_EMPTY(&(vp)->v_pollinfo->vpi_selinfo.si_note))
-
-#define VN_KNOTE(vp, b, a)                                     \
-       do {                                                    \
-               if (!VN_KNLIST_EMPTY(vp))                       \
-                       KNOTE(&vp->v_pollinfo->vpi_selinfo.si_note, (b), \
-                           (a) | KNF_NOKQLOCK);                \
-       } while (0)
-#define        VN_KNOTE_LOCKED(vp, b)          VN_KNOTE(vp, b, KNF_LISTLOCKED)
-#define        VN_KNOTE_UNLOCKED(vp, b)        VN_KNOTE(vp, b, 0)
+#define VN_KNOTE(vp, b, a) do {                                        \
+       if ((vn_irflag_read(vp) & VIRF_KNOTE) != 0) {                   \
+               KNOTE(&vp->v_pollinfo->vpi_selinfo.si_note, (b),        \
+                   (a) | KNF_NOKQLOCK);                                \
+       }                                                               \
+} while (0)
+#define   VN_KNOTE_LOCKED(vp, b)     VN_KNOTE(vp, b, KNF_LISTLOCKED)
+#define   VN_KNOTE_UNLOCKED(vp, b)   VN_KNOTE(vp, b, 0)
 
 /*
  * Vnode flags.
@@ -260,6 +256,7 @@ _Static_assert(sizeof(struct vnode) <= 448, "vnode size 
crosses 448 bytes");
 #define        VIRF_INOTIFY    0x0080  /* This vnode is being watched */
 #define        VIRF_INOTIFY_PARENT 0x0100 /* A parent of this vnode may be 
being
                                      watched */
+#define        VIRF_KNOTE      0x0200  /* Has knlist */
 
 #define        VI_UNUSED0      0x0001  /* unused */
 #define        VI_MOUNT        0x0002  /* Mount in progress */
@@ -1052,7 +1049,7 @@ void      vop_rename_fail(struct vop_rename_args *ap);
        off_t osize, ooffset, noffset;                                  \
                                                                        \
        osize = ooffset = noffset = 0;                                  \
-       if (!VN_KNLIST_EMPTY((ap)->a_vp)) {                             \
+       if ((vn_irflag_read((ap)->a_vp) & VIRF_KNOTE) != 0) {           \
                error = VOP_GETATTR((ap)->a_vp, &va, (ap)->a_cred);     \
                if (error)                                              \
                        return (error);                                 \
@@ -1063,10 +1060,8 @@ void     vop_rename_fail(struct vop_rename_args *ap);
 #define vop_write_post(ap, ret)                                                
\
        noffset = (ap)->a_uio->uio_offset;                              \
        if (noffset > ooffset) {                                        \
-               if (!VN_KNLIST_EMPTY((ap)->a_vp)) {                     \
-                       VFS_KNOTE_LOCKED((ap)->a_vp, NOTE_WRITE |       \
-                           (noffset > osize ? NOTE_EXTEND : 0));       \
-               }                                                       \
+               VFS_KNOTE_LOCKED((ap)->a_vp, NOTE_WRITE |               \
+                   (noffset > osize ? NOTE_EXTEND : 0));               \
                INOTIFY((ap)->a_vp, IN_MODIFY);                         \
        }
 

Reply via email to