drm/i915: Add tracepoints
[pandora-kernel.git] / drivers / gpu / drm / i915 / i915_irq.c
index 8f52766..4dfeec7 100644 (file)
@@ -31,6 +31,7 @@
 #include "drm.h"
 #include "i915_drm.h"
 #include "i915_drv.h"
+#include "i915_trace.h"
 #include "intel_drv.h"
 
 #define MAX_NOPID ((u32)~0)
@@ -279,7 +280,9 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev)
                }
 
                if (gt_iir & GT_USER_INTERRUPT) {
-                       dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev);
+                       u32 seqno = i915_get_gem_seqno(dev);
+                       dev_priv->mm.irq_gem_seqno = seqno;
+                       trace_i915_gem_request_complete(dev, seqno);
                        DRM_WAKEUP(&dev_priv->irq_queue);
                }
 
@@ -309,12 +312,12 @@ static void i915_error_work_func(struct work_struct *work)
        DRM_DEBUG("generating error event\n");
        kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, error_event);
 
-       if (dev_priv->mm.wedged) {
+       if (atomic_read(&dev_priv->mm.wedged)) {
                if (IS_I965G(dev)) {
                        DRM_DEBUG("resetting chip\n");
                        kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_event);
                        if (!i965_reset(dev, GDRST_RENDER)) {
-                               dev_priv->mm.wedged = 0;
+                               atomic_set(&dev_priv->mm.wedged, 0);
                                kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_done_event);
                        }
                } else {
@@ -385,7 +388,7 @@ out:
  * so userspace knows something bad happened (should trigger collection
  * of a ring dump etc.).
  */
-static void i915_handle_error(struct drm_device *dev)
+static void i915_handle_error(struct drm_device *dev, bool wedged)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        u32 eir = I915_READ(EIR);
@@ -495,7 +498,9 @@ static void i915_handle_error(struct drm_device *dev)
                I915_WRITE(IIR, I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT);
        }
 
-       if (dev_priv->mm.wedged) {
+       if (wedged) {
+               atomic_set(&dev_priv->mm.wedged, 1);
+
                /*
                 * Wakeup waiting processes so they don't hang
                 */
@@ -548,7 +553,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
                pipeb_stats = I915_READ(PIPEBSTAT);
 
                if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
-                       i915_handle_error(dev);
+                       i915_handle_error(dev, false);
 
                /*
                 * Clear the PIPE(A|B)STAT regs before the IIR
@@ -620,7 +625,9 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
                }
 
                if (iir & I915_USER_INTERRUPT) {
-                       dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev);
+                       u32 seqno = i915_get_gem_seqno(dev);
+                       dev_priv->mm.irq_gem_seqno = seqno;
+                       trace_i915_gem_request_complete(dev, seqno);
                        DRM_WAKEUP(&dev_priv->irq_queue);
                        dev_priv->hangcheck_count = 0;
                        mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
@@ -934,8 +941,7 @@ void i915_hangcheck_elapsed(unsigned long data)
 
        if (dev_priv->last_acthd == acthd && dev_priv->hangcheck_count > 0) {
                DRM_ERROR("Hangcheck timer elapsed... GPU hung\n");
-               dev_priv->mm.wedged = true; /* Hopefully this is atomic */
-               i915_handle_error(dev);
+               i915_handle_error(dev, true);
                return;
        }