[Intel-gfx] [PATCH] [drm/i915] Shut down retire work handler on lastclose or leavevt

Keith Packard keithp at keithp.com
Wed Oct 15 05:52:17 CEST 2008


From b9c4200fc5923bae72c8f90365da79b94c9ee284 Mon Sep 17 00:00:00 2001
From: Keith Packard <keithp at keithp.com>
Date: Tue, 14 Oct 2008 20:48:42 -0700
Subject: [PATCH] [drm/i915] Shut down retire work handler on lastclose or leavevt

At leavevt and lastclose time, cancel any pending retire work handler
invocation, and keep the retire work handler from requeuing itself if it is
currently running. This ensure that the retire work handler does not run
when the ring is shut down, which would otherwise cause a nice crash.

Signed-off-by: Keith Packard <keithp at keithp.com>
---
 drivers/gpu/drm/i915/i915_drv.h |    7 +++++++
 drivers/gpu/drm/i915/i915_gem.c |   26 +++++++++++++++++++++++++-
 2 files changed, 32 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 025100b..c698b5c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -319,6 +319,13 @@ typedef struct drm_i915_private {
 		 */
 		int wedged;
 
+		/**
+		 * Flag set while the device is shutting down the ring
+		 * This is used to prevent the retire work handler
+		 * from re-queueing itself during lastclose or leavevt
+		 */
+		int ring_stopping;
+
 		/** Bit 6 swizzling required for X tiling */
 		uint32_t bit_6_swizzle_x;
 		/** Bit 6 swizzling required for Y tiling */
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index a23f2c9..3c87248 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -731,7 +731,8 @@ i915_gem_retire_work_handler(struct work_struct *work)
 
 	mutex_lock(&dev->struct_mutex);
 	i915_gem_retire_requests(dev);
-	if (!list_empty(&dev_priv->mm.request_list))
+	if (!dev_priv->mm.ring_stopping &&
+	    !list_empty(&dev_priv->mm.request_list))
 		schedule_delayed_work(&dev_priv->mm.retire_work, HZ);
 	mutex_unlock(&dev->struct_mutex);
 }
@@ -2465,6 +2466,25 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev)
 	}
 }
 
+static void
+i915_gem_cancel_retire_work_handler(struct drm_device *dev)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+
+	mutex_lock(&dev->struct_mutex);
+	dev_priv->mm.ring_stopping = 1;
+	mutex_unlock(&dev->struct_mutex);
+
+	/* Must not hold the lock here; the work handler may
+	 * be running
+	 */
+	cancel_delayed_work_sync(&dev_priv->mm.retire_work);
+
+	mutex_lock(&dev->struct_mutex);
+	dev_priv->mm.ring_stopping = 0;
+	mutex_unlock(&dev->struct_mutex);
+}
+
 int
 i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
 		       struct drm_file *file_priv)
@@ -2500,6 +2520,8 @@ i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
 {
 	int ret;
 
+	i915_gem_cancel_retire_work_handler(dev);
+
 	mutex_lock(&dev->struct_mutex);
 	ret = i915_gem_idle(dev);
 	if (ret == 0)
@@ -2517,6 +2539,8 @@ i915_gem_lastclose(struct drm_device *dev)
 	int ret;
 	drm_i915_private_t *dev_priv = dev->dev_private;
 
+	i915_gem_cancel_retire_work_handler(dev);
+
 	mutex_lock(&dev->struct_mutex);
 
 	if (dev_priv->ring.ring_obj != NULL) {
-- 
1.5.6.5


-- 
keith.packard at intel.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
URL: <http://lists.freedesktop.org/archives/intel-gfx/attachments/20081014/ecc6d04b/attachment.sig>


More information about the Intel-gfx mailing list