etnaviv-gpu 134000.gpu: MMU fault status 0x00000002 on i.XM6 Quad Plus

Russell King - ARM Linux linux at armlinux.org.uk
Thu Aug 31 10:11:02 UTC 2017


On Thu, Aug 31, 2017 at 09:41:01AM +0100, Russell King - ARM Linux wrote:
> On Wed, Aug 30, 2017 at 06:40:09PM +0100, Luís Mendes wrote:
> > Hi,
> > 
> > I've reduced the set of cases that cause the copy areas to fail to single
> > logic condition on void etnaviv_accel_CopyNtoN(...).
> > I was able to fix the screen with:
> > ...
> > if (pSrc->height != pDst->height) {
> >         syslog(LOG_WARNING, "Mismatch src.w=%d, dst.w=%d\n", pSrc->height,
> > pDst->height);
> >         goto fallback;
> > }
> > ...
> > 
> > What is happening is that areas that fail to copy have a pSrc.height value
> > of 24 pixels, but pDst.height value of 25 pixels, etc.
> 
> It's also important to know the pSrc and pDst y, and dy values.
> 
> If these are all zero, what we're being asked to do is to copy a
> drawable that is 24 pixels high into the top of a drawable that is
> 25 pixels high.  This function is only (afaik) defined for copying.
> So what should it be doing with the extra line that the destination
> has if the set of boxes are requesting that line be written?
> 
> from what I can see in the Xorg fb layer, it entirely ignores the
> boundaries of the drawable, and just copies from the source even if
> this means overflowing its width and height, which sounds very
> problematical as that can end up running off the end of the allcoated
> memory - or in the case of a GPU, end up running off the end of the
> mapped buffer and causing GPU faults / crashes.
> 
> However, miDoCopy() should be generating exposures for those areas
> (see the comments in the Xorg source above miHandleExposures().)  It
> sounds like this is failing in some way, but that is all generic Xorg
> code, so should afflict all DDX drivers including the fallbacks.

Having read the Xserver-spec, I'm fairly convinced that how I'm
implementing etnaviv_accel_CopyNtoN() is correct:

| CopyArea copies a rectangle of pixels from one drawable to another of
| the same depth.  To effect scrolling, this must be able to copy from
| any drawable to itself, overlapped.  No squeezing or stretching is done
| because the source and destination are the same size.  However,
| everything is still clipped to the clip regions of the destination
| drawable.

| If pGC->graphicsExposures is True, any portions of the destination which
| were not valid in the source (either occluded by covering windows, or
| outside the bounds of the drawable) should be collected together and
| returned as a region (if this resultant region is empty, NULL can be
| returned instead).  Furthermore, the invalid bits of the source are
| not copied to the destination and (when the destination is a window)
| are filled with the background tile.  The sample routine
| miHandleExposures generates the appropriate return value and fills the
| invalid area using pScreen->PaintWindowBackground.

| For instance, imagine a window that is partially obscured by other
| windows in front of it.  As text is scrolled on your window, the pixels
| that are scrolled out from under obscuring windows will not be
| available on the screen to copy to the right places, and so an exposure
| event must be sent for the client to correctly repaint them.  Of
| course, if you implement backing store, you could do this without resorting
| to exposure events.

The case we have here is "outside the bounds of the drawable".  The
above is pretty clear about how that should be handled.  miDoCopy()
handles all these bits internally by calling miHandleExposures()
after calling the user supplied function to do the copying work.  In
our case, that function is etnaviv_accel_CopyNtoN(), and the only
thing it needs to do is to copy the valid bits of the drawables.

This is what:

        /* Calculate the overall extent */
        extent.x1 = max_t(short, pDst->x, pSrc->x - dx);
        extent.y1 = max_t(short, pDst->y, pSrc->y - dy);
        extent.x2 = min_t(short, pDst->x + pDst->width,
                                 pSrc->x + pSrc->width - dx);
        extent.y2 = min_t(short, pDst->y + pDst->height,
                                 pSrc->y + pSrc->height - dy);

is doing.  "extent" is the overall valid region in the destination
pixmap that is the union of the source drawable and destination
drawable, with the source drawable appropriately offset by the
copying delta (dx,dy).  We use "extent" to pass to the GPU as the
destination clip for the entire operation.

Now, the interesting thing is that this code has been tested by
the X Test Suite (Xlib9/CopyArea test) and it fully passes:

XCopyArea (1/36): PASS
XCopyArea (2/36): PASS
XCopyArea (3/36): PASS
XCopyArea (4/36): PASS
XCopyArea (5/36): PASS
XCopyArea (6/36): PASS
XCopyArea (7/36): PASS
XCopyArea (8/36): PASS
XCopyArea (9/36): PASS
XCopyArea (10/36): PASS
XCopyArea (11/36): PASS
XCopyArea (12/36): PASS
XCopyArea (13/36): PASS
XCopyArea (14/36): PASS
XCopyArea (15/36): PASS
XCopyArea (16/36): PASS
XCopyArea (17/36): PASS
XCopyArea (18/36): PASS
XCopyArea (19/36): PASS
XCopyArea (20/36): PASS
XCopyArea (21/36): PASS
XCopyArea (22/36): PASS
XCopyArea (23/36): PASS
XCopyArea (24/36): PASS
XCopyArea (25/36): PASS
XCopyArea (26/36): PASS
XCopyArea (27/36): UNRESOLVED
XCopyArea (28/36): PASS
XCopyArea (29/36): PASS
XCopyArea (30/36): UNRESOLVED
XCopyArea (31/36): UNRESOLVED
XCopyArea (32/36): UNRESOLVED
XCopyArea (33/36): PASS
XCopyArea (34/36): UNRESOLVED
XCopyArea (35/36): PASS
XCopyArea (36/36): PASS

Test 4 tests the exposure events.

So, I'm wondering if although the DDX appears to be compliant, and
tests as being compliant, Mate is relying on buggy behaviour by
both the generic unaccelerated fb backend and many other DDX?

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
According to speedtest.net: 8.21Mbps down 510kbps up


More information about the etnaviv mailing list