diff mbox

uxa: Restore old bo on failure

Message ID 1458762277-14376-1-git-send-email-cpaul@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

cpaul@redhat.com March 23, 2016, 7:44 p.m. UTC
When we fail to do a modeset, we need to make sure that we restore the
previous bo in the event that it's changed. Otherwise we'll crash the X
server the next time we do a pageflip.

This fixes an issue with panning crashing the X server if a user tries
to set a large panning resolution such as 5200x3200, and the GPU doesn't
have enough memory to handle the bo due to being in UXA mode.

Signed-off-by: Lyude <cpaul@redhat.com>
---
 src/uxa/intel_uxa.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

Comments

Chris Wilson March 23, 2016, 9:01 p.m. UTC | #1
On Wed, Mar 23, 2016 at 03:44:37PM -0400, Lyude wrote:
> When we fail to do a modeset, we need to make sure that we restore the
> previous bo in the event that it's changed. Otherwise we'll crash the X
> server the next time we do a pageflip.
> 
> This fixes an issue with panning crashing the X server if a user tries
> to set a large panning resolution such as 5200x3200, and the GPU doesn't
> have enough memory to handle the bo due to being in UXA mode.
> 
> Signed-off-by: Lyude <cpaul@redhat.com>

Ok, the reference handling there is a little dodgy, but since this only
occurs along one very specific callpath where we know that a ref is held
for both new/old bo here, it all just works and so avoids having to dive
into the mess that is set_pixmap_bo.

Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>

I'll valgrind the flip-vs-xrandr tests tomorrow to be sure.
-Chris
diff mbox

Patch

diff --git a/src/uxa/intel_uxa.c b/src/uxa/intel_uxa.c
index 590ff5d..830f094 100644
--- a/src/uxa/intel_uxa.c
+++ b/src/uxa/intel_uxa.c
@@ -1068,7 +1068,7 @@  Bool intel_uxa_create_screen_resources(ScreenPtr screen)
 	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
 	PixmapPtr pixmap;
 	intel_screen_private *intel = intel_get_screen_private(scrn);
-	dri_bo *bo = intel->front_buffer;
+	dri_bo *bo = intel->front_buffer, *old_bo;
 	int old_width, old_height, old_pitch;
 
 	if (!uxa_resources_init(screen))
@@ -1081,6 +1081,7 @@  Bool intel_uxa_create_screen_resources(ScreenPtr screen)
 	old_width = pixmap->drawable.width;
 	old_height = pixmap->drawable.height;
 	old_pitch = pixmap->devKind;
+	old_bo = intel_uxa_get_pixmap_bo(pixmap);
 
 	if (!screen->ModifyPixmapHeader(pixmap,
 					scrn->virtualX,
@@ -1102,6 +1103,9 @@  Bool intel_uxa_create_screen_resources(ScreenPtr screen)
 err:
 	screen->ModifyPixmapHeader(pixmap,
 				   old_width, old_height, -1, -1, old_pitch, NULL);
+	if (old_bo)
+		intel_uxa_set_pixmap_bo(pixmap, old_bo);
+
 	return FALSE;
 }