]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/gpu/drm/i915/i915_gem.c
Merge remote-tracking branch 'drm-intel/for-linux-next'
[karo-tx-linux.git] / drivers / gpu / drm / i915 / i915_gem.c
index e34b48e862e779e89b368d1cb04953971dc58817..66f8133c18f7a64cbe271adfbd2a4abb3f2676c9 100644 (file)
@@ -2354,15 +2354,24 @@ static void i915_gem_free_request(struct drm_i915_gem_request *request)
        kfree(request);
 }
 
-static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv,
-                                     struct intel_ring_buffer *ring)
+static void i915_gem_reset_ring_status(struct drm_i915_private *dev_priv,
+                                      struct intel_ring_buffer *ring)
 {
-       u32 completed_seqno;
-       u32 acthd;
+       u32 completed_seqno = ring->get_seqno(ring, false);
+       u32 acthd = intel_ring_get_active_head(ring);
+       struct drm_i915_gem_request *request;
+
+       list_for_each_entry(request, &ring->request_list, list) {
+               if (i915_seqno_passed(completed_seqno, request->seqno))
+                       continue;
 
-       acthd = intel_ring_get_active_head(ring);
-       completed_seqno = ring->get_seqno(ring, false);
+               i915_set_reset_status(ring, request, acthd);
+       }
+}
 
+static void i915_gem_reset_ring_cleanup(struct drm_i915_private *dev_priv,
+                                       struct intel_ring_buffer *ring)
+{
        while (!list_empty(&ring->request_list)) {
                struct drm_i915_gem_request *request;
 
@@ -2370,9 +2379,6 @@ static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv,
                                           struct drm_i915_gem_request,
                                           list);
 
-               if (request->seqno > completed_seqno)
-                       i915_set_reset_status(ring, request, acthd);
-
                i915_gem_free_request(request);
        }
 
@@ -2414,8 +2420,16 @@ void i915_gem_reset(struct drm_device *dev)
        struct intel_ring_buffer *ring;
        int i;
 
+       /*
+        * Before we free the objects from the requests, we need to inspect
+        * them for finding the guilty party. As the requests only borrow
+        * their reference to the objects, the inspection must be done first.
+        */
+       for_each_ring(ring, dev_priv, i)
+               i915_gem_reset_ring_status(dev_priv, ring);
+
        for_each_ring(ring, dev_priv, i)
-               i915_gem_reset_ring_lists(dev_priv, ring);
+               i915_gem_reset_ring_cleanup(dev_priv, ring);
 
        i915_gem_cleanup_ringbuffer(dev);
 
@@ -4461,10 +4475,9 @@ i915_gem_init_hw(struct drm_device *dev)
        if (dev_priv->ellc_size)
                I915_WRITE(HSW_IDICR, I915_READ(HSW_IDICR) | IDIHASHMSK(0xf));
 
-       if (IS_HSW_GT3(dev))
-               I915_WRITE(MI_PREDICATE_RESULT_2, LOWER_SLICE_ENABLED);
-       else
-               I915_WRITE(MI_PREDICATE_RESULT_2, LOWER_SLICE_DISABLED);
+       if (IS_HASWELL(dev))
+               I915_WRITE(MI_PREDICATE_RESULT_2, IS_HSW_GT3(dev) ?
+                          LOWER_SLICE_ENABLED : LOWER_SLICE_DISABLED);
 
        if (HAS_PCH_NOP(dev)) {
                u32 temp = I915_READ(GEN7_MSG_CTL);