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

Bug#236187: xserver-xfree86: [r128] GL lockups



On Sun, Mar 07, 2004 at 02:45:59PM -0500, Daniel Jacobowitz wrote:
> On Sun, Mar 07, 2004 at 06:21:11PM +0100, Michel Dänzer wrote:
> > On Sun, 2004-03-07 at 17:38, Daniel Jacobowitz wrote:
> > > 
> > > Downgrading to xserver-xfree86 4.2.1-16 has eliminated the problem so
> > > my money is on the 4.3.0 r128 driver.
> > 
> > If you agree that your problem seems related to
> > http://bugs.xfree86.org/show_bug.cgi?id=271, can you try the workarounds
> > discussed there?
> 
> I'll give it a try.  Looking at the code in 4.2.1 and 4.3.0 (you
> probably know all this already, I'm just educating myself):

> And yes, looking the source to the DRM module I'm running, it does
> honor the timeout.  Which defaults to 10_000, so the old working
> timeout was 10K * 2M * 32, and the new not working timeout is 10K * 32.
> And the max settable timeout is 100K * 32.  So it seems pretty clear
> that, however long it takes to return to idle, it's longer than this
> vastly reduced timeout.
> 
> I'm going to try your suggested changes now, along with some
> instrumentation to see how long resets are really taking.

I've verified that some xscreensaver modules take up to fifty (as
opposed to 32) calls to the ioctl before they quiesce.  Probably it
gets even higher.  So, this is the same problem.

The code I'm testing is more patient, so I don't know if your fix to
call R128CCE_STOP helps with the actual resets; the other fellow in the
bug report said that it did though.  Here's what I was using for
testing.

--- xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c.orig	2004-03-07 14:34:13.000000000 -0500
+++ xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c	2004-03-07 14:39:29.000000000 -0500
@@ -229,25 +229,35 @@
 void R128CCEWaitForIdle(ScrnInfoPtr pScrn)
 {
     R128InfoPtr info = R128PTR(pScrn);
-    int         ret, i;
+    int         ret, i, j;
 
     FLUSH_RING();
 
     for (;;) {
+        j = 0;
+
+        do {
         i = 0;
         do {
             ret = drmCommandNone(info->drmFD, DRM_R128_CCE_IDLE);
         } while ( ret && errno == EBUSY && i++ < R128_IDLE_RETRY );
+        } while ( ret && errno == EBUSY && j++ < R128_TIMEOUT );
 
 	if (ret && ret != -EBUSY) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		       "%s: CCE idle %d\n", __FUNCTION__, ret);
 	}
 
+	if (i != 0 || j != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "%s: CCE idle took j == %d\n", __FUNCTION__, j);
+	}
+
 	if (ret == 0) return;
 
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		   "Idle timed out, resetting engine...\n");
+	R128CCE_STOP(pScrn, info);
 	R128EngineReset(pScrn);
 
 	/* Always restart the engine when doing CCE 2D acceleration */


-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer



Reply to: