Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 228642
b: refs/heads/master
c: 893eead
h: refs/heads/master
v: v3
  • Loading branch information
Chris Wilson committed Oct 27, 2010
1 parent 3c41433 commit a84e8f2
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 40 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7e318e18f248416a3d32a1649a9b4538e7f8b0eb
refs/heads/master: 893eead092f14e42cac054a394a86e3c6e016b68
74 changes: 35 additions & 39 deletions trunk/drivers/gpu/drm/i915/i915_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -1307,12 +1307,29 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
return -EINVAL;
}

static struct drm_i915_gem_request *
i915_get_tail_request(struct drm_device *dev)
static u32
ring_last_seqno(struct intel_ring_buffer *ring)
{
drm_i915_private_t *dev_priv = dev->dev_private;
return list_entry(dev_priv->render_ring.request_list.prev,
struct drm_i915_gem_request, list);
return list_entry(ring->request_list.prev,
struct drm_i915_gem_request, list)->seqno;
}

static bool i915_hangcheck_ring_idle(struct intel_ring_buffer *ring, bool *err)
{
if (list_empty(&ring->request_list) ||
i915_seqno_passed(ring->get_seqno(ring), ring_last_seqno(ring))) {
/* Issue a wake-up to catch stuck h/w. */
if (ring->waiting_gem_seqno && waitqueue_active(&ring->irq_queue)) {
DRM_ERROR("Hangcheck timer elapsed... %s idle [waiting on %d, at %d], missed IRQ?\n",
ring->name,
ring->waiting_gem_seqno,
ring->get_seqno(ring));
wake_up_all(&ring->irq_queue);
*err = true;
}
return true;
}
return false;
}

/**
Expand All @@ -1326,6 +1343,17 @@ void i915_hangcheck_elapsed(unsigned long data)
struct drm_device *dev = (struct drm_device *)data;
drm_i915_private_t *dev_priv = dev->dev_private;
uint32_t acthd, instdone, instdone1;
bool err = false;

/* If all work is done then ACTHD clearly hasn't advanced. */
if (i915_hangcheck_ring_idle(&dev_priv->render_ring, &err) &&
i915_hangcheck_ring_idle(&dev_priv->bsd_ring, &err) &&
i915_hangcheck_ring_idle(&dev_priv->blt_ring, &err)) {
dev_priv->hangcheck_count = 0;
if (err)
goto repeat;
return;
}

if (INTEL_INFO(dev)->gen < 4) {
acthd = I915_READ(ACTHD);
Expand All @@ -1337,38 +1365,6 @@ void i915_hangcheck_elapsed(unsigned long data)
instdone1 = I915_READ(INSTDONE1);
}

/* If all work is done then ACTHD clearly hasn't advanced. */
if (list_empty(&dev_priv->render_ring.request_list) ||
i915_seqno_passed(dev_priv->render_ring.get_seqno(&dev_priv->render_ring),
i915_get_tail_request(dev)->seqno)) {
bool missed_wakeup = false;

dev_priv->hangcheck_count = 0;

/* Issue a wake-up to catch stuck h/w. */
if (dev_priv->render_ring.waiting_gem_seqno &&
waitqueue_active(&dev_priv->render_ring.irq_queue)) {
wake_up_all(&dev_priv->render_ring.irq_queue);
missed_wakeup = true;
}

if (dev_priv->bsd_ring.waiting_gem_seqno &&
waitqueue_active(&dev_priv->bsd_ring.irq_queue)) {
wake_up_all(&dev_priv->bsd_ring.irq_queue);
missed_wakeup = true;
}

if (dev_priv->blt_ring.waiting_gem_seqno &&
waitqueue_active(&dev_priv->blt_ring.irq_queue)) {
wake_up_all(&dev_priv->blt_ring.irq_queue);
missed_wakeup = true;
}

if (missed_wakeup)
DRM_ERROR("Hangcheck timer elapsed... GPU idle, missed IRQ.\n");
return;
}

if (dev_priv->last_acthd == acthd &&
dev_priv->last_instdone == instdone &&
dev_priv->last_instdone1 == instdone1) {
Expand All @@ -1385,7 +1381,7 @@ void i915_hangcheck_elapsed(unsigned long data)
if (tmp & RING_WAIT) {
I915_WRITE(PRB0_CTL, tmp);
POSTING_READ(PRB0_CTL);
goto out;
goto repeat;
}
}

Expand All @@ -1400,7 +1396,7 @@ void i915_hangcheck_elapsed(unsigned long data)
dev_priv->last_instdone1 = instdone1;
}

out:
repeat:
/* Reset timer case chip hangs without another request being added */
mod_timer(&dev_priv->hangcheck_timer,
jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD));
Expand Down

0 comments on commit a84e8f2

Please sign in to comment.