Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a6910434 authored by Daniel Vetter's avatar Daniel Vetter Committed by Chris Wilson
Browse files

drm/i915: only one interrupt per batchbuffer is not enough!



Previously I thought that one interrupt per batchbuffer should be
enough. Now tedious benchmarking showed this to be wrong.

Therefore track whether any commands have been isssued with a future
seqno (like pipelined fencing changes or flushes). If this is the case
emit a request before issueing the batchbuffer.

Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
parent 8bff917c
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -293,9 +293,6 @@ typedef struct drm_i915_private {
	unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds;
	int vblank_pipe;
	int num_pipe;
	u32 flush_rings;
#define FLUSH_RENDER_RING	0x1
#define FLUSH_BSD_RING		0x2

	/* For hangcheck timer */
#define DRM_I915_HANGCHECK_PERIOD 75 /* in jiffies */
+16 −17
Original line number Diff line number Diff line
@@ -1470,10 +1470,13 @@ i915_gem_object_put_pages(struct drm_gem_object *obj)
}

static uint32_t
i915_gem_next_request_seqno(struct drm_device *dev)
i915_gem_next_request_seqno(struct drm_device *dev,
			    struct intel_ring_buffer *ring)
{
	drm_i915_private_t *dev_priv = dev->dev_private;

	ring->outstanding_lazy_request = true;

	return dev_priv->next_seqno;
}

@@ -1495,7 +1498,7 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno,

	/* Take the seqno of the next request if none is given */
	if (seqno == 0)
		seqno = i915_gem_next_request_seqno(dev);
		seqno = i915_gem_next_request_seqno(dev, ring);

	/* Move from whatever list we were on to the tail of execution. */
	spin_lock(&dev_priv->mm.active_list_lock);
@@ -2979,7 +2982,6 @@ static void
i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
{
	struct drm_device		*dev = obj->dev;
	drm_i915_private_t		*dev_priv = dev->dev_private;
	struct drm_i915_gem_object	*obj_priv = to_intel_bo(obj);
	uint32_t			invalidate_domains = 0;
	uint32_t			flush_domains = 0;
@@ -3042,13 +3044,6 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
		obj->pending_write_domain = obj->write_domain;
	obj->read_domains = obj->pending_read_domains;

	if (flush_domains & I915_GEM_GPU_DOMAINS) {
		if (obj_priv->ring == &dev_priv->render_ring)
			dev_priv->flush_rings |= FLUSH_RENDER_RING;
		else if (obj_priv->ring == &dev_priv->bsd_ring)
			dev_priv->flush_rings |= FLUSH_BSD_RING;
	}

	dev->invalidate_domains |= invalidate_domains;
	dev->flush_domains |= flush_domains;
#if WATCH_BUF
@@ -3762,7 +3757,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
	 */
	dev->invalidate_domains = 0;
	dev->flush_domains = 0;
	dev_priv->flush_rings = 0;

	for (i = 0; i < args->buffer_count; i++) {
		struct drm_gem_object *obj = object_list[i];
@@ -3783,12 +3777,17 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
		i915_gem_flush(dev,
			       dev->invalidate_domains,
			       dev->flush_domains);
		if (dev_priv->flush_rings & FLUSH_RENDER_RING)
	}

	if (dev_priv->render_ring.outstanding_lazy_request) {
		(void)i915_add_request(dev, file_priv, 0,
				       &dev_priv->render_ring);
		if (dev_priv->flush_rings & FLUSH_BSD_RING)
		dev_priv->render_ring.outstanding_lazy_request = false;
	}
	if (dev_priv->bsd_ring.outstanding_lazy_request) {
		(void)i915_add_request(dev, file_priv, 0,
				       &dev_priv->bsd_ring);
		dev_priv->bsd_ring.outstanding_lazy_request = false;
	}

	for (i = 0; i < args->buffer_count; i++) {
+5 −0
Original line number Diff line number Diff line
@@ -83,6 +83,11 @@ struct intel_ring_buffer {
	 */
	struct list_head request_list;

	/**
	 * Do we have some not yet emitted requests outstanding?
	 */
	bool outstanding_lazy_request;

	wait_queue_head_t irq_queue;
	drm_local_map_t map;
};