On Friday, January 30, 2009 11:16 am Timo Aaltonen wrote:
> On Fri, 30 Jan 2009, Jesse Barnes wrote:
> > I'm not sure about Timo's problem though; this patch helps with a problem
> > he was seeing too, but he sees it after running for awhile, not at VT
> > switch. It's possible that his problem could be due to wraparound, if the
> > jumps we see at interrupt off->on time are big enough, a few DPMS events
> > could cause a wraparound related hang.  Timo, do you have a reliable way
> > of reproducing your problem?  It sounds separate from 18041 so we may
> > want to fix it differently.
>
> I understood that 18041 was already fixed by the recent'ish commits to
> drm, and I haven't been able to reproduce that since they were added to
> the jaunty kernel (and vblank was again enabled in mesa).
>
> I can reproduce the momentary freezes after changing the VT a couple of
> times. That's what happens on a suspend/resume cycle as well, so it's
> probably what triggered it in the first place. And the patch you posted
> did fix this issue for me.

Ah ok, then it probably is the same issue.  Sounds like you're just hitting 
the timeout in libdrm, which would cause apps to freeze for about a second 
after a VT switch.  I think the sequence number the apps are waiting for is 
actually less than the current one, but our current code prevents that from 
being detected.  Does this patch also fix things for you?

-- 
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;

------------------------------------------------------------------------------
This SF.net email is sponsored by:
SourcForge Community
SourceForge wants to tell your story.
http://p.sf.net/sfu/sf-spreadtheword
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to