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.