xf86-video-intel: 5 commits - src/sna/gen2_render.c src/sna/gen3_render.c src/sna/gen4_render.c src/sna/gen5_render.c src/sna/gen6_render.c src/sna/kgem.c src/sna/kgem.h src/sna/sna_accel.c src/sna/sna_render.c src/sna/sna_render.h

Chris Wilson ickle at kemper.freedesktop.org
Thu Jun 9 03:20:40 PDT 2011


 src/sna/gen2_render.c |    7 ----
 src/sna/gen3_render.c |    7 ----
 src/sna/gen4_render.c |   17 ---------
 src/sna/gen5_render.c |   10 ++---
 src/sna/gen6_render.c |   10 ++---
 src/sna/kgem.c        |   87 ++++++++++++++++++++++++++++++++++++--------------
 src/sna/kgem.h        |   17 ++-------
 src/sna/sna_accel.c   |   31 ++++++++++++-----
 src/sna/sna_render.c  |   28 +---------------
 src/sna/sna_render.h  |    1 
 10 files changed, 100 insertions(+), 115 deletions(-)

New commits:
commit 021209d5d3add8b28143611cfad4c5481a2945a3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jun 9 10:27:12 2011 +0100

    sna: Remove the stubs from sna_render.c
    
    These only existed to work around an include order problem, when kgem
    was intended to be entirely separable from sna. Moving the function
    pointer into kgem simplifies matters.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index 368e910..0ead969 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -1259,12 +1259,6 @@ gen2_render_flush(struct sna *sna)
 }
 
 static void
-gen2_render_context_switch(struct sna *sna,
-			   int new_mode)
-{
-}
-
-static void
 gen2_render_fini(struct sna *sna)
 {
 }
@@ -1284,7 +1278,6 @@ Bool gen2_render_init(struct sna *sna)
 
 	render->reset = gen2_render_reset;
 	render->flush = gen2_render_flush;
-	render->context_switch = gen2_render_context_switch;
 	render->fini = gen2_render_fini;
 
 	render->max_3d_size = 2048;
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 5d7f894..fcc3ba2 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -3660,12 +3660,6 @@ static void gen3_render_flush(struct sna *sna)
 }
 
 static void
-gen3_render_context_switch(struct sna *sna,
-			   int new_mode)
-{
-}
-
-static void
 gen3_render_fini(struct sna *sna)
 {
 }
@@ -3689,7 +3683,6 @@ Bool gen3_render_init(struct sna *sna)
 
 	render->reset = gen3_render_reset;
 	render->flush = gen3_render_flush;
-	render->context_switch = gen3_render_context_switch;
 	render->fini = gen3_render_fini;
 
 	render->max_3d_size = 2048;
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index 3399919..0c31019 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -2479,22 +2479,6 @@ gen4_render_flush(struct sna *sna)
 	gen4_vertex_finish(sna, TRUE);
 }
 
-static void
-gen4_render_context_switch(struct sna *sna,
-			   int new_mode)
-{
-	if (sna->kgem.mode == 0)
-		return;
-
-	if (new_mode == KGEM_BLT) {
-#if 0
-		OUT_BATCH(MI_FLUSH |
-			  MI_STATE_INSTRUCTION_CACHE_FLUSH |
-			  MI_INHIBIT_RENDER_CACHE_FLUSH);
-#endif
-	}
-}
-
 static void gen4_render_reset(struct sna *sna)
 {
 	sna->render_state.gen4.needs_invariant = TRUE;
@@ -2761,7 +2745,6 @@ Bool gen4_render_init(struct sna *sna)
 	sna->render.fill = gen4_render_fill;
 
 	sna->render.flush = gen4_render_flush;
-	sna->render.context_switch = gen4_render_context_switch;
 	sna->render.reset = gen4_render_reset;
 	sna->render.fini = gen4_render_fini;
 
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index eea0dd0..c444b69 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -2537,16 +2537,16 @@ gen5_render_flush(struct sna *sna)
 }
 
 static void
