Download raw body.
mp-safe drm*_filtops
The resurrection my old diff. No reason for X to stuck in kernel lock
while polling.
The `event_lock' mutex(9) is already protects `event_list' checked by
filt_drmread(), so use it to protect the `drmread_filtops' too.
The filt_drmkms() doesn't touch any data and could be easily converted
to always return 1, so the lock is only required for `drm_filtops'.
Introduce the new `note_mtx' mutex(9) for that purpose.
I have no radeondrm(4), so tested with inteldrm(4) only. Previous time I
had successful reports from people with radeondrm(4) too.
Index: sys/dev/pci/drm/drm_connector.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/drm_connector.c,v
retrieving revision 1.15
diff -u -p -r1.15 drm_connector.c
--- sys/dev/pci/drm/drm_connector.c 24 Mar 2025 02:33:30 -0000 1.15
+++ sys/dev/pci/drm/drm_connector.c 18 Jul 2025 20:20:49 -0000
@@ -3093,7 +3093,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_locked(&connector->dev->note, NOTE_CHANGE);
+ knote(&connector->dev->note, NOTE_CHANGE);
ret = 0;
#endif
} else if (connector->funcs->set_property)
Index: sys/dev/pci/drm/drm_drv.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/drm_drv.c,v
retrieving revision 1.203
diff -u -p -r1.203 drm_drv.c
--- sys/dev/pci/drm/drm_drv.c 2 Jul 2025 12:19:26 -0000 1.203
+++ sys/dev/pci/drm/drm_drv.c 18 Jul 2025 20:20:49 -0000
@@ -1362,6 +1362,9 @@ drm_attach(struct device *parent, struct
dev->dev_private = parent;
dev->driver = da->driver;
+ mtx_init(&dev->note_mtx, IPL_MPFLOOR);
+ klist_init_mutex(&dev->note, &dev->note_mtx);
+
INIT_LIST_HEAD(&dev->managed.resources);
mtx_init(&dev->managed.lock, IPL_TTY);
@@ -1640,58 +1643,108 @@ void
filt_drmdetach(struct knote *kn)
{
struct drm_device *dev = kn->kn_hook;
- int s;
- s = spltty();
- klist_remove_locked(&dev->note, kn);
- splx(s);
+ klist_remove(&dev->note, kn);
}
int
filt_drmkms(struct knote *kn, long hint)
{
+ struct drm_device *dev = kn->kn_hook;
+
+ MUTEX_ASSERT_LOCKED(&dev->note_mtx);
+
if (kn->kn_sfflags & hint)
kn->kn_fflags |= hint;
return (kn->kn_fflags != 0);
}
+int
+filt_drmmodify(struct kevent *kev, struct knote *kn)
+{
+ struct drm_device *dev = kn->kn_hook;
+ int active;
+
+ mtx_enter(&dev->note_mtx);
+ active = knote_modify(kev, kn);
+ mtx_leave(&dev->note_mtx);
+
+ return (active);
+}
+
+int
+filt_drmprocess(struct knote *kn, struct kevent *kev)
+{
+ struct drm_device *dev = kn->kn_hook;
+ int active;
+
+ mtx_enter(&dev->note_mtx);
+ active = knote_process(kn, kev);
+ mtx_leave(&dev->note_mtx);
+
+ return (active);
+}
+
void
filt_drmreaddetach(struct knote *kn)
{
struct drm_file *file_priv = kn->kn_hook;
- int s;
- s = spltty();
- klist_remove_locked(&file_priv->rsel.si_note, kn);
- splx(s);
+ klist_remove(&file_priv->rklist, kn);
}
int
filt_drmread(struct knote *kn, long hint)
{
struct drm_file *file_priv = kn->kn_hook;
- int val = 0;
- if ((hint & NOTE_SUBMIT) == 0)
- mtx_enter(&file_priv->minor->dev->event_lock);
- val = !list_empty(&file_priv->event_list);
- if ((hint & NOTE_SUBMIT) == 0)
- mtx_leave(&file_priv->minor->dev->event_lock);
- return (val);
+ MUTEX_ASSERT_LOCKED(&file_priv->minor->dev->event_lock);
+
+ return !(list_empty(&file_priv->event_list));
+}
+
+int
+filt_drmreadmodify(struct kevent *kev, struct knote *kn)
+{
+ struct drm_file *file_priv = kn->kn_hook;
+ int active;
+
+ mtx_enter(&file_priv->minor->dev->event_lock);
+ active = knote_modify(kev, kn);
+ mtx_leave(&file_priv->minor->dev->event_lock);
+
+ return (active);
+}
+
+int
+filt_drmreadprocess(struct knote *kn, struct kevent *kev)
+{
+ struct drm_file *file_priv = kn->kn_hook;
+ int active;
+
+ mtx_enter(&file_priv->minor->dev->event_lock);
+ active = knote_process(kn, kev);
+ mtx_leave(&file_priv->minor->dev->event_lock);
+
+ return (active);
}
const struct filterops drm_filtops = {
- .f_flags = FILTEROP_ISFD,
+ .f_flags = FILTEROP_ISFD | FILTEROP_MPSAFE,
.f_attach = NULL,
.f_detach = filt_drmdetach,
.f_event = filt_drmkms,
+ .f_modify = filt_drmmodify,
+ .f_process = filt_drmprocess,
};
const struct filterops drmread_filtops = {
- .f_flags = FILTEROP_ISFD,
+ .f_flags = FILTEROP_ISFD | FILTEROP_MPSAFE,
.f_attach = NULL,
.f_detach = filt_drmreaddetach,
.f_event = filt_drmread,
+ .f_modify = filt_drmreadmodify,
+ .f_process = filt_drmreadprocess,
};
int
@@ -1699,7 +1752,6 @@ drmkqfilter(dev_t kdev, struct knote *kn
{
struct drm_device *dev = NULL;
struct drm_file *file_priv = NULL;
- int s;
dev = drm_get_device_from_kdev(kdev);
if (dev == NULL || dev->dev_private == NULL)
@@ -1716,17 +1768,13 @@ drmkqfilter(dev_t kdev, struct knote *kn
kn->kn_fop = &drmread_filtops;
kn->kn_hook = file_priv;
- s = spltty();
- klist_insert_locked(&file_priv->rsel.si_note, kn);
- splx(s);
+ klist_insert(&file_priv->rklist, kn);
break;
case EVFILT_DEVICE:
kn->kn_fop = &drm_filtops;
kn->kn_hook = dev;
- s = spltty();
- klist_insert_locked(&dev->note, kn);
- splx(s);
+ klist_insert(&dev->note, kn);
break;
default:
return (EINVAL);
Index: sys/dev/pci/drm/drm_file.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/drm_file.c,v
retrieving revision 1.15
diff -u -p -r1.15 drm_file.c
--- sys/dev/pci/drm/drm_file.c 12 May 2025 08:02:35 -0000 1.15
+++ sys/dev/pci/drm/drm_file.c 18 Jul 2025 20:20:49 -0000
@@ -160,6 +160,8 @@ struct drm_file *drm_file_alloc(struct d
mtx_init(&file->master_lookup_lock, IPL_NONE);
rw_init(&file->event_read_lock, "evread");
+ klist_init_mutex(&file->rklist, &dev->event_lock);
+
if (drm_core_check_feature(dev, DRIVER_GEM))
drm_gem_open(dev, file);
@@ -244,6 +246,9 @@ void drm_file_free(struct drm_file *file
drm_events_release(file);
+ klist_invalidate(&file->rklist);
+ klist_free(&file->rklist);
+
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
drm_fb_release(file);
drm_property_destroy_user_blobs(dev, file);
@@ -789,7 +794,7 @@ static void drm_send_event_helper(struct
wake_up_interruptible_poll(&e->file_priv->event_wait,
EPOLLIN | EPOLLRDNORM);
#ifdef __OpenBSD__
- selwakeup(&e->file_priv->rsel);
+ knote_locked(&e->file_priv->rklist, NOTE_CHANGE);
#endif
}
Index: sys/dev/pci/drm/drm_linux.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/drm_linux.c,v
retrieving revision 1.126
diff -u -p -r1.126 drm_linux.c
--- sys/dev/pci/drm/drm_linux.c 13 Jun 2025 07:01:37 -0000 1.126
+++ sys/dev/pci/drm/drm_linux.c 18 Jul 2025 20:20:49 -0000
@@ -1669,13 +1669,13 @@ dev_get_drvdata(struct device *dev)
void
drm_sysfs_hotplug_event(struct drm_device *dev)
{
- knote_locked(&dev->note, NOTE_CHANGE);
+ knote(&dev->note, NOTE_CHANGE);
}
void
drm_sysfs_connector_hotplug_event(struct drm_connector *connector)
{
- knote_locked(&connector->dev->note, NOTE_CHANGE);
+ knote(&connector->dev->note, NOTE_CHANGE);
}
void
Index: sys/dev/pci/drm/drm_mode_object.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/drm_mode_object.c,v
retrieving revision 1.9
diff -u -p -r1.9 drm_mode_object.c
--- sys/dev/pci/drm/drm_mode_object.c 7 Feb 2025 03:03:08 -0000 1.9
+++ sys/dev/pci/drm/drm_mode_object.c 18 Jul 2025 20:20:49 -0000
@@ -564,7 +564,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_locked(&connector->dev->note, NOTE_CHANGE);
+ knote(&connector->dev->note, NOTE_CHANGE);
ret = 0;
#endif
} else {
Index: sys/dev/pci/drm/amd/amdgpu/amdgpu_drv.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/amd/amdgpu/amdgpu_drv.c,v
retrieving revision 1.63
diff -u -p -r1.63 amdgpu_drv.c
--- sys/dev/pci/drm/amd/amdgpu/amdgpu_drv.c 5 Jul 2025 23:44:49 -0000 1.63
+++ sys/dev/pci/drm/amd/amdgpu/amdgpu_drv.c 18 Jul 2025 20:20:49 -0000
@@ -3574,7 +3574,7 @@ amdgpu_wsioctl(void *v, u_long cmd, cadd
case WSDISPLAYIO_PARAM_BRIGHTNESS:
bd->props.brightness = dp->curval;
backlight_update_status(bd);
- knote_locked(&adev->ddev.note, NOTE_CHANGE);
+ knote(&adev->ddev.note, NOTE_CHANGE);
return 0;
}
break;
Index: sys/dev/pci/drm/i915/i915_driver.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/i915/i915_driver.c,v
retrieving revision 1.22
diff -u -p -r1.22 i915_driver.c
--- sys/dev/pci/drm/i915/i915_driver.c 19 May 2025 21:48:28 -0000 1.22
+++ sys/dev/pci/drm/i915/i915_driver.c 18 Jul 2025 20:20:49 -0000
@@ -1972,7 +1972,7 @@ inteldrm_wsioctl(void *v, u_long cmd, ca
case WSDISPLAYIO_PARAM_BRIGHTNESS:
bd->props.brightness = dp->curval;
backlight_update_status(bd);
- knote_locked(&dev_priv->drm.note, NOTE_CHANGE);
+ knote(&dev_priv->drm.note, NOTE_CHANGE);
return 0;
}
break;
Index: sys/dev/pci/drm/include/drm/drm_device.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/include/drm/drm_device.h,v
retrieving revision 1.11
diff -u -p -r1.11 drm_device.h
--- sys/dev/pci/drm/include/drm/drm_device.h 7 Feb 2025 03:03:30 -0000 1.11
+++ sys/dev/pci/drm/include/drm/drm_device.h 18 Jul 2025 20:20:49 -0000
@@ -109,6 +109,7 @@ struct drm_device {
bus_dma_tag_t dmat;
bus_space_tag_t bst;
+ struct mutex note_mtx;
struct klist note;
struct pci_dev _pdev;
struct pci_dev *pdev;
Index: sys/dev/pci/drm/include/drm/drm_file.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/include/drm/drm_file.h,v
retrieving revision 1.13
diff -u -p -r1.13 drm_file.h
--- sys/dev/pci/drm/include/drm/drm_file.h 18 Jul 2025 00:12:49 -0000 1.13
+++ sys/dev/pci/drm/include/drm/drm_file.h 18 Jul 2025 20:20:49 -0000
@@ -38,7 +38,7 @@
#include <drm/drm_prime.h>
-#include <sys/selinfo.h>
+#include <sys/event.h>
struct dma_fence;
struct drm_file;
@@ -398,7 +398,7 @@ struct drm_file {
struct drm_prime_file_private prime;
#ifdef __OpenBSD__
- struct selinfo rsel;
+ struct klist rklist;
SPLAY_ENTRY(drm_file) link;
#endif
};
mp-safe drm*_filtops