Make knote(9) lock the knote list internally, and add knote_locked(9)
for the typical situation where the list is already locked.

Simplify the kqueue API a bit (and make room for the new function)
by dropping the KNOTE(9) macro. Its value is dubious, not least because
it is common to use proper non-inline functions even for very minor
tasks in the kernel.

Index: share/man/man9/knote.9
===================================================================
RCS file: src/share/man/man9/knote.9,v
retrieving revision 1.9
diff -u -p -r1.9 knote.9
--- share/man/man9/knote.9      21 Jan 2014 03:15:46 -0000      1.9
+++ share/man/man9/knote.9      2 Feb 2023 04:32:53 -0000
@@ -33,18 +33,21 @@
 .Os
 .Sh NAME
 .Nm knote ,
-.Nm KNOTE
+.Nm knote_locked
 .Nd raise kernel event
 .Sh SYNOPSIS
 .In sys/param.h
 .In sys/event.h
 .Ft void
 .Fn knote "struct klist *list" "long hint"
-.Fn KNOTE "struct klist *list" "long hint"
+.Ft void
+.Fn knote_locked "struct klist *list" "long hint"
 .Sh DESCRIPTION
 The
 .Fn knote
-function provides a hook into the kqueue kernel event notification
+and
+.Fn knote_locked
+functions provide a hook into the kqueue kernel event notification
 mechanism to allow sections of the kernel to raise a kernel event
 in the form of a
 .Sq knote ,
@@ -60,7 +63,7 @@ of knotes, along with a
 .Fa hint
 (which is passed to the appropriate filter routine).
 .Fn knote
-then walks the
+then locks and walks the
 .Fa list
 making calls to the filter routine for each knote.
 As each knote contains a reference to the data structure that it is
@@ -80,17 +83,19 @@ If the knote is already on the active li
 call to the filter occurs in order to provide an opportunity for the
 filter to record the activity.
 .Pp
+.Fn knote_locked
+is like
+.Fn knote
+but assumes that the
+.Fa list
+is already locked.
+.Pp
 .Fn knote
+and
+.Fn knote_locked
 must not be called from interrupt contexts running at an interrupt
 priority level higher than
 .Fn splsched .
-.Pp
-.Fn KNOTE
-is a macro that calls
-.Fn knote list hint
-if
-.Fa list
-is not empty.
 .\" .Sh ERRORS
 .Sh SEE ALSO
 .Xr kqueue 2
@@ -98,8 +103,6 @@ is not empty.
 .Sh HISTORY
 The
 .Fn knote
-and
-.Fn KNOTE
 functions first appeared in
 .Fx 4.1 ,
 and then in
Index: sys/arch/arm64/dev/apm.c
===================================================================
RCS file: src/sys/arch/arm64/dev/apm.c,v
retrieving revision 1.21
diff -u -p -r1.21 apm.c
--- sys/arch/arm64/dev/apm.c    22 Jan 2023 13:14:21 -0000      1.21
+++ sys/arch/arm64/dev/apm.c    2 Feb 2023 04:32:53 -0000
@@ -345,7 +345,7 @@ apm_record_event(u_int event)
                return 1;
 
        apm_evindex++;
-       KNOTE(&sc->sc_note, APM_EVENT_COMPOSE(event, apm_evindex));
+       knote_locked(&sc->sc_note, APM_EVENT_COMPOSE(event, apm_evindex));
        return 0;
 }
 
Index: sys/arch/i386/i386/apm.c
===================================================================
RCS file: src/sys/arch/i386/i386/apm.c,v
retrieving revision 1.129
diff -u -p -r1.129 apm.c
--- sys/arch/i386/i386/apm.c    30 Jan 2023 10:49:04 -0000      1.129
+++ sys/arch/i386/i386/apm.c    2 Feb 2023 04:32:54 -0000
@@ -311,7 +311,7 @@ apm_record_event(struct apm_softc *sc, u
        }
 
        apm_evindex++;
-       KNOTE(&sc->sc_note, APM_EVENT_COMPOSE(type, apm_evindex));
+       knote_locked(&sc->sc_note, APM_EVENT_COMPOSE(type, apm_evindex));
        return (0);
 }
 
Index: sys/arch/loongson/dev/apm.c
===================================================================
RCS file: src/sys/arch/loongson/dev/apm.c,v
retrieving revision 1.41
diff -u -p -r1.41 apm.c
--- sys/arch/loongson/dev/apm.c 19 Nov 2022 16:23:48 -0000      1.41
+++ sys/arch/loongson/dev/apm.c 2 Feb 2023 04:32:54 -0000
@@ -363,7 +363,7 @@ apm_record_event(u_int event, const char
                return (1);
 
        apm_evindex++;
-       KNOTE(&sc->sc_note, APM_EVENT_COMPOSE(event, apm_evindex));
+       knote_locked(&sc->sc_note, APM_EVENT_COMPOSE(event, apm_evindex));
 
        return (0);
 }
