[Intel-gfx] Interrupt handling across leave/entervt

Jesse Barnes jbarnes at virtuousgeek.org
Wed Dec 31 20:29:41 CET 2008


A patch was recently committed to uninstall the i915 interrupt handler at 
leavevt time and re-install it at entervt.  The changelog doesn't indicate why 
this was done, but I imagine it's because the interrupt handler tries to read 
the hardware status page which is torn down at leavevt time by 
cleanup_ringbuffer.

The problem with disabling interrupts is that the server may wait on a vblank 
event before the DDX has had a chance to call into the entervt ioctl, 
resulting in a hang if say compiz is running before the VT switch (see bug 
18879).

So we can either remove the HWS teardown at leavevt time along with the 
interrupt handler removal (ugly patch below), or try to work around the 
problem in libdrm by timing out vblank waits after some reasonable period (see 
the patch in 18041 for an example of that; just makes drmWaitVBlank() timeout 
after 1s).

Anyone have thoughts here?  In the KMS case we'll just leave everything set up 
and hopefully eventually get rid of the whole VT switch dance altogether, but 
we still need a solution for the current stuff.

-- 
Jesse Barnes, Intel Open Source Technology Center

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index feec3a7..cc6551a 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2530,6 +2530,10 @@ i915_gem_init_hws(struct drm_device *dev)
 	if (!I915_NEED_GFX_HWS(dev))
 		return 0;
 
+	/* Already set up */
+	if (dev_priv->hws_obj)
+		return 0;
+
 	obj = drm_gem_object_alloc(dev, 4096);
 	if (obj == NULL) {
 		DRM_ERROR("Failed to allocate status page\n");
@@ -2673,21 +2677,6 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev)
 	drm_gem_object_unreference(dev_priv->ring.ring_obj);
 	dev_priv->ring.ring_obj = NULL;
 	memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
-
-	if (dev_priv->hws_obj != NULL) {
-		struct drm_gem_object *obj = dev_priv->hws_obj;
-		struct drm_i915_gem_object *obj_priv = obj->driver_private;
-
-		kunmap(obj_priv->page_list[0]);
-		i915_gem_object_unpin(obj);
-		drm_gem_object_unreference(obj);
-		dev_priv->hws_obj = NULL;
-		memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
-		dev_priv->hw_status_page = NULL;
-
-		/* Write high address into HWS_PGA when disabling. */
-		I915_WRITE(HWS_PGA, 0x1ffff000);
-	}
 }
 
 int
@@ -2732,7 +2721,6 @@ i915_gem_leavevt_ioctl(struct drm_device *dev, void 
*data,
 	int ret;
 
 	ret = i915_gem_idle(dev);
-	drm_irq_uninstall(dev);
 
 	io_mapping_free(dev_priv->mm.gtt_mapping);
 	return ret;




More information about the Intel-gfx mailing list