summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMario Kleiner <mario.kleiner.de@gmail.com>2018-12-19 07:56:15 +0100
committerMichel Dänzer <michel.daenzer@amd.com>2018-12-19 18:03:27 +0100
commitd4eab5d108c4569f3a9e2892704ea89b7ee797b6 (patch)
tree38ef9d7c4dd416d574b4c2ecd85561e2c8f0bb22 /src
parent0d60233d26ec70d4e1faa343b438e33829c6d5e4 (diff)
Fix crash when page flipping in multi-X-Screen/Zaphod mode
amdgpu_do_pageflip() indexed the flipdata->fb[] array indexing over config->num_crtc, but the flip completion routines, e.g., drmmode_flip_handler(), index that array via the crtc hw id from drmmode_get_crtc_id(crtc). This is mismatched and causes indexing into the wrong array slot at flip completion -> Server crash. Always use drmmode_get_crtc_id(crtc) for indexing into the array to fix this. Tested on a dual-X-Screen setup with one video output assigned to each X-Screen, page-flipping an OpenGL app on either of both X-Screens. This used to crash when flipping on X-Screen 1, now it doesn't anymore. Fixes: 9b6782c821e0 "Store FB for each CRTC in drmmode_flipdata_rec" (Ported from radeon commit 0058fd2ebf4c900b12f129984e98886a7ac84b2f) Reviewed-by: Michel Dänzer <michel.daenzer@amd.com> Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/drmmode_display.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 92cf543..fdadf89 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -4006,6 +4006,7 @@ Bool amdgpu_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
xf86CrtcPtr crtc = NULL;
drmmode_crtc_private_ptr drmmode_crtc = config->crtc[0]->driver_private;
+ int crtc_id;
uint32_t flip_flags = flip_sync == FLIP_ASYNC ? DRM_MODE_PAGE_FLIP_ASYNC : 0;
drmmode_flipdata_ptr flipdata;
Bool handle_deferred = FALSE;
@@ -4013,7 +4014,7 @@ Bool amdgpu_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
struct drmmode_fb *fb;
int i = 0;
- flipdata = calloc(1, sizeof(*flipdata) + config->num_crtc *
+ flipdata = calloc(1, sizeof(*flipdata) + drmmode_crtc->drmmode->count_crtcs *
sizeof(flipdata->fb[0]));
if (!flipdata) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
@@ -4045,6 +4046,7 @@ Bool amdgpu_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
for (i = 0; i < config->num_crtc; i++) {
crtc = config->crtc[i];
drmmode_crtc = crtc->driver_private;
+ crtc_id = drmmode_get_crtc_id(crtc);
if (!drmmode_crtc_can_flip(crtc) ||
(drmmode_crtc->tear_free && crtc != ref_crtc))
@@ -4079,9 +4081,9 @@ Bool amdgpu_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
goto next;
}
- drmmode_fb_reference(pAMDGPUEnt->fd, &flipdata->fb[i],
+ drmmode_fb_reference(pAMDGPUEnt->fd, &flipdata->fb[crtc_id],
amdgpu_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap));
- if (!flipdata->fb[i]) {
+ if (!flipdata->fb[crtc_id]) {
ErrorF("Failed to get FB for TearFree flip\n");
goto error;
}
@@ -4097,13 +4099,13 @@ Bool amdgpu_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
drmmode_crtc->scanout_update_pending = 0;
}
} else {
- drmmode_fb_reference(pAMDGPUEnt->fd, &flipdata->fb[i], fb);
+ drmmode_fb_reference(pAMDGPUEnt->fd, &flipdata->fb[crtc_id], fb);
}
if (crtc == ref_crtc) {
if (drmmode_page_flip_target_absolute(pAMDGPUEnt,
drmmode_crtc,
- flipdata->fb[i]->handle,
+ flipdata->fb[crtc_id]->handle,
flip_flags,
drm_queue_seq,
target_msc) != 0)
@@ -4111,7 +4113,7 @@ Bool amdgpu_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
} else {
if (drmmode_page_flip_target_relative(pAMDGPUEnt,
drmmode_crtc,
- flipdata->fb[i]->handle,
+ flipdata->fb[crtc_id]->handle,
flip_flags,
drm_queue_seq, 0) != 0)
goto flip_error;
@@ -4124,7 +4126,7 @@ Bool amdgpu_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
next:
drmmode_fb_reference(pAMDGPUEnt->fd, &drmmode_crtc->flip_pending,
- flipdata->fb[i]);
+ flipdata->fb[crtc_id]);
drm_queue_seq = 0;
}