summaryrefslogtreecommitdiff
path: root/sys/dev/pci/drm
diff options
context:
space:
mode:
authorJonathan Gray <jsg@jsg.id.au>2013-02-19 20:22:25 +1100
committerJonathan Gray <jsg@jsg.id.au>2013-02-19 20:22:25 +1100
commit2efa3770208dda06183784aeb3aae440eaecf421 (patch)
tree1795f955e244308dc571b3b467c902abe5f76175 /sys/dev/pci/drm
parent520ad4b5a6db21037472be6bacbde668f5df46fb (diff)
move to per ring tracking of request seqnos
doesn't seem to help with gpu hangs on ivb...
Diffstat (limited to 'sys/dev/pci/drm')
-rw-r--r--sys/dev/pci/drm/i915_drv.h1
-rw-r--r--sys/dev/pci/drm/i915_gem.c30
-rw-r--r--sys/dev/pci/drm/intel_ringbuffer.c30
-rw-r--r--sys/dev/pci/drm/intel_ringbuffer.h4
4 files changed, 39 insertions, 26 deletions
diff --git a/sys/dev/pci/drm/i915_drv.h b/sys/dev/pci/drm/i915_drv.h
index 82ff1d18a96..e0e2317ef7c 100644
--- a/sys/dev/pci/drm/i915_drv.h
+++ b/sys/dev/pci/drm/i915_drv.h
@@ -1156,6 +1156,7 @@ struct drm_i915_gem_object *
i915_gem_alloc_object(struct drm_device *, size_t);
int i915_gpu_idle(struct drm_device *);
void i915_gem_object_move_to_flushing(struct drm_i915_gem_object *);
+u32 i915_gem_next_request_seqno(struct intel_ring_buffer *);
/* intel_opregion.c */
int intel_opregion_setup(struct drm_device *dev);
diff --git a/sys/dev/pci/drm/i915_gem.c b/sys/dev/pci/drm/i915_gem.c
index bc4542eb8e3..61838427649 100644
--- a/sys/dev/pci/drm/i915_gem.c
+++ b/sys/dev/pci/drm/i915_gem.c
@@ -401,7 +401,7 @@ i915_wait_seqno(struct intel_ring_buffer *ring, uint32_t seqno)
if (dev_priv->mm.wedged)
return (EIO);
- if (seqno == dev_priv->next_seqno) {
+ if (seqno == ring->outstanding_lazy_request) {
ret = i915_add_request(ring, NULL, &seqno);
if (ret)
return (ret);
@@ -784,7 +784,9 @@ i915_gem_object_move_to_active(struct drm_i915_gem_object *obj,
{
struct drm_device *dev = obj->base.dev;
struct inteldrm_softc *dev_priv = dev->dev_private;
- u_int32_t seqno = dev_priv->next_seqno;
+ u_int32_t seqno;
+
+ seqno = i915_gem_next_request_seqno(ring);
MUTEX_ASSERT_LOCKED(&dev_priv->request_lock);
MUTEX_ASSERT_LOCKED(&dev_priv->list_lock);
@@ -916,6 +918,16 @@ i915_gem_handle_seqno_wrap(struct drm_device *dev)
return 0;
}
+u32
+i915_gem_next_request_seqno(struct intel_ring_buffer *ring)
+{
+ if (ring->outstanding_lazy_request == 0)
+ /* XXX check return */
+ i915_gem_get_seqno(ring->dev, &ring->outstanding_lazy_request);
+
+ return ring->outstanding_lazy_request;
+}
+
int
i915_gem_get_seqno(struct drm_device *dev, u32 *seqno)
{
@@ -923,9 +935,11 @@ i915_gem_get_seqno(struct drm_device *dev, u32 *seqno)
/* reserve 0 for non-seqno */
if (dev_priv->next_seqno == 0) {
+#ifdef notyet
int ret = i915_gem_handle_seqno_wrap(dev);
if (ret)
return ret;
+#endif
dev_priv->next_seqno = 1;
}
@@ -960,14 +974,6 @@ i915_add_request(struct intel_ring_buffer *ring,
return -ENOMEM;
}
- /* Grab the seqno we're going to make this request be, and bump the
- * next (skipping 0 so it can be the reserved no-seqno value).
- */
- seqno = dev_priv->next_seqno;
- dev_priv->next_seqno++;
- if (dev_priv->next_seqno == 0)
- dev_priv->next_seqno++;
-
/* Record the position of the start of the request so that
* should we detect the updated seqno part-way through the
* GPU processing the request, we never over-estimate the
@@ -975,7 +981,7 @@ i915_add_request(struct intel_ring_buffer *ring,
*/
request_ring_position = intel_ring_get_tail(ring);
- ret = ring->add_request(ring, seqno);
+ ret = ring->add_request(ring, &seqno);
if (ret) {
drm_free(request);
return ret;
@@ -992,6 +998,8 @@ i915_add_request(struct intel_ring_buffer *ring,
list_add_tail(&request->list, &ring->request_list);
mtx_leave(&dev_priv->request_lock);
+ ring->outstanding_lazy_request = 0;
+
if (dev_priv->mm.suspended == 0) {
if (was_empty)
timeout_add_sec(&dev_priv->mm.retire_timer, 1);
diff --git a/sys/dev/pci/drm/intel_ringbuffer.c b/sys/dev/pci/drm/intel_ringbuffer.c
index 4fcd63f2ff7..603ceacfb46 100644
--- a/sys/dev/pci/drm/intel_ringbuffer.c
+++ b/sys/dev/pci/drm/intel_ringbuffer.c
@@ -54,10 +54,10 @@ void cleanup_pipe_control(struct intel_ring_buffer *);
int init_render_ring(struct intel_ring_buffer *);
void render_ring_cleanup(struct intel_ring_buffer *);
void update_mboxes(struct intel_ring_buffer *, u32, u32);
-int gen6_add_request(struct intel_ring_buffer *, u32);
+int gen6_add_request(struct intel_ring_buffer *, u32 *);
int gen6_ring_sync(struct intel_ring_buffer *, struct intel_ring_buffer *,
u32);
-int pc_render_add_request(struct intel_ring_buffer *, u32);
+int pc_render_add_request(struct intel_ring_buffer *, u32 *);
u32 gen6_ring_get_seqno(struct intel_ring_buffer *, bool);
u32 ring_get_seqno(struct intel_ring_buffer *, bool);
u32 pc_render_get_seqno(struct intel_ring_buffer *, bool);
@@ -68,7 +68,7 @@ void i9xx_ring_put_irq(struct intel_ring_buffer *);
bool i8xx_ring_get_irq(struct intel_ring_buffer *);
void i8xx_ring_put_irq(struct intel_ring_buffer *);
int bsd_ring_flush(struct intel_ring_buffer *, u32, u32);
-int i9xx_add_request(struct intel_ring_buffer *, u32);
+int i9xx_add_request(struct intel_ring_buffer *, u32 *);
bool gen6_ring_get_irq(struct intel_ring_buffer *);
void gen6_ring_put_irq(struct intel_ring_buffer *);
int i830_dispatch_execbuffer(struct intel_ring_buffer *, u32, u32,
@@ -675,7 +675,7 @@ update_mboxes(struct intel_ring_buffer *ring,
* This acts like a signal in the canonical semaphore.
*/
int
-gen6_add_request(struct intel_ring_buffer *ring, u32 seqno)
+gen6_add_request(struct intel_ring_buffer *ring, u32 *seqno)
{
u32 mbox1_reg;
u32 mbox2_reg;
@@ -688,11 +688,13 @@ gen6_add_request(struct intel_ring_buffer *ring, u32 seqno)
mbox1_reg = ring->signal_mbox[0];
mbox2_reg = ring->signal_mbox[1];
- update_mboxes(ring, mbox1_reg, seqno);
- update_mboxes(ring, mbox2_reg, seqno);
+ *seqno = i915_gem_next_request_seqno(ring);
+
+ update_mboxes(ring, mbox1_reg, *seqno);
+ update_mboxes(ring, mbox2_reg, *seqno);
intel_ring_emit(ring, MI_STORE_DWORD_INDEX);
intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
- intel_ring_emit(ring, seqno);
+ intel_ring_emit(ring, *seqno);
intel_ring_emit(ring, MI_USER_INTERRUPT);
intel_ring_advance(ring);
@@ -749,8 +751,9 @@ do { \
} while (0)
int
-pc_render_add_request(struct intel_ring_buffer *ring, u32 seqno)
+pc_render_add_request(struct intel_ring_buffer *ring, u32 *result)
{
+ u32 seqno = i915_gem_next_request_seqno(ring);
struct pipe_control *pc = ring->private;
u32 scratch_addr = pc->gtt_offset + 128;
int ret;
@@ -794,6 +797,7 @@ pc_render_add_request(struct intel_ring_buffer *ring, u32 seqno)
intel_ring_emit(ring, 0);
intel_ring_advance(ring);
+ *result = seqno;
return 0;
}
@@ -976,20 +980,24 @@ bsd_ring_flush(struct intel_ring_buffer *ring,
}
int
-i9xx_add_request(struct intel_ring_buffer *ring, u32 seqno)
+i9xx_add_request(struct intel_ring_buffer *ring, u32 *result)
{
+ uint32_t seqno;
int ret;
ret = intel_ring_begin(ring, 4);
if (ret)
return ret;
+ seqno = i915_gem_next_request_seqno(ring);
+
intel_ring_emit(ring, MI_STORE_DWORD_INDEX);
intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
intel_ring_emit(ring, seqno);
intel_ring_emit(ring, MI_USER_INTERRUPT);
intel_ring_advance(ring);
+ *result = seqno;
return 0;
}
@@ -1516,16 +1524,14 @@ int
intel_ring_idle(struct intel_ring_buffer *ring)
{
u32 seqno;
-#ifdef notyet
int ret;
/* We need to add any requests required to flush the objects and ring */
if (ring->outstanding_lazy_request) {
- ret = i915_add_request(ring);
+ ret = i915_add_request(ring, NULL, NULL);
if (ret)
return ret;
}
-#endif
/* Wait upon the last request to be completed */
if (list_empty(&ring->request_list))
diff --git a/sys/dev/pci/drm/intel_ringbuffer.h b/sys/dev/pci/drm/intel_ringbuffer.h
index 8841114aee2..8bda2ece499 100644
--- a/sys/dev/pci/drm/intel_ringbuffer.h
+++ b/sys/dev/pci/drm/intel_ringbuffer.h
@@ -93,7 +93,7 @@ struct intel_ring_buffer {
int (*flush)(struct intel_ring_buffer *ring,
u32 invalidate_domains,
u32 flush_domains);
- int (*add_request)(struct intel_ring_buffer *ring, u32 seqno);
+ int (*add_request)(struct intel_ring_buffer *ring, u32 *seqno);
/* Some chipsets are not quite as coherent as advertised and need
* an expensive kick to force a true read of the up-to-date seqno.
* However, the up-to-date seqno is not always required and the last
@@ -137,9 +137,7 @@ struct intel_ring_buffer {
/**
* Do we have some not yet emitted requests outstanding?
*/
-#ifdef notyet
u32 outstanding_lazy_request;
-#endif
bool gpu_caches_dirty;
int irq_queue;