Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/i915: Move frontbuffer CS write tracking from ggtt vma to object

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>

+19 -20
+11
drivers/gpu/drm/i915/i915_gem.c
··· 3886 3886 return err; 3887 3887 } 3888 3888 3889 + static void 3890 + frontbuffer_retire(struct i915_gem_active *active, 3891 + struct drm_i915_gem_request *request) 3892 + { 3893 + struct drm_i915_gem_object *obj = 3894 + container_of(active, typeof(*obj), frontbuffer_write); 3895 + 3896 + intel_fb_obj_flush(obj, true, ORIGIN_CS); 3897 + } 3898 + 3889 3899 void i915_gem_object_init(struct drm_i915_gem_object *obj, 3890 3900 const struct drm_i915_gem_object_ops *ops) 3891 3901 { ··· 3913 3903 obj->resv = &obj->__builtin_resv; 3914 3904 3915 3905 obj->frontbuffer_ggtt_origin = ORIGIN_GTT; 3906 + init_request_active(&obj->frontbuffer_write, frontbuffer_retire); 3916 3907 3917 3908 obj->mm.madv = I915_MADV_WILLNEED; 3918 3909 INIT_RADIX_TREE(&obj->mm.get_page.radix, GFP_KERNEL | __GFP_NOWARN);
+2 -3
drivers/gpu/drm/i915/i915_gem_execbuffer.c
··· 1276 1276 list_move_tail(&vma->vm_link, &vma->vm->active_list); 1277 1277 1278 1278 if (flags & EXEC_OBJECT_WRITE) { 1279 - i915_gem_active_set(&vma->last_write, req); 1280 - 1281 - intel_fb_obj_invalidate(obj, ORIGIN_CS); 1279 + if (intel_fb_obj_invalidate(obj, ORIGIN_CS)) 1280 + i915_gem_active_set(&obj->frontbuffer_write, req); 1282 1281 1283 1282 /* update for the implicit flush after a batch */ 1284 1283 obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS;
+1
drivers/gpu/drm/i915/i915_gem_object.h
··· 103 103 104 104 atomic_t frontbuffer_bits; 105 105 unsigned int frontbuffer_ggtt_origin; /* write once */ 106 + struct i915_gem_active frontbuffer_write; 106 107 107 108 /** Current tiling stride for the object, if it's tiled. */ 108 109 unsigned int tiling_and_stride;
+2 -2
drivers/gpu/drm/i915/i915_gpu_error.c
··· 886 886 887 887 for (i = 0; i < I915_NUM_ENGINES; i++) 888 888 err->rseqno[i] = __active_get_seqno(&vma->last_read[i]); 889 - err->wseqno = __active_get_seqno(&vma->last_write); 890 - err->engine = __active_get_engine_id(&vma->last_write); 889 + err->wseqno = __active_get_seqno(&obj->frontbuffer_write); 890 + err->engine = __active_get_engine_id(&obj->frontbuffer_write); 891 891 892 892 err->gtt_offset = vma->node.start; 893 893 err->read_domains = obj->base.read_domains;
-12
drivers/gpu/drm/i915/i915_vma.c
··· 68 68 } 69 69 } 70 70 71 - static void 72 - i915_ggtt_retire__write(struct i915_gem_active *active, 73 - struct drm_i915_gem_request *request) 74 - { 75 - struct i915_vma *vma = 76 - container_of(active, struct i915_vma, last_write); 77 - 78 - intel_fb_obj_flush(vma->obj, true, ORIGIN_CS); 79 - } 80 - 81 71 static struct i915_vma * 82 72 __i915_vma_create(struct drm_i915_gem_object *obj, 83 73 struct i915_address_space *vm, ··· 86 96 INIT_LIST_HEAD(&vma->exec_list); 87 97 for (i = 0; i < ARRAY_SIZE(vma->last_read); i++) 88 98 init_request_active(&vma->last_read[i], i915_vma_retire); 89 - init_request_active(&vma->last_write, 90 - i915_is_ggtt(vm) ? i915_ggtt_retire__write : NULL); 91 99 init_request_active(&vma->last_fence, NULL); 92 100 list_add(&vma->vm_link, &vm->unbound_list); 93 101 vma->vm = vm;
-1
drivers/gpu/drm/i915/i915_vma.h
··· 80 80 81 81 unsigned int active; 82 82 struct i915_gem_active last_read[I915_NUM_ENGINES]; 83 - struct i915_gem_active last_write; 84 83 struct i915_gem_active last_fence; 85 84 86 85 /**
+3 -2
drivers/gpu/drm/i915/intel_frontbuffer.h
··· 53 53 * until the rendering completes or a flip on this frontbuffer plane is 54 54 * scheduled. 55 55 */ 56 - static inline void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj, 56 + static inline bool intel_fb_obj_invalidate(struct drm_i915_gem_object *obj, 57 57 enum fb_op_origin origin) 58 58 { 59 59 unsigned int frontbuffer_bits; 60 60 61 61 frontbuffer_bits = atomic_read(&obj->frontbuffer_bits); 62 62 if (!frontbuffer_bits) 63 - return; 63 + return false; 64 64 65 65 __intel_fb_obj_invalidate(obj, origin, frontbuffer_bits); 66 + return true; 66 67 } 67 68 68 69 /**