Index: sys/dev/audio.c
===================================================================
RCS file: src/sys/dev/audio.c,v
retrieving revision 1.205
diff -u -p -r1.205 audio.c
--- sys/dev/audio.c     8 Nov 2022 17:53:01 -0000       1.205
+++ sys/dev/audio.c     2 Feb 2023 04:32:54 -0000
@@ -285,7 +285,7 @@ audio_mixer_wakeup(struct audio_softc *s
                wakeup(&sc->mix_blocking);
                sc->mix_blocking = 0;
        }
-       KNOTE(&sc->mix_klist, 0);
+       knote_locked(&sc->mix_klist, 0);
 }
 
 void
@@ -297,7 +297,7 @@ audio_buf_wakeup(struct audio_buf *buf)
                wakeup(&buf->blocking);
                buf->blocking = 0;
        }
-       KNOTE(&buf->klist, 0);
+       knote_locked(&buf->klist, 0);
 }
 
 int
Index: sys/dev/acpi/acpi.c
===================================================================
RCS file: src/sys/dev/acpi/acpi.c,v
retrieving revision 1.418
diff -u -p -r1.418 acpi.c
--- sys/dev/acpi/acpi.c 13 Sep 2022 17:14:54 -0000      1.418
+++ sys/dev/acpi/acpi.c 2 Feb 2023 04:32:54 -0000
@@ -3483,7 +3483,7 @@ acpi_record_event(struct acpi_softc *sc,
                return (1);
 
        acpi_evindex++;
-       KNOTE(&sc->sc_note, APM_EVENT_COMPOSE(type, acpi_evindex));
+       knote_locked(&sc->sc_note, APM_EVENT_COMPOSE(type, acpi_evindex));
        return (0);
 }
 
Index: sys/dev/pci/drm/drm_connector.c
===================================================================
RCS file: src/sys/dev/pci/drm/drm_connector.c,v
retrieving revision 1.9
diff -u -p -r1.9 drm_connector.c
--- sys/dev/pci/drm/drm_connector.c     9 Jan 2023 04:09:22 -0000       1.9
+++ sys/dev/pci/drm/drm_connector.c     2 Feb 2023 04:32:54 -0000
@@ -2590,7 +2590,7 @@ int drm_connector_set_obj_prop(struct dr
        } else if (property == connector->backlight_property) {
                connector->backlight_device->props.brightness = value;
                backlight_schedule_update_status(connector->backlight_device);
-               KNOTE(&connector->dev->note, NOTE_CHANGE);
+               knote_locked(&connector->dev->note, NOTE_CHANGE);
                ret = 0;
 #endif
        } else if (connector->funcs->set_property)
