xf86-video-intel: 2 commits - src/sna/kgem.c src/sna/sna_display.c src/sna/sna.h

Chris Wilson ickle at kemper.freedesktop.org
Mon Sep 15 03:42:12 PDT 2014


 src/sna/kgem.c        |   25 +++++++++++++++++++++++--
 src/sna/sna.h         |    2 ++
 src/sna/sna_display.c |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 72 insertions(+), 2 deletions(-)

New commits:
commit d470f0f520f6bd160ae4acef2b4b3c86afd8dbbd
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Sep 15 11:36:20 2014 +0100

    sna: Last ditch attempt to make extra large batches fit
    
    If we have unfortunate fragmentation, e.g. a cursor is pinned in the
    middle of an aperture, we can struggle to fit large objects, especially
    fenced objects on gen2/gen3. We do have one last trick up our sleeves
    that we can try: disable all of the outputs and cursors and try
    submitting the batch in as pristine an aperture as we can arrange. We
    can only hope that the subsequent restoration of the outputs is more
    conducive to future batches (and so not lead us into continual flicker).
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 82ff619..485ef8f 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -3200,7 +3200,7 @@ static void dump_fence_regs(struct kgem *kgem)
 
 static int do_execbuf(struct kgem *kgem, struct drm_i915_gem_execbuffer2 *execbuf)
 {
-	int ret;
+	int ret, err;
 
 retry:
 	ret = do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, execbuf);
@@ -3216,7 +3216,28 @@ retry:
 		goto retry;
 
 	/* last gasp */
-	return do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, execbuf);
+	ret = do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, execbuf);
+	if (ret == 0)
+		return 0;
+
+	xf86DrvMsg(kgem_get_screen_index(kgem), X_WARNING,
+		   "Failed to submit rendering commands, trying again with outputs disabled.\n");
+
+	/* One last trick up our sleeve for when we run out of space.
+	 * We turn everything off to free up our pinned framebuffers,
+	 * sprites and cursors, and try one last time.
+	 */
+	err = errno;
+	if (sna_mode_disable(container_of(kgem, struct sna, kgem))) {
+		kgem_cleanup_cache(kgem);
+		ret = do_ioctl(kgem->fd,
+			       DRM_IOCTL_I915_GEM_EXECBUFFER2,
+			       execbuf);
+		sna_mode_enable(container_of(kgem, struct sna, kgem));
+	}
+	errno = err;
+
+	return ret;
 }
 
 void _kgem_submit(struct kgem *kgem)
diff --git a/src/sna/sna.h b/src/sna/sna.h
index ad74870..04ee35c 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -426,6 +426,8 @@ bool sna_mode_wants_tear_free(struct sna *sna);
 void sna_mode_adjust_frame(struct sna *sna, int x, int y);
 extern void sna_mode_discover(struct sna *sna);
 extern void sna_mode_check(struct sna *sna);
+extern bool sna_mode_disable(struct sna *sna);
+extern void sna_mode_enable(struct sna *sna);
 extern void sna_mode_reset(struct sna *sna);
 extern void sna_mode_wakeup(struct sna *sna);
 extern void sna_mode_redisplay(struct sna *sna);
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 54ebe78..2a98fb9 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -5785,6 +5785,52 @@ sna_mode_set_primary(struct sna *sna)
 #endif
 }
 
+bool
+sna_mode_disable(struct sna *sna)
+{
+	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
+	int i;
+
+	if (sna->flags & SNA_IS_HOSTED)
+		return false;
+
+	if (!sna->scrn->vtSema)
+		return false;
+
+	sna_hide_cursors(sna->scrn);
+	for (i = 0; i < sna->mode.num_real_crtc; i++)
+		sna_crtc_disable(config->crtc[i]);
+
+	while (sna_mode_has_pending_events(sna))
+		sna_mode_wakeup(sna);
+
+	kgem_clean_scanout_cache(&sna->kgem);
+	return true;
+}
+
+void
+sna_mode_enable(struct sna *sna)
+{
+	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
+	int i;
+
+	if (sna->flags & SNA_IS_HOSTED)
+		return;
+
+	if (!sna->scrn->vtSema)
+		return;
+
+	for (i = 0; i < sna->mode.num_real_crtc; i++) {
+		xf86CrtcPtr crtc = config->crtc[i];
+
+		assert(to_sna_crtc(crtc) != NULL);
+		if (!crtc->enabled)
+			continue;
+
+		__sna_crtc_set_mode(crtc);
+	}
+}
+
 void
 sna_mode_close(struct sna *sna)
 {
commit 435fe185e335a147f5edb803561509e1f0cb4e70
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Sep 15 09:09:19 2014 +0100

    sna: Update the list of outputs after a failed modeset
    
    In case we have a hotplug at just the wrong time, we can fail a modeset
    with a stale connector. Before attempting to recover, probe the kernel
    for the current state.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index df6d384..54ebe78 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -2173,6 +2173,7 @@ error:
 	sna_crtc->offset = saved_offset;
 	sna_crtc->transform = saved_transform;
 	sna_crtc->bo = saved_bo;
+	sna_mode_discover(sna);
 	return FALSE;
 }
 


More information about the xorg-commit mailing list