AIGLX DRI Locking

vehemens vehemens at verizon.net
Tue Nov 7 23:23:00 PST 2006


On Tuesday 07 November 2006 15:40, Adam Jackson wrote:
> On Wednesday 01 November 2006 23:55, vehemens wrote:
> > I'm attempting to run 7.2 RC1 on my freebsd (10/26/06 current snap shot),
> > with a MESA 10/29/06 snap shot, and an ATI RV250, but I'm having problems
> > with AIGLX and DRI.  In particular, there appears to be a number of
> > missing DRI locks.
> >
> > To stop it from hanging at startup, I added a dri lock to the dri.c
> > function DRIWindowExposures; as well as disabling drm locking tests in
> > radeon_cp.c for functions radeon_cp_idle, radeon_engine_reset,
> > radeon_cp_buffers, as well as radeon_state.c function radeon_cp_indirect.
> >  Yes I know it isn't pretty, but it better then a system hang.
> >
> > Any pointers would be appreciated.
>
> It sounds more like there's a number of missing DRI unlocks.
>
> What process is holding the lock when DRI hangs?

From what I can tell, nothing is holding a lock when a request fails as the 
only GL application that I'm running is the server.  Before the addition of 
the WindowExposures lock, the server never got past the initialization stage 
before a kernel hang occured.

The removal of the DRM locking checks was just a quick way of preventing other 
requests which were failing due to missing locks from hanging the kernel or 
the server.

The problem appears to be that when a particular requests fails, and a later 
request succeeds, the kernel can lockup as the drm and/or video card is not 
configured as expected due a previously failed request.

This problem does not appear to be unique to my system as it's listed as a 
known problem on the TODO list at http://wikitest.freebsd.org/ModularXorg, 
and I've seen it in bugzilla.

My initial inspection seems to suggest that the compile options are correct, 
but as there are so many levels of indirection, I could of easily missed 
something.

I also have artifacts at startup which can be cleared by running glxinfo or 
glxgears which cleans up the problem.  This one I've also seen in bugzilla, 
but have not dug into it as it appears to be an unrelated problem.

My patches which are good enough to run gnome and glxgears without hangs are 
attached for reference.  Note that my MESA snaphot is now 11/05/06.  Also 
note that RADEON_WAIT_UNTIL_IDLE commands are part of my workaround.


--- hw/xfree86/dri/dri.c.orig   Fri Oct 13 15:52:55 2006
+++ hw/xfree86/dri/dri.c        Mon Oct 30 22:06:48 2006
@@ -1577,8 +1577,12 @@
        /* unwrap */
        pScreen->WindowExposures = pDRIPriv->wrap.WindowExposures;

+       DRILock(pScreen, 0);
+
        /* call lower layers */
        (*pScreen->WindowExposures)(pWin, prgn, bsreg);
+
+       DRIUnlock(pScreen);

        /* rewrap */
        pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures;

--- /usr/cvsup/xorg_current/mesa/drm/shared-core/radeon_cp.c    Sat Sep 16 
00:01:49 2006
+++ /usr/cvsup/drm-mine/shared-core/radeon_cp.c Sun Oct 22 03:54:49 2006
@@ -1937,7 +1937,7 @@
        drm_radeon_private_t *dev_priv = dev->dev_private;
        DRM_DEBUG("\n");

-       LOCK_TEST_WITH_RETURN(dev, filp);
+//     LOCK_TEST_WITH_RETURN(dev, filp);

        return radeon_do_cp_idle(dev_priv);
 }
@@ -1956,7 +1956,7 @@
        DRM_DEVICE;
        DRM_DEBUG("\n");

-       LOCK_TEST_WITH_RETURN(dev, filp);
+//     LOCK_TEST_WITH_RETURN(dev, filp);
 
        return radeon_do_engine_reset(dev);
 }
@@ -2150,7 +2150,7 @@
        drm_dma_t __user *argp = (void __user *)data;
        drm_dma_t d;
 
-       LOCK_TEST_WITH_RETURN(dev, filp);
+//     LOCK_TEST_WITH_RETURN(dev, filp);
 
        DRM_COPY_FROM_USER_IOCTL(d, argp, sizeof(d));


--- /usr/cvsup/xorg_current/mesa/drm/shared-core/radeon_state.c Mon Oct  9 
21:05:51 2006
+++ /usr/cvsup/drm-mine/shared-core/radeon_state.c      Mon Oct 23 16:28:43 
2006
@@ -1358,10 +1358,9 @@
        /* Wait for the 3D stream to idle before dispatching the bitblt.
         * This will prevent data corruption between the two streams.
         */
-       BEGIN_RING(2);
-
-       RADEON_WAIT_UNTIL_3D_IDLE();

+       BEGIN_RING(2);
+       RADEON_WAIT_UNTIL_IDLE();
        ADVANCE_RING();

        for (i = 0; i < nbox; i++) {
@@ -2485,7 +2484,7 @@
        drm_radeon_indirect_t indirect;
        RING_LOCALS;
 
-       LOCK_TEST_WITH_RETURN(dev, filp);
+//     LOCK_TEST_WITH_RETURN(dev, filp);
 
        if (!dev_priv) {
                DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
@@ -2911,6 +2910,7 @@
        drm_radeon_cmd_header_t header;
        int orig_nbox, orig_bufsz;
        char *kbuf = NULL;
+       RING_LOCALS;
 
        LOCK_TEST_WITH_RETURN(dev, filp);
 
@@ -2950,6 +2950,14 @@
        }
 
        orig_nbox = cmdbuf.nbox;
+
+       /* Wait for the engine to idle before the indirect buffer
+        * is processed.
+        */
+
+       BEGIN_RING(2);
+       RADEON_WAIT_UNTIL_IDLE();
+       ADVANCE_RING();
 
        if (dev_priv->microcode_version == UCODE_R300) {
                int temp;






More information about the xorg mailing list