-gen5_render_context_switch(struct sna *sna,
+gen5_render_context_switch(struct kgem *kgem,
 			   int new_mode)
 {
 	/* Ironlake has a limitation that a 3D or Media command can't
 	 * be the first command after a BLT, unless it's
 	 * non-pipelined.
 	 */
-	if (sna->kgem.mode == KGEM_BLT) {
-		OUT_BATCH(CMD_POLY_STIPPLE_OFFSET << 16);
-		OUT_BATCH(0);
+	if (kgem->mode == KGEM_BLT) {
+		kgem->batch[kgem->nbatch++] = CMD_POLY_STIPPLE_OFFSET << 16;
+		kgem->batch[kgem->nbatch++] = 0;
 	}
 }
 
@@ -2810,6 +2810,7 @@ Bool gen5_render_init(struct sna *sna)
 		return FALSE;
 
 	gen5_render_reset(sna);
+	sna->kgem.context_switch = gen5_render_context_switch;
 
 	sna->render.composite = gen5_render_composite;
 	sna->render.video = gen5_render_video;
@@ -2821,7 +2822,6 @@ Bool gen5_render_init(struct sna *sna)
 	sna->render.fill = gen5_render_fill;
 
 	sna->render.flush = gen5_render_flush;
-	sna->render.context_switch = gen5_render_context_switch;
 	sna->render.reset = gen5_render_reset;
 	sna->render.fini = gen5_render_fini;
 
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 1cc30b2..2195882 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -2769,16 +2769,16 @@ static void gen6_render_flush(struct sna *sna)
 }
 
 static void
-gen6_render_context_switch(struct sna *sna,
+gen6_render_context_switch(struct kgem *kgem,
 			   int new_mode)
 {
 	if (!new_mode)
 		return;
 
-	if (sna->kgem.mode)
-		_kgem_submit(&sna->kgem);
+	if (kgem->mode)
+		_kgem_submit(kgem);
 
-	sna->kgem.ring = new_mode;
+	kgem->ring = new_mode;
 }
 
 static void gen6_render_reset(struct sna *sna)
@@ -2853,6 +2853,7 @@ Bool gen6_render_init(struct sna *sna)
 		return FALSE;
 
 	gen6_render_reset(sna);
+	sna->kgem.context_switch = gen6_render_context_switch;
 
 	sna->render.composite = gen6_render_composite;
 	sna->render.video = gen6_render_video;
@@ -2864,7 +2865,6 @@ Bool gen6_render_init(struct sna *sna)
 	sna->render.fill = gen6_render_fill;
 
 	sna->render.flush = gen6_render_flush;
-	sna->render.context_switch = gen6_render_context_switch;
 	sna->render.reset = gen6_render_reset;
 	sna->render.fini = gen6_render_fini;
 
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 2c61d2c..9ed8160 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -84,6 +84,24 @@ struct kgem_partial_bo {
 
 static struct drm_i915_gem_exec_object2 _kgem_dummy_exec;
 
+static void kgem_sna_reset(struct kgem *kgem)
+{
+	struct sna *sna = container_of(kgem, struct sna, kgem);
+
+	sna->render.reset(sna);
+}
+
+static void kgem_sna_flush(struct kgem *kgem)
+{
+	struct sna *sna = container_of(kgem, struct sna, kgem);
+
+	sna->render.flush(sna);
+
+	if (sna->render.solid_cache.dirty)
+		sna_render_flush_solid(sna);
+}
+
+
 static int gem_set_tiling(int fd, uint32_t handle, int tiling, int stride)
 {
 	struct drm_i915_gem_set_tiling set_tiling;
@@ -462,6 +480,8 @@ void _kgem_add_bo(struct kgem *kgem, struct kgem_bo *bo)
 
 static uint32_t kgem_end_batch(struct kgem *kgem)
 {
+	kgem->context_switch(kgem, KGEM_NONE);
+
 	kgem->batch[kgem->nbatch++] = MI_BATCH_BUFFER_END;
 	if (kgem->nbatch & 1)
 		kgem->batch[kgem->nbatch++] = MI_NOOP;
@@ -747,10 +767,8 @@ void _kgem_submit(struct kgem *kgem)
 	assert(kgem->nbatch <= KGEM_BATCH_SIZE(kgem));
 	assert(kgem->nbatch <= kgem->surface);
 
-	sna_kgem_context_switch(kgem, KGEM_NONE);
-
 	batch_end = kgem_end_batch(kgem);
-	sna_kgem_flush(kgem);
+	kgem_sna_flush(kgem);
 
 	DBG(("batch[%d/%d]: %d %d %d, nreloc=%d, nexec=%d, nfence=%d, aperture=%d\n",
 	     kgem->mode, kgem->ring, batch_end, kgem->nbatch, kgem->surface,
@@ -907,7 +925,7 @@ void _kgem_submit(struct kgem *kgem)
 	kgem->mode = KGEM_NONE;
 	kgem->flush = 0;
 
-	sna_kgem_reset(kgem);
+	kgem_sna_reset(kgem);
 }
 
 void kgem_throttle(struct kgem *kgem)
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 2b05c12..3709930 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -106,6 +106,7 @@ struct kgem {
 	uint16_t fence_max;
 	uint32_t aperture_high, aperture_low, aperture;
 
+	void (*context_switch)(struct kgem *kgem, int new_mode);
 	uint32_t batch[4*1024];
 	struct drm_i915_gem_exec_object2 exec[256];
 	struct drm_i915_gem_relocation_entry reloc[384];
@@ -192,7 +193,6 @@ static inline void kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
 void kgem_emit_flush(struct kgem *kgem);
 void kgem_clear_dirty(struct kgem *kgem);
 
-extern void sna_kgem_context_switch(struct kgem *kgem, int new_mode);
 static inline void kgem_set_mode(struct kgem *kgem, enum kgem_mode mode)
 {
 #if DEBUG_FLUSH_CACHE
@@ -206,8 +206,7 @@ static inline void kgem_set_mode(struct kgem *kgem, enum kgem_mode mode)
 	if (kgem->mode == mode)
 		return;
 
-	sna_kgem_context_switch(kgem, mode);
-
+	kgem->context_switch(kgem, mode);
 	kgem->mode = mode;
 }
 
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 63747ea..43fbff7 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -42,30 +42,6 @@
 #define NO_FIXUP 0
 #define NO_EXTRACT 0
 
-void sna_kgem_reset(struct kgem *kgem)
-{
-	struct sna *sna = container_of(kgem, struct sna, kgem);
-
-	sna->render.reset(sna);
-}
-
-void sna_kgem_flush(struct kgem *kgem)
-{
-	struct sna *sna = container_of(kgem, struct sna, kgem);
-
-	sna->render.flush(sna);
-
-	if (sna->render.solid_cache.dirty)
-		sna_render_flush_solid(sna);
-}
-
-void sna_kgem_context_switch(struct kgem *kgem, int new_mode)
-{
-	struct sna *sna = container_of(kgem, struct sna, kgem);
-
-	sna->render.context_switch(sna, new_mode);
-}
-
 CARD32
 sna_format_for_depth(int depth)
 {
@@ -206,7 +182,7 @@ static void no_render_flush(struct sna *sna)
 }
 
 static void
-no_render_context_switch(struct sna *sna,
+no_render_context_switch(struct kgem *kgem,
 			 int new_mode)
 {
 }
@@ -230,9 +206,9 @@ void no_render_init(struct sna *sna)
 
 	render->reset = no_render_reset;
 	render->flush = no_render_flush;
-	render->context_switch = no_render_context_switch;
 	render->fini = no_render_fini;
 
+	sna->kgem.context_switch = no_render_context_switch;
 	if (sna->kgem.gen >= 60)
 		sna->kgem.ring = KGEM_BLT;
 }
diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h
index 328eaf7..bd075aa 100644
--- a/src/sna/sna_render.h
+++ b/src/sna/sna_render.h
@@ -200,7 +200,6 @@ struct sna_render {
 
 	void (*flush)(struct sna *sna);
 	void (*reset)(struct sna *sna);
-	void (*context_switch)(struct sna *sna, int new_mode);
 	void (*fini)(struct sna *sna);
 
 	struct sna_solid_cache {
commit 6141b1aea159759e7e9dcf2561deb9d8c02bd0a2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jun 9 10:06:08 2011 +0100

    sna: Warn after detecting a hung GPU
    
    ...and include the instructional error message from uxa.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 1c88e7f..2c61d2c 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -912,7 +912,18 @@ void _kgem_submit(struct kgem *kgem)
 
 void kgem_throttle(struct kgem *kgem)
 {
+	static int warned;
+
 	kgem->wedged |= drmCommandNone(kgem->fd, DRM_I915_GEM_THROTTLE) == -EIO;
+
+	if (kgem->wedged && !warned) {
+		struct sna *sna = container_of(kgem, struct sna, kgem);
+		xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR,
+			   "Detected a hung GPU, disabling acceleration.\n");
+		xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR,
+			   "When reporting this, please include i915_error_state from debugfs and the full dmesg.\n");
+		warned = 1;
+	}
 }
 
 bool kgem_needs_expire(struct kgem *kgem)
commit 1786d2ee03a190ebe242ac7b58bed7cc31d66b16
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jun 9 09:48:57 2011 +0100

    sna/accel: Add debug messages for falling back due to a wedged GPU
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 1ddfe52..1640e79 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1541,8 +1541,10 @@ sna_fill_spans(DrawablePtr drawable, GCPtr gc, int n,
 	DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__,
 	     extents.x1, extents.y1, extents.x2, extents.y2));
 
-	if (sna->kgem.wedged)
+	if (sna->kgem.wedged) {
+		DBG(("%s: fallback -- wedged\n"));
 		goto fallback;
+	}
 
 	if (gc->fillStyle == FillSolid &&
 	    PM_IS_SOLID(drawable, gc->planemask)) {
@@ -1734,8 +1736,10 @@ sna_poly_point(DrawablePtr drawable, GCPtr gc,
 	DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__,
 	     extents.x1, extents.y1, extents.x2, extents.y2));
 
-	if (sna->kgem.wedged)
+	if (sna->kgem.wedged) {
+		DBG(("%s: fallback -- wedged\n"));
 		goto fallback;
+	}
 
 	if (gc->fillStyle == FillSolid &&
 	    PM_IS_SOLID(drawable, gc->planemask)) {
@@ -1951,8 +1955,10 @@ sna_poly_line(DrawablePtr drawable, GCPtr gc,
 	DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__,
 	     extents.x1, extents.y1, extents.x2, extents.y2));
 
-	if (sna->kgem.wedged)
+	if (sna->kgem.wedged) {
+		DBG(("%s: fallback -- wedged\n"));
 		goto fallback;
+	}
 
 	if (gc->fillStyle == FillSolid &&
 	    gc->lineStyle == LineSolid &&
@@ -2162,8 +2168,10 @@ sna_poly_segment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg)
 	DBG(("%s: extents=(%d, %d), (%d, %d)\n", __FUNCTION__,
 	     extents.x1, extents.y1, extents.x2, extents.y2));
 
-	if (sna->kgem.wedged)
+	if (sna->kgem.wedged) {
+		DBG(("%s: fallback -- wedged\n"));
 		goto fallback;
+	}
 
 	if (gc->fillStyle == FillSolid &&
 	    gc->lineStyle == LineSolid &&
@@ -2643,8 +2651,10 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect)
 	if (sna_poly_fill_rect_extents(draw, gc, n, rect, &extents))
 		return;
 
-	if (sna->kgem.wedged)
+	if (sna->kgem.wedged) {
+		DBG(("%s: fallback -- wedged\n"));
 		goto fallback;
+	}
 
 	if (!PM_IS_SOLID(draw, gc->planemask))
 		goto fallback;
@@ -2950,6 +2960,7 @@ sna_copy_window(WindowPtr win, DDXPointRec origin, RegionPtr src)
 	DBG(("%s origin=(%d, %d)\n", __FUNCTION__, origin.x, origin.y));
 
 	if (sna->kgem.wedged) {
+		DBG(("%s: fallback -- wedged\n"));
 		sna_pixmap_move_to_cpu(pixmap, true);
 		fbCopyWindow(win, origin, src);
 		return;
commit 4d509d501b09f565fea232947e6f53d54a08749f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jun 9 01:03:16 2011 +0100

    sna: Tweak retiring old bo
    
    As we check for retirement everytime we wakeup, it is seldom useful to
    check again until we know we have invoked an operation that may block.
    But when we do check, we do not want to scan the entire active list
    looking for flushing candidates, so track those on a separate list.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 979a552..1c88e7f 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -158,7 +158,8 @@ Bool kgem_bo_write(struct kgem *kgem, struct kgem_bo *bo,
 	if (gem_write(kgem->fd, bo->handle, 0, length, data))
 		return FALSE;
 
-	_kgem_retire(kgem);
+	if (bo->gpu)
+		kgem_retire(kgem);
 	return TRUE;
 }
 
@@ -292,6 +293,7 @@ void kgem_init(struct kgem *kgem, int fd, int gen)
 	list_init(&kgem->partial);
 	list_init(&kgem->requests);
 	list_init(&kgem->active);
+	list_init(&kgem->flushing);
 	for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++)
 		list_init(&kgem->inactive[i]);
 
@@ -500,6 +502,11 @@ static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
 	}
 
 	list_move(&bo->list, (bo->rq || bo->needs_flush) ? &kgem->active : inactive(kgem, bo->size));
+	if (bo->rq == NULL && bo->needs_flush) {
+		assert(list_is_empty(&bo->request));
+		list_add(&bo->request, &kgem->flushing);
+	}
+
 	return;
 
 destroy:
@@ -516,16 +523,19 @@ static void kgem_bo_unref(struct kgem *kgem, struct kgem_bo *bo)
 		__kgem_bo_destroy(kgem, bo);
 }
 
-void _kgem_retire(struct kgem *kgem)
+void kgem_retire(struct kgem *kgem)
 {
 	struct kgem_bo *bo, *next;
 
-	list_for_each_entry_safe(bo, next, &kgem->active, list) {
-		if (bo->rq == NULL && !kgem_busy(kgem, bo->handle)) {
+	list_for_each_entry_safe(bo, next, &kgem->flushing, request) {
+		if (!kgem_busy(kgem, bo->handle)) {
+			assert(bo->rq == NULL);
 			assert(bo->needs_flush);
 			assert(bo->deleted);
 			bo->needs_flush = 0;
+			bo->gpu = false;
 			list_move(&bo->list, inactive(kgem, bo->size));
+			list_del(&bo->request);
 		}
 	}
 
@@ -544,11 +554,13 @@ void _kgem_retire(struct kgem *kgem)
 					      request);
 			list_del(&bo->request);
 			bo->rq = NULL;
-			bo->gpu = false;
 
-			if (bo->refcnt == 0 && !bo->needs_flush) {
+			if (bo->refcnt == 0) {
 				assert(bo->deleted);
-				if (bo->reusable) {
+				if (bo->needs_flush) {
+					list_add(&bo->request, &kgem->flushing);
+				} else if (bo->reusable) {
+					bo->gpu = false;
 					list_move(&bo->list,
 						  inactive(kgem, bo->size));
 				} else {
@@ -573,8 +585,6 @@ void _kgem_retire(struct kgem *kgem)
 		list_del(&rq->list);
 		free(rq);
 	}
-
-	kgem->retire = 0;
 }
 
 static void kgem_commit(struct kgem *kgem)
@@ -897,8 +907,6 @@ void _kgem_submit(struct kgem *kgem)
 	kgem->mode = KGEM_NONE;
 	kgem->flush = 0;
 
-	kgem->retire = 1;
-
 	sna_kgem_reset(kgem);
 }
 
@@ -930,7 +938,7 @@ bool kgem_expire_cache(struct kgem *kgem)
 	bool idle;
 	int i;
 
-	_kgem_retire(kgem);
+	kgem_retire(kgem);
 	if (kgem->wedged)
 		kgem_cleanup(kgem);
 
@@ -994,12 +1002,7 @@ search_linear_cache(struct kgem *kgem, int size, bool active)
 	struct kgem_bo *bo, *next;
 	struct list *cache;
 
-	if (!active) {
-		cache = inactive(kgem, size);
-		kgem_retire(kgem);
-	} else
-		cache = &kgem->active;
-
+	cache = active ? &kgem->active : inactive(kgem, size);
 	list_for_each_entry_safe(bo, next, cache, list) {
 		if (size > bo->size)
 			continue;
@@ -1008,6 +1011,8 @@ search_linear_cache(struct kgem *kgem, int size, bool active)
 			continue;
 
 		list_del(&bo->list);
+		if (bo->rq == NULL)
+			list_del(&bo->request);
 
 		if (bo->deleted) {
 			if (!gem_madvise(kgem->fd, bo->handle,
@@ -1245,6 +1250,8 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem,
 		}
 
 		list_del(&bo->list);
+		if (bo->rq == NULL)
+			list_del(&bo->request);
 
 		if (bo->deleted) {
 			if (!gem_madvise(kgem->fd, bo->handle,
@@ -1293,6 +1300,7 @@ skip_active_search:
 		bo->tiling = tiling;
 
 		list_del(&bo->list);
+		assert(list_is_empty(&bo->request));
 
 		if (bo->deleted) {
 			if (!gem_madvise(kgem->fd, bo->handle,
@@ -1571,7 +1579,8 @@ void kgem_bo_sync(struct kgem *kgem, struct kgem_bo *bo, bool for_write)
 	set_domain.write_domain = for_write ? I915_GEM_DOMAIN_CPU : 0;
 
 	drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain);
-	_kgem_retire(kgem);
+	if (bo->gpu)
+		kgem_retire(kgem);
 	bo->cpu_read = true;
 	if (for_write)
 		bo->cpu_write = true;
@@ -1767,7 +1776,8 @@ void kgem_buffer_sync(struct kgem *kgem, struct kgem_bo *_bo)
 				  0, bo->used, bo+1);
 		else
 			gem_read(kgem->fd, bo->base.handle, bo+1, bo->used);
-		_kgem_retire(kgem);
+		if (bo->base.gpu)
+			kgem_retire(kgem);
 		bo->need_io = 0;
 	}
 
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 37803bd..2b05c12 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -86,8 +86,7 @@ struct kgem {
 		KGEM_BLT,
 	} mode, ring;
 
-	struct list active;
-	struct list inactive[16];
+	struct list active, flushing, inactive[16];
 	struct list partial;
 	struct list requests;
 	struct kgem_request *next_request;
@@ -98,7 +97,6 @@ struct kgem {
 	uint16_t nreloc;
 	uint16_t nfence;
 
-	uint32_t retire;
 	uint32_t flush;
 	uint32_t need_purge;
 
@@ -155,12 +153,7 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem,
 			       int tiling,
 			       uint32_t flags);
 
-void _kgem_retire(struct kgem *kgem);
-static inline void kgem_retire(struct kgem *kgem)
-{
-	if (kgem->retire)
-		_kgem_retire(kgem);
-}
+void kgem_retire(struct kgem *kgem);
 
 void _kgem_submit(struct kgem *kgem);
 static inline void kgem_submit(struct kgem *kgem)
@@ -290,7 +283,6 @@ static inline bool kgem_bo_is_busy(struct kgem *kgem, struct kgem_bo *bo)
 	if (!bo->gpu)
 		return false;
 
-	kgem_retire(kgem);
 	return bo->rq != NULL;
 }
 
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 82c9973..1ddfe52 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -3306,7 +3306,7 @@ void sna_accel_block_handler(struct sna *sna)
 
 void sna_accel_wakeup_handler(struct sna *sna)
 {
-	_kgem_retire(&sna->kgem);
+	kgem_retire(&sna->kgem);
 	sna_deferred_free(sna);
 
 	if (sna->kgem.need_purge)
commit 17be5e2eb41b2ada94954b87c855961003c2fc7c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jun 9 00:38:29 2011 +0100

    sna: Reduce the frequency of the timer interrupts
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 8e2bc33..82c9973 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -3097,9 +3097,9 @@ static Bool sna_accel_do_flush(struct sna *sna)
 	to.it_value.tv_sec = 0;
 	to.it_value.tv_nsec = 10 * 1000 * 1000;
 
-	/* Then periodic updates at 50Hz.*/
+	/* Then periodic updates at 25Hz.*/
 	to.it_interval.tv_sec = 0;
-	to.it_interval.tv_nsec = 20 * 1000 * 1000;
+	to.it_interval.tv_nsec = 40 * 1000 * 1000;
 	timerfd_settime(sna->timer[FLUSH_TIMER], 0, &to, NULL);
 
 	sna->timer_active |= 1 << FLUSH_TIMER;
@@ -3122,8 +3122,8 @@ static Bool sna_accel_do_expire(struct sna *sna)
 	to.it_value.tv_sec = 5;
 	to.it_value.tv_nsec = 0;
 
-	/* Then periodic update every 1s.*/
-	to.it_interval.tv_sec = 1;
+	/* Then periodic update every 10s.*/
+	to.it_interval.tv_sec = 10;
 	to.it_interval.tv_nsec = 0;
 	timerfd_settime(sna->timer[EXPIRE_TIMER], 0, &to, NULL);
 


More information about the xorg-commit mailing list