Re: [Bug #12765] i915 VT switch with AIGLX causes X lock up

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, 26 Apr 2009 11:46:26 +0200 (CEST)
"Rafael J. Wysocki" <rjw@xxxxxxx> wrote:

> This message has been generated automatically as a part of a report
> of regressions introduced between 2.6.28 and 2.6.29.
> 
> The following bug entry is on the current list of known regressions
> introduced between 2.6.28 and 2.6.29.  Please verify if it still
> should be listed and let me know (either way).
> 
> 
> Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=12765
> Subject		: i915 VT switch with AIGLX causes X lock up
> Submitter	: Sitsofe Wheeler <sitsofe@xxxxxxxxx>
> Date		: 2009-02-21 15:38 (65 days old)
> First-Bad-Commit:
> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=14d200c5e5bd19219d930bbb9a5a22758c8f5bec
> References	:
> http://marc.info/?l=linux-kernel&m=123523074304955&w=4

I think we had a workaround for this (attached), but it sounds like
Robert has tracked down the root cause (search for "Broken vblanks on
Intel" on dri-devel@xxxxxxxxxxxxxxxxxxxxx).  Will try to get the fix
into the Intel driver soon.  Fortunately this doesn't seem to be biting
a lot of people (at least not that I've heard); I certainly have a hard
time reproducing it.

-- 
Jesse Barnes, Intel Open Source Technology Center
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 69aa0ab..c41cba4 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -341,7 +341,7 @@ int drm_control(struct drm_device *dev, void *data,
  * vblank events since the system was booted, including lost events due to
  * modesetting activity.
  */
-u32 drm_vblank_count(struct drm_device *dev, int crtc)
+unsigned int drm_vblank_count(struct drm_device *dev, int crtc)
 {
 	return atomic_read(&dev->_vblank_count[crtc]);
 }
@@ -522,6 +522,11 @@ out:
 	return ret;
 }
 
+#define frame_after_eq(a,b)	       \
+	(typecheck(unsigned int, a) && \
+	 typecheck(unsigned int, b) && \
+	 ((int)(a) - (int)(b) >= 0))
+
 /**
  * Wait for VBLANK.
  *
@@ -589,10 +594,12 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
 	DRM_DEBUG("waiting on vblank count %d, crtc %d\n",
 		  vblwait->request.sequence, crtc);
 	dev->last_vblank_wait[crtc] = vblwait->request.sequence;
+
+	/* Wait for the sequence number to pass or IRQs to get disabled */
 	DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ,
-		    (((drm_vblank_count(dev, crtc) -
-		       vblwait->request.sequence) <= (1 << 23)) ||
-		     !dev->irq_enabled));
+		    frame_after_eq(drm_vblank_count(dev, crtc),
+				   vblwait->request.sequence) ||
+		    !dev->irq_enabled);
 
 	if (ret != -EINTR) {
 		struct timeval now;

[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux