drm/i915: add flags to i915_ring_stop
authorMika Kuoppala <mika.kuoppala@linux.intel.com>
Fri, 28 Mar 2014 16:18:18 +0000 (18:18 +0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Wed, 9 Apr 2014 13:07:42 +0000 (15:07 +0200)
Piglit runner and QA are both looking at the dmesg for
DRM_ERRORs with test cases. Add a flag to control those
when we they are expected from related test cases.

Also add flag to control if contexts should be banned
that introduced the hang. Hangcheck is timer based and
preventing bans by adding sleeps to testcases makes
testing slower.

v2: intel_ring_stopped(), readable comment (Chris)
v3: keep compatibility (Daniel)

References: https://bugs.freedesktop.org/show_bug.cgi?id=75876
Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/intel_ringbuffer.c

index 55addaaa8222010a79fb8ed31377e39a8f9e05d9..3ea9f7ea14f1296f39e2e52af078ce5345af1548 100644 (file)
@@ -1099,8 +1099,12 @@ struct i915_gpu_error {
         */
        wait_queue_head_t reset_queue;
 
-       /* For gpu hang simulation. */
-       unsigned int stop_rings;
+       /* Userspace knobs for gpu hang simulation;
+        * combines both a ring mask, and extra flags
+        */
+       u32 stop_rings;
+#define I915_STOP_RING_ALLOW_BAN       (1 << 31)
+#define I915_STOP_RING_ALLOW_WARN      (1 << 30)
 
        /* For missed irq/seqno simulation. */
        unsigned int test_irq_rings;
@@ -2146,6 +2150,18 @@ static inline u32 i915_reset_count(struct i915_gpu_error *error)
        return ((atomic_read(&error->reset_counter) & ~I915_WEDGED) + 1) / 2;
 }
 
+static inline bool i915_stop_ring_allow_ban(struct drm_i915_private *dev_priv)
+{
+       return dev_priv->gpu_error.stop_rings == 0 ||
+               dev_priv->gpu_error.stop_rings & I915_STOP_RING_ALLOW_BAN;
+}
+
+static inline bool i915_stop_ring_allow_warn(struct drm_i915_private *dev_priv)
+{
+       return dev_priv->gpu_error.stop_rings == 0 ||
+               dev_priv->gpu_error.stop_rings & I915_STOP_RING_ALLOW_WARN;
+}
+
 void i915_gem_reset(struct drm_device *dev);
 bool i915_gem_clflush_object(struct drm_i915_gem_object *obj, bool force);
 int __must_check i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj);
index 6370a761d137d9d9055633c7f3aa6afa398fe360..85c9cf055f55f19aef57fbc79c9c2b42c284cf43 100644 (file)
@@ -2277,8 +2277,9 @@ static bool i915_context_is_banned(struct drm_i915_private *dev_priv,
                if (!i915_gem_context_is_default(ctx)) {
                        DRM_DEBUG("context hanging too fast, banning!\n");
                        return true;
-               } else if (dev_priv->gpu_error.stop_rings == 0) {
-                       DRM_ERROR("gpu hanging too fast, banning!\n");
+               } else if (i915_stop_ring_allow_ban(dev_priv)) {
+                       if (i915_stop_ring_allow_warn(dev_priv))
+                               DRM_ERROR("gpu hanging too fast, banning!\n");
                        return true;
                }
        }
index 3d76ce135a05481ca41acfe5a27f7e7fd6435d80..eb3dd26b94ded4b4c91e020108e8d0f9a6b5952d 100644 (file)
@@ -41,12 +41,16 @@ static inline int ring_space(struct intel_ring_buffer *ring)
        return space;
 }
 
-void __intel_ring_advance(struct intel_ring_buffer *ring)
+static bool intel_ring_stopped(struct intel_ring_buffer *ring)
 {
        struct drm_i915_private *dev_priv = ring->dev->dev_private;
+       return dev_priv->gpu_error.stop_rings & intel_ring_flag(ring);
+}
 
+void __intel_ring_advance(struct intel_ring_buffer *ring)
+{
        ring->tail &= ring->size - 1;
-       if (dev_priv->gpu_error.stop_rings & intel_ring_flag(ring))
+       if (intel_ring_stopped(ring))
                return;
        ring->write_tail(ring, ring->tail);
 }