Index: sys/dev/pci/drm/drm_linux.c
===================================================================
RCS file: src/sys/dev/pci/drm/drm_linux.c,v
retrieving revision 1.95
diff -u -p -r1.95 drm_linux.c
--- sys/dev/pci/drm/drm_linux.c 1 Jan 2023 01:34:34 -0000       1.95
+++ sys/dev/pci/drm/drm_linux.c 2 Feb 2023 04:32:54 -0000
@@ -1541,13 +1541,13 @@ backlight_disable(struct backlight_devic
 void
 drm_sysfs_hotplug_event(struct drm_device *dev)
 {
-       KNOTE(&dev->note, NOTE_CHANGE);
+       knote_locked(&dev->note, NOTE_CHANGE);
 }
 
 void
 drm_sysfs_connector_hotplug_event(struct drm_connector *connector)
 {
-       KNOTE(&connector->dev->note, NOTE_CHANGE);
+       knote_locked(&connector->dev->note, NOTE_CHANGE);
 }
 
 void
Index: sys/dev/pci/drm/drm_mode_object.c
===================================================================
RCS file: src/sys/dev/pci/drm/drm_mode_object.c,v
retrieving revision 1.6
diff -u -p -r1.6 drm_mode_object.c
--- sys/dev/pci/drm/drm_mode_object.c   1 Jan 2023 01:34:34 -0000       1.6
+++ sys/dev/pci/drm/drm_mode_object.c   2 Feb 2023 04:32:54 -0000
@@ -561,7 +561,7 @@ retry:
                struct drm_connector *connector = obj_to_connector(obj);
                connector->backlight_device->props.brightness = prop_value;
                backlight_schedule_update_status(connector->backlight_device);
-               KNOTE(&connector->dev->note, NOTE_CHANGE);
+               knote_locked(&connector->dev->note, NOTE_CHANGE);
                ret = 0;
 #endif
        } else {
Index: sys/dev/pci/drm/amd/amdgpu/amdgpu_drv.c
===================================================================
RCS file: src/sys/dev/pci/drm/amd/amdgpu/amdgpu_drv.c,v
retrieving revision 1.25
diff -u -p -r1.25 amdgpu_drv.c
--- sys/dev/pci/drm/amd/amdgpu/amdgpu_drv.c     19 Jan 2023 00:00:06 -0000      
1.25
+++ sys/dev/pci/drm/amd/amdgpu/amdgpu_drv.c     2 Feb 2023 04:32:54 -0000
@@ -3324,7 +3324,7 @@ amdgpu_wsioctl(void *v, u_long cmd, cadd
                case WSDISPLAYIO_PARAM_BRIGHTNESS:
                        bd->props.brightness = dp->curval;
                        backlight_update_status(bd);
-                       KNOTE(&adev->ddev.note, NOTE_CHANGE);
+                       knote_locked(&adev->ddev.note, NOTE_CHANGE);
                        return 0;
                }
                break;
Index: sys/dev/pci/drm/i915/i915_driver.c
===================================================================
RCS file: src/sys/dev/pci/drm/i915/i915_driver.c,v
retrieving revision 1.3
diff -u -p -r1.3 i915_driver.c
--- sys/dev/pci/drm/i915/i915_driver.c  25 Jan 2023 01:56:39 -0000      1.3
+++ sys/dev/pci/drm/i915/i915_driver.c  2 Feb 2023 04:32:55 -0000
@@ -2251,7 +2251,7 @@ inteldrm_wsioctl(void *v, u_long cmd, ca
                case WSDISPLAYIO_PARAM_BRIGHTNESS:
                        bd->props.brightness = dp->curval;
                        backlight_update_status(bd);
-                       KNOTE(&dev_priv->drm.note, NOTE_CHANGE);
+                       knote_locked(&dev_priv->drm.note, NOTE_CHANGE);
                        return 0;
                }
                break;
Index: sys/kern/kern_event.c
===================================================================
RCS file: src/sys/kern/kern_event.c,v
retrieving revision 1.194
diff -u -p -r1.194 kern_event.c
--- sys/kern/kern_event.c       9 Nov 2022 22:25:36 -0000       1.194
+++ sys/kern/kern_event.c       2 Feb 2023 04:32:55 -0000
@@ -1590,9 +1590,7 @@ kqueue_task(void *arg)
 {
        struct kqueue *kq = arg;
 
-       mtx_enter(&kqueue_klist_lock);
-       KNOTE(&kq->kq_klist, 0);
-       mtx_leave(&kqueue_klist_lock);
+       knote(&kq->kq_klist, 0);
 }
 
 void
@@ -1744,6 +1742,16 @@ knote_activate(struct knote *kn)
 void
 knote(struct klist *list, long hint)
 {
+       int ls;
+
+       ls = klist_lock(list);
+       knote_locked(list, hint);
+       klist_unlock(list, ls);
+}
+
+void
+knote_locked(struct klist *list, long hint)
+{
        struct knote *kn, *kn0;
        struct kqueue *kq;
 
@@ -1853,7 +1861,7 @@ knote_processexit(struct process *pr)
 {
        KERNEL_ASSERT_LOCKED();
 
-       KNOTE(&pr->ps_klist, NOTE_EXIT);
+       knote_locked(&pr->ps_klist, NOTE_EXIT);
 
        /* remove other knotes hanging off the process */
        klist_invalidate(&pr->ps_klist);
Index: sys/kern/kern_exec.c
===================================================================
RCS file: src/sys/kern/kern_exec.c,v
retrieving revision 1.243
diff -u -p -r1.243 kern_exec.c
--- sys/kern/kern_exec.c        13 Jan 2023 23:02:43 -0000      1.243
+++ sys/kern/kern_exec.c        2 Feb 2023 04:32:55 -0000
@@ -675,7 +675,7 @@ sys_execve(struct proc *p, void *v, regi
        /*
         * notify others that we exec'd
         */
-       KNOTE(&pr->ps_klist, NOTE_EXEC);
+       knote_locked(&pr->ps_klist, NOTE_EXEC);
 
        /* map the process's timekeep page, needs to be before exec_elf_fixup */
        if (exec_timekeep_map(pr))
Index: sys/kern/kern_fork.c
===================================================================
RCS file: src/sys/kern/kern_fork.c,v
retrieving revision 1.245
diff -u -p -r1.245 kern_fork.c
--- sys/kern/kern_fork.c        7 Jan 2023 05:24:58 -0000       1.245
+++ sys/kern/kern_fork.c        2 Feb 2023 04:32:55 -0000
@@ -465,7 +465,7 @@ fork1(struct proc *curp, int flags, void
        /*
         * Notify any interested parties about the new process.
         */
-       KNOTE(&curpr->ps_klist, NOTE_FORK | pr->ps_pid);
+       knote_locked(&curpr->ps_klist, NOTE_FORK | pr->ps_pid);
 
        /*
         * Update stats now that we know the fork was successful.
Index: sys/kern/kern_sig.c
===================================================================
RCS file: src/sys/kern/kern_sig.c,v
retrieving revision 1.304
diff -u -p -r1.304 kern_sig.c
--- sys/kern/kern_sig.c 31 Jan 2023 15:18:56 -0000      1.304
+++ sys/kern/kern_sig.c 2 Feb 2023 04:32:55 -0000
@@ -985,7 +985,7 @@ ptsignal(struct proc *p, int signum, enu
        }
 
        if (type != SPROPAGATED)
-               KNOTE(&pr->ps_klist, NOTE_SIGNAL | signum);
+               knote_locked(&pr->ps_klist, NOTE_SIGNAL | signum);
 
        prop = sigprop[signum];
 
Index: sys/kern/sys_generic.c
===================================================================
RCS file: src/sys/kern/sys_generic.c,v
retrieving revision 1.151
diff -u -p -r1.151 sys_generic.c
--- sys/kern/sys_generic.c      27 Dec 2022 20:13:03 -0000      1.151
+++ sys/kern/sys_generic.c      2 Feb 2023 04:32:55 -0000
@@ -832,7 +832,7 @@ void
 selwakeup(struct selinfo *sip)
 {
        KERNEL_LOCK();
-       KNOTE(&sip->si_note, NOTE_SUBMIT);
+       knote_locked(&sip->si_note, NOTE_SUBMIT);
        KERNEL_UNLOCK();
 }
 
Index: sys/kern/sys_pipe.c
===================================================================
RCS file: src/sys/kern/sys_pipe.c,v
retrieving revision 1.143
diff -u -p -r1.143 sys_pipe.c
--- sys/kern/sys_pipe.c 5 Dec 2022 23:18:37 -0000       1.143
+++ sys/kern/sys_pipe.c 2 Feb 2023 04:32:55 -0000
@@ -370,7 +370,7 @@ pipeselwakeup(struct pipe *cpipe)
 {
        rw_assert_wrlock(cpipe->pipe_lock);
 
-       KNOTE(&cpipe->pipe_klist, 0);
+       knote_locked(&cpipe->pipe_klist, 0);
 
        if (cpipe->pipe_state & PIPE_ASYNC)
                pgsigio(&cpipe->pipe_sigio, SIGIO, 0);
Index: sys/kern/uipc_socket.c
===================================================================
RCS file: src/sys/kern/uipc_socket.c,v
retrieving revision 1.299
diff -u -p -r1.299 uipc_socket.c
--- sys/kern/uipc_socket.c      27 Jan 2023 21:01:59 -0000      1.299
+++ sys/kern/uipc_socket.c      2 Feb 2023 04:32:55 -0000
@@ -2112,7 +2112,7 @@ void
 sohasoutofband(struct socket *so)
 {
        pgsigio(&so->so_sigio, SIGURG, 0);
-       KNOTE(&so->so_rcv.sb_klist, 0);
+       knote_locked(&so->so_rcv.sb_klist, 0);
 }
 
 int
Index: sys/kern/uipc_socket2.c
===================================================================
RCS file: src/sys/kern/uipc_socket2.c,v
retrieving revision 1.134
diff -u -p -r1.134 uipc_socket2.c
--- sys/kern/uipc_socket2.c     27 Jan 2023 18:46:34 -0000      1.134
+++ sys/kern/uipc_socket2.c     2 Feb 2023 04:32:55 -0000
@@ -549,7 +549,7 @@ sowakeup(struct socket *so, struct sockb
        }
        if (sb->sb_flags & SB_ASYNC)
                pgsigio(&so->so_sigio, SIGIO, 0);
-       KNOTE(&sb->sb_klist, 0);
+       knote_locked(&sb->sb_klist, 0);
 }
 
 /*
Index: sys/kern/uipc_syscalls.c
===================================================================
RCS file: src/sys/kern/uipc_syscalls.c,v
retrieving revision 1.211
diff -u -p -r1.211 uipc_syscalls.c
--- sys/kern/uipc_syscalls.c    27 Jan 2023 21:01:59 -0000      1.211
+++ sys/kern/uipc_syscalls.c    2 Feb 2023 04:32:55 -0000
@@ -326,7 +326,7 @@ doaccept(struct proc *p, int sock, struc
            : (flags & SOCK_NONBLOCK ? FNONBLOCK : 0);
 
        /* connection has been removed from the listen queue */
-       KNOTE(&head->so_rcv.sb_klist, 0);
+       knote_locked(&head->so_rcv.sb_klist, 0);
 
        if (persocket)
                sounlock(head);
Index: sys/net/bpf.c
===================================================================
RCS file: src/sys/net/bpf.c,v
retrieving revision 1.219
diff -u -p -r1.219 bpf.c
--- sys/net/bpf.c       9 Jul 2022 12:48:21 -0000       1.219
+++ sys/net/bpf.c       2 Feb 2023 04:32:55 -0000
@@ -586,7 +586,7 @@ bpf_wakeup(struct bpf_d *d)
        if (d->bd_nreaders)
                wakeup(d);
 
-       KNOTE(&d->bd_klist, 0);
+       knote_locked(&d->bd_klist, 0);
 
        /*
         * As long as pgsigio() needs to be protected
Index: sys/net/if_pppx.c
===================================================================
RCS file: src/sys/net/if_pppx.c,v
retrieving revision 1.125
diff -u -p -r1.125 if_pppx.c
--- sys/net/if_pppx.c   30 Jan 2023 03:31:59 -0000      1.125
+++ sys/net/if_pppx.c   2 Feb 2023 04:32:55 -0000
@@ -903,9 +903,7 @@ pppx_if_output(struct ifnet *ifp, struct
                                wakeup((caddr_t)pxi->pxi_dev);
                                pxi->pxi_dev->pxd_waiting = 0;
                        }
-                       mtx_enter(&pxi->pxi_dev->pxd_mtx);
-                       KNOTE(&pxi->pxi_dev->pxd_rklist, 0);
-                       mtx_leave(&pxi->pxi_dev->pxd_mtx);
+                       knote(&pxi->pxi_dev->pxd_rklist, 0);
                }
        }
 
@@ -1519,8 +1517,6 @@ bad:
 
        if (!mq_empty(&sc->sc_mq)) {
                wakeup(sc);
-               mtx_enter(&sc->sc_mtx);
-               KNOTE(&sc->sc_rklist, 0);
-               mtx_leave(&sc->sc_mtx);
+               knote(&sc->sc_rklist, 0);
        }
 }
Index: sys/sys/event.h
===================================================================
RCS file: src/sys/sys/event.h,v
retrieving revision 1.67
diff -u -p -r1.67 event.h
--- sys/sys/event.h     31 Mar 2022 01:41:22 -0000      1.67
+++ sys/sys/event.h     2 Feb 2023 04:32:55 -0000
@@ -152,12 +152,6 @@ struct klist {
  */
 #define NOTE_SUBMIT    0x01000000              /* initial knote submission */
 
-#define KNOTE(list, hint)      do { \
-                                       struct klist *__list = (list); \
-                                       if (!klist_empty(__list)) \
-                                               knote(__list, hint); \
-                               } while (0)
-
 #define        KN_HASHSIZE             64              /* XXX should be 
tunable */
 
 /*
@@ -292,6 +286,7 @@ extern void kqpoll_init(unsigned int);
 extern void    kqpoll_done(unsigned int);
 extern void    kqpoll_exit(void);
 extern void    knote(struct klist *list, long hint);
+extern void    knote_locked(struct klist *list, long hint);
 extern void    knote_fdclose(struct proc *p, int fd);
 extern void    knote_processexit(struct process *);
 extern void    knote_assign(const struct kevent *, struct knote *);
Index: sys/sys/vnode.h
===================================================================
RCS file: src/sys/sys/vnode.h,v
retrieving revision 1.167
diff -u -p -r1.167 vnode.h
--- sys/sys/vnode.h     12 Aug 2022 14:30:53 -0000      1.167
+++ sys/sys/vnode.h     2 Feb 2023 04:32:55 -0000
@@ -246,7 +246,7 @@ extern int          vttoif_tab[];
 #define        VATTR_NULL(vap) vattr_null(vap)
 #define        NULLVP  ((struct vnode *)NULL)
 #define        VN_KNOTE(vp, b)                                 \
-       KNOTE(&vp->v_selectinfo.si_note, (b))
+       knote_locked(&vp->v_selectinfo.si_note, (b))
 
 /*
  * Global vnode data.

Reply via email to