Bug 11264

Summary: xv crashes Xorg on resume from software suspend
Product: xorg Reporter: Mattias Nissler <mattias.nissler>
Component: Server/GeneralAssignee: Xorg Project Team <xorg-team>
Status: RESOLVED FIXED QA Contact: Xorg Project Team <xorg-team>
Severity: normal    
Priority: medium CC: ht990332
Version: git   
Hardware: x86-64 (AMD64)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:

Description Mattias Nissler 2007-06-14 00:30:38 UTC
The server sometimes crashes when I resume my swsusp-suspended Linux system. If I don't use xv before the crash (i.e. don't watch videos or the like), the server will not crash.

This happens with gentoo's xorg-server-1.3.0.0 build, here is the -version output:

X Window System Version 1.3.0
Release Date: 19 April 2007
X Protocol Version 11, Revision 0, Release 1.3
Build Operating System: UNKNOWN 
Current Operating System: Linux kea 2.6.22-rc4-mattias_rt2x00 #12 SMP PREEMPT Sat Jun 9 09:37:53 CEST 2007 x86_64
Build Date: 13 June 2007
        Before reporting problems, check http://wiki.x.org
        to make sure that you have the latest version.
Module Loader present

Here is the relevant section of Xorg.0.log:

(WW) Open ACPI failed (/var/run/acpid.socket) (No such file or directory)
(II) No APM support in BIOS or kernel
(II) AIGLX: Resuming AIGLX clients after VT switch
(**) RADEON(0): RADEONEnterVT
(**) RADEON(0): RADEONModeInit()
1600x1200     229.50  1600 1664 1856 2160  1200 1201 1204 1250 (24,32) +H +V
1600x1200     229.50  1600 1664 1856 2160  1200 1201 1204 1250 (24,32) +H +V
(**) RADEON(0): Pitch = 13107400 bytes (virtualX = 1600, displayWidth = 1600)
(**) RADEON(0): dc=22950, of=22950, fd=60, pd=1
(**) RADEON(0): RADEONInit returns 0x6e6b58
(**) RADEON(0): RADEONRestoreMode()
(**) RADEON(0): RADEONRestoreMode(0x6e6b58)
(**) RADEON(0): RADEONRestoreMemMapRegisters() : 
(**) RADEON(0):   MC_FB_LOCATION   : 0xefffe000
(**) RADEON(0):   MC_AGP_LOCATION  : 0xffffffc0
(**) RADEON(0):   Map Changed ! Applying ...
(**) RADEON(0):   Map applied, resetting engine ...
(**) RADEON(0): Updating display base addresses...
(**) RADEON(0): Memory map updated.
(**) RADEON(0): Programming CRTC1, offset: 0x00000000
(**) RADEON(0): Wrote: 0x00000007 0x0000003c 0x00000000 (0x0000bf00)
(**) RADEON(0): Wrote: rd=7, fd=60, pd=0
(II) RADEON(0): [RESUME] Attempting to re-init Radeon hardware.
(**) RADEON(0): EngineRestore (32/32)
(**) RADEON(0): EngineRestore (32/32)

Backtrace:
0: /usr/bin/Xorg(xf86SigHandler+0x6d) [0x47d5ae]
1: /lib/libc.so.6 [0x2b6695285650]
2: /usr/bin/Xorg [0x47c233]
3: /usr/bin/Xorg [0x47c68f]
4: /usr/bin/Xorg(TraverseTree+0x24) [0x434e64]
5: /usr/bin/Xorg [0x47c6fe]
6: /usr/lib64/xorg/modules/extensions//libglx.so [0x2b6695c437f1]
7: /usr/bin/Xorg(xf86Wakeup+0x3e4) [0x47e90a]
8: /usr/bin/Xorg(WakeupHandler+0x4a) [0x44c2b7]
9: /usr/bin/Xorg(WaitForSomething+0x1c0) [0x54fe64]
10: /usr/bin/Xorg(Dispatch+0x8b) [0x4489ac]
11: /usr/bin/Xorg(main+0x458) [0x4330ad]
12: /lib/libc.so.6(__libc_start_main+0xe3) [0x2b6695273323]
13: /usr/bin/Xorg(FontFileCompleteXLFD+0xa1) [0x432439]

Fatal server error:
Caught signal 11.  Server aborting

(II) AIGLX: Suspending AIGLX clients for VT switch
(**) RADEON(0): RADEONLeaveVT
(**) RADEON(0): EngineRestore (32/32)
(**) RADEON(0): RADEONRestore
(**) RADEON(0): RADEONRestoreMode()
(**) RADEON(0): RADEONRestoreMode(0x6e61a8)
(**) RADEON(0): RADEONRestoreMemMapRegisters() : 
(**) RADEON(0):   MC_FB_LOCATION   : 0xefffe000
(**) RADEON(0):   MC_AGP_LOCATION  : 0x003f0000
(**) RADEON(0):   Map Changed ! Applying ...
(**) RADEON(0):   Map applied, resetting engine ...
(**) RADEON(0): Updating display base addresses...
(**) RADEON(0): Memory map updated.
(**) RADEON(0): Programming CRTC1, offset: 0x00000000
(**) RADEON(0): Wrote: 0x001c0007 0x00060065 0x00000000 (0x0000bf00)
(**) RADEON(0): Wrote: rd=7, fd=101, pd=6
(**) RADEON(0): Ok, leaving now...


