Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/external/bsd/drm2/dist drm: New mechanism to suspend ioc...
details: https://anonhg.NetBSD.org/src/rev/fbd4a0ea533d
branches: trunk
changeset: 371868:fbd4a0ea533d
user: riastradh <riastradh%NetBSD.org@localhost>
date: Sat Oct 15 15:19:28 2022 +0000
description:
drm: New mechanism to suspend ioctls during system suspend.
drm drivers must opt into this by calling drm_suspend_ioctl in their
driver suspend routine, and drm_resume_ioctl in their driver resume
routine.
This is a stop-gap measure -- it would be better to fill in the
pm_runtime_* API with new pmf(9) hooks to acquire/release references
to devices for coordinating with suspend/resume, but getting the
details right is tricky, and this stop-gap is enough to get i915
suspend/resume to work reliably on my Kaby Lake laptop. Rather than
wait until I've got all the details right, let's just go with this
stop-gap for now.
diffstat:
sys/external/bsd/drm2/dist/drm/drm_drv.c | 23 +++++++-
sys/external/bsd/drm2/dist/drm/drm_ioctl.c | 63 ++++++++++++++++++++-
sys/external/bsd/drm2/dist/include/drm/drm_device.h | 7 ++-
sys/external/bsd/drm2/dist/include/drm/drm_ioctl.h | 4 +-
4 files changed, 91 insertions(+), 6 deletions(-)
diffs (216 lines):
diff -r c87a0522a349 -r fbd4a0ea533d sys/external/bsd/drm2/dist/drm/drm_drv.c
--- a/sys/external/bsd/drm2/dist/drm/drm_drv.c Sat Oct 15 14:54:21 2022 +0000
+++ b/sys/external/bsd/drm2/dist/drm/drm_drv.c Sat Oct 15 15:19:28 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: drm_drv.c,v 1.23 2022/07/17 14:11:18 riastradh Exp $ */
+/* $NetBSD: drm_drv.c,v 1.24 2022/10/15 15:19:28 riastradh Exp $ */
/*
* Created: Fri Jan 19 10:48:35 2001 by faith%acm.org@localhost
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_drv.c,v 1.23 2022/07/17 14:11:18 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_drv.c,v 1.24 2022/10/15 15:19:28 riastradh Exp $");
#include <linux/debugfs.h>
#include <linux/fs.h>
@@ -695,6 +695,12 @@
mutex_init(&dev->filelist_mutex);
mutex_init(&dev->clientlist_mutex);
mutex_init(&dev->master_mutex);
+#ifdef __NetBSD__
+ mutex_init(&dev->suspend_lock);
+ DRM_INIT_WAITQUEUE(&dev->suspend_cv, "drmsusp");
+ dev->active_ioctls = 0;
+ dev->suspender = NULL;
+#endif
dev->sc_monitor_hotplug.smpsw_name = PSWITCH_HK_DISPLAY_CYCLE;
dev->sc_monitor_hotplug.smpsw_type = PSWITCH_TYPE_HOTKEY;
@@ -757,6 +763,12 @@
#ifndef __NetBSD__ /* XXX drm sysfs */
put_device(dev->dev);
#endif
+#ifdef __NetBSD__
+ KASSERT(dev->suspender == NULL);
+ KASSERT(dev->active_ioctls == 0);
+ DRM_DESTROY_WAITQUEUE(&dev->suspend_cv);
+ mutex_destroy(&dev->suspend_lock);
+#endif
mutex_destroy(&dev->master_mutex);
mutex_destroy(&dev->clientlist_mutex);
mutex_destroy(&dev->filelist_mutex);
@@ -844,6 +856,13 @@
put_device(dev->dev);
#endif
+#ifdef __NetBSD__
+ KASSERT(dev->suspender == NULL);
+ KASSERT(dev->active_ioctls == 0);
+ DRM_DESTROY_WAITQUEUE(&dev->suspend_cv);
+ mutex_destroy(&dev->suspend_lock);
+#endif
+
mutex_destroy(&dev->master_mutex);
mutex_destroy(&dev->clientlist_mutex);
mutex_destroy(&dev->filelist_mutex);
diff -r c87a0522a349 -r fbd4a0ea533d sys/external/bsd/drm2/dist/drm/drm_ioctl.c
--- a/sys/external/bsd/drm2/dist/drm/drm_ioctl.c Sat Oct 15 14:54:21 2022 +0000
+++ b/sys/external/bsd/drm2/dist/drm/drm_ioctl.c Sat Oct 15 15:19:28 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: drm_ioctl.c,v 1.23 2022/08/27 21:24:15 riastradh Exp $ */
+/* $NetBSD: drm_ioctl.c,v 1.24 2022/10/15 15:19:28 riastradh Exp $ */
/*
* Created: Fri Jan 8 09:01:26 1999 by faith%valinux.com@localhost
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_ioctl.c,v 1.23 2022/08/27 21:24:15 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_ioctl.c,v 1.24 2022/10/15 15:19:28 riastradh Exp $");
#include <linux/export.h>
#include <linux/nospec.h>
@@ -739,6 +739,58 @@
#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
+#ifdef __NetBSD__
+/* ioctl suspend/resume */
+
+static void
+drm_ioctl_enter(struct drm_device *dev)
+{
+ int ret __diagused;
+
+ mutex_lock(&dev->suspend_lock);
+ DRM_WAIT_NOINTR_UNTIL(ret, &dev->suspend_cv, &dev->suspend_lock,
+ dev->suspender == NULL);
+ KASSERTMSG(ret == 0, "error=%d", -ret);
+ dev->active_ioctls++;
+ mutex_unlock(&dev->suspend_lock);
+}
+
+static void
+drm_ioctl_exit(struct drm_device *dev)
+{
+
+ mutex_lock(&dev->suspend_lock);
+ KASSERT(dev->suspender == NULL);
+ if (--dev->active_ioctls == 0)
+ DRM_WAKEUP_ALL(&dev->suspend_cv, &dev->suspend_lock);
+ mutex_unlock(&dev->suspend_lock);
+}
+
+void
+drm_suspend_ioctl(struct drm_device *dev)
+{
+ int ret;
+
+ mutex_lock(&dev->suspend_lock);
+ DRM_WAIT_NOINTR_UNTIL(ret, &dev->suspend_cv, &dev->suspend_lock,
+ dev->suspender == NULL && dev->active_ioctls == 0);
+ dev->suspender = curlwp;
+ mutex_unlock(&dev->suspend_lock);
+}
+
+void
+drm_resume_ioctl(struct drm_device *dev)
+{
+
+ mutex_lock(&dev->suspend_lock);
+ KASSERT(dev->suspender);
+ KASSERT(dev->active_ioctls == 0);
+ dev->suspender = NULL;
+ DRM_WAKEUP_ALL(&dev->suspend_cv, &dev->suspend_lock);
+ mutex_unlock(&dev->suspend_lock);
+}
+#endif
+
/**
* DOC: driver specific ioctls
*
@@ -805,6 +857,8 @@
if (unlikely(retcode))
return retcode;
+ drm_ioctl_enter(dev);
+
/* Enforce sane locking for modern driver ioctls. */
if (likely(!drm_core_check_feature(dev, DRIVER_LEGACY)) ||
(flags & DRM_UNLOCKED))
@@ -814,6 +868,9 @@
retcode = func(dev, kdata, file_priv);
mutex_unlock(&drm_global_mutex);
}
+
+ drm_ioctl_exit(dev);
+
return retcode;
}
EXPORT_SYMBOL(drm_ioctl_kernel);
@@ -900,6 +957,7 @@
data0 = buf;
}
+ drm_ioctl_enter(dev);
if ((drm_core_check_feature(dev, DRIVER_MODESET) && is_driver_ioctl) ||
ISSET(ioctl->flags, DRM_UNLOCKED)) {
/* XXX errno Linux->NetBSD */
@@ -910,6 +968,7 @@
error = -(*ioctl->func)(dev, data0, file);
mutex_unlock(&drm_global_mutex);
}
+ drm_ioctl_exit(dev);
/* If we used a temporary buffer, copy it back out. */
if (data != data0)
diff -r c87a0522a349 -r fbd4a0ea533d sys/external/bsd/drm2/dist/include/drm/drm_device.h
--- a/sys/external/bsd/drm2/dist/include/drm/drm_device.h Sat Oct 15 14:54:21 2022 +0000
+++ b/sys/external/bsd/drm2/dist/include/drm/drm_device.h Sat Oct 15 15:19:28 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: drm_device.h,v 1.10 2021/12/22 12:05:24 riastradh Exp $ */
+/* $NetBSD: drm_device.h,v 1.11 2022/10/15 15:19:28 riastradh Exp $ */
#ifndef _DRM_DEVICE_H_
#define _DRM_DEVICE_H_
@@ -12,6 +12,7 @@
#include <drm/drm_mode_config.h>
#ifdef __NetBSD__
+#include <drm/drm_wait_netbsd.h>
#include <dev/sysmon/sysmonvar.h>
#endif
@@ -332,6 +333,10 @@
#ifdef __NetBSD__
struct sysmon_pswitch sc_monitor_hotplug;
+ struct mutex suspend_lock;
+ drm_waitqueue_t suspend_cv;
+ uint64_t active_ioctls;
+ struct lwp *suspender;
#endif
/* Everything below here is for legacy driver, never use! */
diff -r c87a0522a349 -r fbd4a0ea533d sys/external/bsd/drm2/dist/include/drm/drm_ioctl.h
--- a/sys/external/bsd/drm2/dist/include/drm/drm_ioctl.h Sat Oct 15 14:54:21 2022 +0000
+++ b/sys/external/bsd/drm2/dist/include/drm/drm_ioctl.h Sat Oct 15 15:19:28 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: drm_ioctl.h,v 1.4 2021/12/19 01:56:08 riastradh Exp $ */
+/* $NetBSD: drm_ioctl.h,v 1.5 2022/10/15 15:19:28 riastradh Exp $ */
/*
* Internal Header for the Direct Rendering Manager
@@ -178,6 +178,8 @@
int drm_ioctl_permit(u32 flags, struct drm_file *file_priv);
#ifdef __NetBSD__
int drm_ioctl(struct file *, unsigned long, void *);
+void drm_suspend_ioctl(struct drm_device *);
+void drm_resume_ioctl(struct drm_device *);
#else
long drm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
#endif
Home |
Main Index |
Thread Index |
Old Index