drm/i915: Move frontbuffer CS write tracking from ggtt vma to object
authorChris Wilson <chris@chris-wilson.co.uk>
Wed, 16 Nov 2016 19:07:04 +0000 (19:07 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Fri, 18 Nov 2016 11:15:59 +0000 (11:15 +0000)
I tried to avoid having to track the write for every VMA by only
tracking writes to the ggtt. However, for the purposes of frontbuffer
tracking this is insufficient as we need to invalidate around writes not
just to the the ggtt but all aliased ppgtt views of the framebuffer. By
moving the critical section to the object and only doing so for
framebuffer writes we can reduce the tracking even further by only
watching framebuffers and not vma.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20161116190704.5293-1-chris@chris-wilson.co.uk
Tested-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_execbuffer.c
drivers/gpu/drm/i915/i915_gem_object.h
drivers/gpu/drm/i915/i915_gpu_error.c
drivers/gpu/drm/i915/i915_vma.c
drivers/gpu/drm/i915/i915_vma.h
drivers/gpu/drm/i915/intel_frontbuffer.h

index 7b9f5b99b0f37991f76c5da5883c49e9afbb3d0b..d5b7723bb028f081b2eff9f83c6f7a66259fd0f6 100644 (file)
@@ -3886,6 +3886,16 @@ out:
        return err;
 }
 
+static void
+frontbuffer_retire(struct i915_gem_active *active,
+                  struct drm_i915_gem_request *request)
+{
+       struct drm_i915_gem_object *obj =
+               container_of(active, typeof(*obj), frontbuffer_write);
+
+       intel_fb_obj_flush(obj, true, ORIGIN_CS);
+}
+
 void i915_gem_object_init(struct drm_i915_gem_object *obj,
                          const struct drm_i915_gem_object_ops *ops)
 {
@@ -3903,6 +3913,7 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
        obj->resv = &obj->__builtin_resv;
 
        obj->frontbuffer_ggtt_origin = ORIGIN_GTT;
+       init_request_active(&obj->frontbuffer_write, frontbuffer_retire);
 
        obj->mm.madv = I915_MADV_WILLNEED;
        INIT_RADIX_TREE(&obj->mm.get_page.radix, GFP_KERNEL | __GFP_NOWARN);
index e4efffe02fa84c88c29a2d7dfe23090085371474..097d9d8c2315e061a3600615532c6d51531ee42c 100644 (file)
@@ -1276,9 +1276,8 @@ void i915_vma_move_to_active(struct i915_vma *vma,
        list_move_tail(&vma->vm_link, &vma->vm->active_list);
 
        if (flags & EXEC_OBJECT_WRITE) {
-               i915_gem_active_set(&vma->last_write, req);
-
-               intel_fb_obj_invalidate(obj, ORIGIN_CS);
+               if (intel_fb_obj_invalidate(obj, ORIGIN_CS))
+                       i915_gem_active_set(&obj->frontbuffer_write, req);
 
                /* update for the implicit flush after a batch */
                obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS;
index 014f80392f18179c4a0eba22ba1a635ba0027c8b..6a368de9d81e7be2d6e775b3cca7c7187e6a4c88 100644 (file)
@@ -103,6 +103,7 @@ struct drm_i915_gem_object {
 
        atomic_t frontbuffer_bits;
        unsigned int frontbuffer_ggtt_origin; /* write once */
+       struct i915_gem_active frontbuffer_write;
 
        /** Current tiling stride for the object, if it's tiled. */
        unsigned int tiling_and_stride;
index d951dccbe81b8f892117df9e589dd25c4d06af5a..ae84aa4b14678b5f76ce43d532d8ae95ce1dbd61 100644 (file)
@@ -886,8 +886,8 @@ static void capture_bo(struct drm_i915_error_buffer *err,
 
        for (i = 0; i < I915_NUM_ENGINES; i++)
                err->rseqno[i] = __active_get_seqno(&vma->last_read[i]);
-       err->wseqno = __active_get_seqno(&vma->last_write);
-       err->engine = __active_get_engine_id(&vma->last_write);
+       err->wseqno = __active_get_seqno(&obj->frontbuffer_write);
+       err->engine = __active_get_engine_id(&obj->frontbuffer_write);
 
        err->gtt_offset = vma->node.start;
        err->read_domains = obj->base.read_domains;
index 738ff3a5cd6e1f118b9931dd864d561dd1c0ae39..a792dcb902b51d337f46f2c1ad7ad1ea737f4c8a 100644 (file)
@@ -68,16 +68,6 @@ i915_vma_retire(struct i915_gem_active *active,
        }
 }
 
-static void
-i915_ggtt_retire__write(struct i915_gem_active *active,
-                       struct drm_i915_gem_request *request)
-{
-       struct i915_vma *vma =
-               container_of(active, struct i915_vma, last_write);
-
-       intel_fb_obj_flush(vma->obj, true, ORIGIN_CS);
-}
-
 static struct i915_vma *
 __i915_vma_create(struct drm_i915_gem_object *obj,
                  struct i915_address_space *vm,
@@ -96,8 +86,6 @@ __i915_vma_create(struct drm_i915_gem_object *obj,
        INIT_LIST_HEAD(&vma->exec_list);
        for (i = 0; i < ARRAY_SIZE(vma->last_read); i++)
                init_request_active(&vma->last_read[i], i915_vma_retire);
-       init_request_active(&vma->last_write,
-                           i915_is_ggtt(vm) ? i915_ggtt_retire__write : NULL);
        init_request_active(&vma->last_fence, NULL);
        list_add(&vma->vm_link, &vm->unbound_list);
        vma->vm = vm;
index 2e49f5dd610764a960a10bb50812d42a0b09bc42..85446f0b0b3f1d4a757449ff7e935aa8758d6138 100644 (file)
@@ -80,7 +80,6 @@ struct i915_vma {
 
        unsigned int active;
        struct i915_gem_active last_read[I915_NUM_ENGINES];
-       struct i915_gem_active last_write;
        struct i915_gem_active last_fence;
 
        /**
index 76ceb539f9f0a73fd208cd63c35c0af2241ca13a..7bab41218cf75b243585b274243bb6d9234bcbe0 100644 (file)
@@ -53,16 +53,17 @@ void __intel_fb_obj_flush(struct drm_i915_gem_object *obj,
  * until the rendering completes or a flip on this frontbuffer plane is
  * scheduled.
  */
-static inline void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj,
+static inline bool intel_fb_obj_invalidate(struct drm_i915_gem_object *obj,
                                           enum fb_op_origin origin)
 {
        unsigned int frontbuffer_bits;
 
        frontbuffer_bits = atomic_read(&obj->frontbuffer_bits);
        if (!frontbuffer_bits)
-               return;
+               return false;
 
        __intel_fb_obj_invalidate(obj, origin, frontbuffer_bits);
+       return true;
 }
 
 /**