I have built a debugging server to find out where exactly it crashes. The crash is in xf86XVRegetVideo, which I verbosified like so:

static int
xf86XVRegetVideo(XvPortRecPrivatePtr portPriv)
{
  RegionRec WinRegion;
  RegionRec ClipRegion;
  BoxRec WinBox;
  ScreenPtr pScreen;
  int ret = Success;
  Bool clippedAway = FALSE;

  xf86Msg(X_INFO, "xf86XVRegetVideo: portPriv %p\n", portPriv);
  xf86Msg(X_INFO, "xf86XVRegetVideo: portPriv->pDraw %p\n", portPriv->pDraw);

  pScreen = portPriv->pDraw->pScreen;

  xf86Msg(X_INFO, "xf86XVRegetVideo: pScreen %p\n", pScreen);

  xf86XVUpdateCompositeClip(portPriv);

  xf86Msg(X_INFO, "xf86XVRegetVideo: check 1\n");

  /* translate the video region to the screen */
  WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
  WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
  WinBox.x2 = WinBox.x1 + portPriv->drw_w;
  WinBox.y2 = WinBox.y1 + portPriv->drw_h;

  /* clip to the window composite clip */
  REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
  REGION_NULL(pScreen, &ClipRegion);
  REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, portPriv->pCompositeClip);

  xf86Msg(X_INFO, "xf86XVRegetVideo: check 2\n");

  /* that's all if it's totally obscured */
  if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
	clippedAway = TRUE;
	goto CLIP_VIDEO_BAILOUT;
  }

  if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
     REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
  }

  xf86Msg(X_INFO, "xf86XVRegetVideo: check 3\n");

  ret = (*portPriv->AdaptorRec->GetVideo)(portPriv->pScrn,
			portPriv->vid_x, portPriv->vid_y,
			WinBox.x1, WinBox.y1,
			portPriv->vid_w, portPriv->vid_h,
			portPriv->drw_w, portPriv->drw_h,
			&ClipRegion, portPriv->DevPriv.ptr,
			portPriv->pDraw);

  if(ret == Success)
	portPriv->isOn = XV_ON;

  xf86Msg(X_INFO, "xf86XVRegetVideo: check 4\n");

CLIP_VIDEO_BAILOUT:

  xf86Msg(X_INFO, "xf86XVRegetVideo: check 5\n");

  if((clippedAway || (ret != Success)) && portPriv->isOn == XV_ON) {
	(*portPriv->AdaptorRec->StopVideo)(
		portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
	portPriv->isOn = XV_PENDING;
  }

  /* This clip was copied and only good for one shot */
  if(!portPriv->FreeCompositeClip)
     portPriv->pCompositeClip = NULL;

  REGION_UNINIT(pScreen, &WinRegion);
  REGION_UNINIT(pScreen, &ClipRegion);

  xf86Msg(X_INFO, "xf86XVRegetVideo: EXIT\n");

  return ret;
}

On the next crash it told me:

(II) xf86XVRegetVideo: portPriv 0x711ac0
(II) xf86XVRegetVideo: portPriv->pDraw (nil)

Backtrace:
0: /usr/bin/Xorg(xf86SigHandler+0x6d) [0x47d68e]
1: /lib/libc.so.6 [0x2b2b65ffb650]
2: /usr/bin/Xorg [0x47c258]
3: /usr/bin/Xorg [0x47c772]
4: /usr/bin/Xorg(TraverseTree+0x24) [0x434e64]
5: /usr/bin/Xorg [0x47c7e1]
6: /usr/lib64/xorg/modules/extensions//libglx.so [0x2b2b669b97f1]
7: /usr/bin/Xorg(xf86Wakeup+0x3e4) [0x47e9ea]
8: /usr/bin/Xorg(WakeupHandler+0x4a) [0x44c2b7]
9: /usr/bin/Xorg(WaitForSomething+0x1c0) [0x54ff44]
10: /usr/bin/Xorg(Dispatch+0x8b) [0x4489ac]
11: /usr/bin/Xorg(main+0x458) [0x4330ad]
12: /lib/libc.so.6(__libc_start_main+0xe3) [0x2b2b65fe9323]
13: /usr/bin/Xorg(FontFileCompleteXLFD+0xa1) [0x432439]

So, portPriv->pDraw is NULL.

So far for the investigation part. Now I need someone who knows the code well enough to figure why the NULL pointer turns up and how to fix this.

Cheers,

Mattias
Comment 1 Michel Dänzer 2007-06-14 01:16:50 UTC
Fixed in xserver commit 649e7f82d8d4333443493056b81eb20d6cf022bc, nominated for the 1.3 branch.
Comment 2 Michel Dänzer 2007-06-20 01:50:09 UTC
*** Bug 11312 has been marked as a duplicate of this bug. ***

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.