aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMika Kuoppala <mika.kuoppala@linux.intel.com>2013-05-24 10:16:07 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-05-31 14:53:54 -0400
commit92cab7345131db7af18f630a799ce6b2e8e624c5 (patch)
treed61c1ac94941db3bdcbbae8753a2864557ed0b67
parent79ee20dc85072b0edfb5e461799d192a9cc9d422 (diff)
drm/i915: track ring progression using seqnos
Instead of relying in acthd, track ring seqno progression to detect if ring has hung. v2: put hangcheck stuff inside struct (Chris Wilson) v3: initialize hangcheck.seqno (Ben Widawsky) Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com> Reviewed-by: Ben Widawsky <ben@bwidawsk.net> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h2
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c30
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c1
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.h6
4 files changed, 20 insertions, 19 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e09c54c73a22..e417049ea581 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -842,8 +842,6 @@ struct i915_gpu_error {
842#define DRM_I915_HANGCHECK_JIFFIES msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD) 842#define DRM_I915_HANGCHECK_JIFFIES msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)
843 struct timer_list hangcheck_timer; 843 struct timer_list hangcheck_timer;
844 int hangcheck_count; 844 int hangcheck_count;
845 uint32_t last_acthd[I915_NUM_RINGS];
846 uint32_t prev_instdone[I915_NUM_INSTDONE_REG];
847 845
848 /* For reset and error_state handling. */ 846 /* For reset and error_state handling. */
849 spinlock_t lock; 847 spinlock_t lock;
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 0e5c9b0cc5a6..004ad3455992 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2384,22 +2384,19 @@ void i915_hangcheck_elapsed(unsigned long data)
2384{ 2384{
2385 struct drm_device *dev = (struct drm_device *)data; 2385 struct drm_device *dev = (struct drm_device *)data;
2386 drm_i915_private_t *dev_priv = dev->dev_private; 2386 drm_i915_private_t *dev_priv = dev->dev_private;
2387 uint32_t acthd[I915_NUM_RINGS], instdone[I915_NUM_INSTDONE_REG];
2388 struct intel_ring_buffer *ring; 2387 struct intel_ring_buffer *ring;
2389 bool err = false, idle; 2388 bool err = false, idle;
2390 int i; 2389 int i;
2390 u32 seqno[I915_NUM_RINGS];
2391 bool work_done;
2391 2392
2392 if (!i915_enable_hangcheck) 2393 if (!i915_enable_hangcheck)
2393 return; 2394 return;
2394 2395
2395 memset(acthd, 0, sizeof(acthd));
2396 idle = true; 2396 idle = true;
2397 for_each_ring(ring, dev_priv, i) { 2397 for_each_ring(ring, dev_priv, i) {
2398 u32 seqno; 2398 seqno[i] = ring->get_seqno(ring, false);
2399 2399 idle &= i915_hangcheck_ring_idle(ring, seqno[i], &err);
2400 seqno = ring->get_seqno(ring, false);
2401 idle &= i915_hangcheck_ring_idle(ring, seqno, &err);
2402 acthd[i] = intel_ring_get_active_head(ring);
2403 } 2400 }
2404 2401
2405 /* If all work is done then ACTHD clearly hasn't advanced. */ 2402 /* If all work is done then ACTHD clearly hasn't advanced. */
@@ -2415,20 +2412,19 @@ void i915_hangcheck_elapsed(unsigned long data)
2415 return; 2412 return;
2416 } 2413 }
2417 2414
2418 i915_get_extra_instdone(dev, instdone); 2415 work_done = false;
2419 if (memcmp(dev_priv->gpu_error.last_acthd, acthd, 2416 for_each_ring(ring, dev_priv, i) {
2420 sizeof(acthd)) == 0 && 2417 if (ring->hangcheck.seqno != seqno[i]) {
2421 memcmp(dev_priv->gpu_error.prev_instdone, instdone, 2418 work_done = true;
2422 sizeof(instdone)) == 0) { 2419 ring->hangcheck.seqno = seqno[i];
2420 }
2421 }
2422
2423 if (!work_done) {
2423 if (i915_hangcheck_hung(dev)) 2424 if (i915_hangcheck_hung(dev))
2424 return; 2425 return;
2425 } else { 2426 } else {
2426 dev_priv->gpu_error.hangcheck_count = 0; 2427 dev_priv->gpu_error.hangcheck_count = 0;
2427
2428 memcpy(dev_priv->gpu_error.last_acthd, acthd,
2429 sizeof(acthd));
2430 memcpy(dev_priv->gpu_error.prev_instdone, instdone,
2431 sizeof(instdone));
2432 } 2428 }
2433 2429
2434repeat: 2430repeat:
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 3d2c236e15ab..5698faeee6f6 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1502,6 +1502,7 @@ void intel_ring_init_seqno(struct intel_ring_buffer *ring, u32 seqno)
1502 } 1502 }
1503 1503
1504 ring->set_seqno(ring, seqno); 1504 ring->set_seqno(ring, seqno);
1505 ring->hangcheck.seqno = seqno;
1505} 1506}
1506 1507
1507void intel_ring_advance(struct intel_ring_buffer *ring) 1508void intel_ring_advance(struct intel_ring_buffer *ring)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index dac1614a1bca..ef374a892105 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -37,6 +37,10 @@ struct intel_hw_status_page {
37#define I915_READ_SYNC_0(ring) I915_READ(RING_SYNC_0((ring)->mmio_base)) 37#define I915_READ_SYNC_0(ring) I915_READ(RING_SYNC_0((ring)->mmio_base))
38#define I915_READ_SYNC_1(ring) I915_READ(RING_SYNC_1((ring)->mmio_base)) 38#define I915_READ_SYNC_1(ring) I915_READ(RING_SYNC_1((ring)->mmio_base))
39 39
40struct intel_ring_hangcheck {
41 u32 seqno;
42};
43
40struct intel_ring_buffer { 44struct intel_ring_buffer {
41 const char *name; 45 const char *name;
42 enum intel_ring_id { 46 enum intel_ring_id {
@@ -137,6 +141,8 @@ struct intel_ring_buffer {
137 struct i915_hw_context *default_context; 141 struct i915_hw_context *default_context;
138 struct i915_hw_context *last_context; 142 struct i915_hw_context *last_context;
139 143
144 struct intel_ring_hangcheck hangcheck;
145
140 void *private; 146 void *private;
141}; 147};
142 148