All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] drm: Add flag to make whole ioctl critical section for unplug
@ 2023-01-25 17:16 Stanislaw Gruszka
  0 siblings, 0 replies; only message in thread
From: Stanislaw Gruszka @ 2023-01-25 17:16 UTC (permalink / raw)
  To: dri-devel; +Cc: Stanislaw Gruszka, Jacek Lawrynowicz, Thomas Zimmermann

drm_dev_is_unplugged() check is inherently racy as unplug can happen
just after this check. Add DRM_UNPLUG_SAFE ioctl flag to keep
the whole ioctl func call within drm_dev_enter() ... drm_dev_exit().

This could be enabled by drivers for individual ioctl's .

Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
---
 drivers/gpu/drm/drm_ioctl.c | 22 +++++++++++++++-------
 include/drm/drm_ioctl.h     |  7 +++++++
 2 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index ca2a6e6101dc..9943f38c6b05 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -773,24 +773,32 @@ long drm_ioctl_kernel(struct file *file, drm_ioctl_t *func, void *kdata,
 {
 	struct drm_file *file_priv = file->private_data;
 	struct drm_device *dev = file_priv->minor->dev;
-	int retcode;
+	const bool global_mutex = drm_core_check_feature(dev, DRIVER_LEGACY) &&
+				  !(flags & DRM_UNLOCKED);
+	const bool unplug_safe = flags & DRM_UNPLUG_SAFE;
+	int retcode, idx;
 
-	if (drm_dev_is_unplugged(dev))
+	if (!drm_dev_enter(dev, &idx))
 		return -ENODEV;
+	if (!unplug_safe)
+		drm_dev_exit(idx);
 
 	retcode = drm_ioctl_permit(flags, file_priv);
 	if (unlikely(retcode))
-		return retcode;
+		goto out;
 
-	/* Enforce sane locking for modern driver ioctls. */
-	if (likely(!drm_core_check_feature(dev, DRIVER_LEGACY)) ||
-	    (flags & DRM_UNLOCKED))
+	if (likely(!global_mutex)) {
 		retcode = func(dev, kdata, file_priv);
-	else {
+	} else {
 		mutex_lock(&drm_global_mutex);
 		retcode = func(dev, kdata, file_priv);
 		mutex_unlock(&drm_global_mutex);
 	}
+
+out:
+	if (unplug_safe)
+		drm_dev_exit(idx);
+
 	return retcode;
 }
 EXPORT_SYMBOL(drm_ioctl_kernel);
diff --git a/include/drm/drm_ioctl.h b/include/drm/drm_ioctl.h
index 6ed61c371f6c..894ce775ff12 100644
--- a/include/drm/drm_ioctl.h
+++ b/include/drm/drm_ioctl.h
@@ -130,6 +130,13 @@ enum drm_ioctl_flags {
 	 * not set DRM_AUTH because they do not require authentication.
 	 */
 	DRM_RENDER_ALLOW	= BIT(5),
+	/**
+	 * @DRM_UNPUG_SAFE:
+	 *
+	 * Whether &drm_ioctl_desc.func should be called as unplug critical
+	 * section protected by drm_dev_enter() / drm_dev_exit()
+	 */
+	DRM_UNPLUG_SAFE		= BIT(6),
 };
 
 /**
-- 
2.25.1


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2023-01-25 17:18 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-25 17:16 [RFC] drm: Add flag to make whole ioctl critical section for unplug Stanislaw Gruszka

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.