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

drm/i915: Refactor common list iteration over GGTT vma

In quite a few places, we have a list iteration over the vma on an
object that only want to inspect GGTT vma. By construction, these are
placed at the start of the list, so we have copied that knowledge into
many callsites. Pull that knowledge back to i915_vma.h and provide a
for_each_ggtt_vma() to tidy up the code.

v2: Add a backreference from vma_create() to remind ourselves why we put
ggtt vma at the head of the obj->vma_list (and ppgtt vma at the tail).
v3: Fixup s/vma/V/

Suggested-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20171207211407.31549-1-chris@chris-wilson.co.uk

+30 -29
+2 -2
drivers/gpu/drm/i915/i915_debugfs.c
··· 111 111 u64 size = 0; 112 112 struct i915_vma *vma; 113 113 114 - list_for_each_entry(vma, &obj->vma_list, obj_link) { 115 - if (i915_vma_is_ggtt(vma) && drm_mm_node_allocated(&vma->node)) 114 + for_each_ggtt_vma(vma, obj) { 115 + if (drm_mm_node_allocated(&vma->node)) 116 116 size += vma->node.size; 117 117 } 118 118
+4 -14
drivers/gpu/drm/i915/i915_gem.c
··· 714 714 intel_fb_obj_flush(obj, 715 715 fb_write_origin(obj, I915_GEM_DOMAIN_GTT)); 716 716 717 - list_for_each_entry(vma, &obj->vma_list, obj_link) { 718 - if (!i915_vma_is_ggtt(vma)) 719 - break; 720 - 717 + for_each_ggtt_vma(vma, obj) { 721 718 if (vma->iomap) 722 719 continue; 723 720 ··· 1566 1569 1567 1570 GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj)); 1568 1571 1569 - list_for_each_entry(vma, &obj->vma_list, obj_link) { 1570 - if (!i915_vma_is_ggtt(vma)) 1571 - break; 1572 - 1572 + for_each_ggtt_vma(vma, obj) { 1573 1573 if (i915_vma_is_active(vma)) 1574 1574 continue; 1575 1575 ··· 2045 2051 drm_vma_node_unmap(&obj->base.vma_node, 2046 2052 obj->base.dev->anon_inode->i_mapping); 2047 2053 2048 - list_for_each_entry(vma, &obj->vma_list, obj_link) { 2049 - if (!i915_vma_is_ggtt(vma)) 2050 - break; 2051 - 2054 + for_each_ggtt_vma(vma, obj) 2052 2055 i915_vma_unset_userfault(vma); 2053 - } 2054 2056 } 2055 2057 2056 2058 /** ··· 3812 3822 * dropped the fence as all snoopable access is 3813 3823 * supposed to be linear. 3814 3824 */ 3815 - list_for_each_entry(vma, &obj->vma_list, obj_link) { 3825 + for_each_ggtt_vma(vma, obj) { 3816 3826 ret = i915_vma_put_fence(vma); 3817 3827 if (ret) 3818 3828 return ret;
+1 -4
drivers/gpu/drm/i915/i915_gem_gtt.c
··· 3620 3620 bool ggtt_bound = false; 3621 3621 struct i915_vma *vma; 3622 3622 3623 - list_for_each_entry(vma, &obj->vma_list, obj_link) { 3624 - if (vma->vm != &ggtt->base) 3625 - continue; 3626 - 3623 + for_each_ggtt_vma(vma, obj) { 3627 3624 if (!i915_vma_unbind(vma)) 3628 3625 continue; 3629 3626
+2 -8
drivers/gpu/drm/i915/i915_gem_tiling.c
··· 205 205 if (tiling_mode == I915_TILING_NONE) 206 206 return 0; 207 207 208 - list_for_each_entry(vma, &obj->vma_list, obj_link) { 209 - if (!i915_vma_is_ggtt(vma)) 210 - break; 211 - 208 + for_each_ggtt_vma(vma, obj) { 212 209 if (i915_vma_fence_prepare(vma, tiling_mode, stride)) 213 210 continue; 214 211 ··· 282 285 } 283 286 mutex_unlock(&obj->mm.lock); 284 287 285 - list_for_each_entry(vma, &obj->vma_list, obj_link) { 286 - if (!i915_vma_is_ggtt(vma)) 287 - break; 288 - 288 + for_each_ggtt_vma(vma, obj) { 289 289 vma->fence_size = 290 290 i915_gem_fence_size(i915, vma->size, tiling, stride); 291 291 vma->fence_alignment =
+6
drivers/gpu/drm/i915/i915_vma.c
··· 142 142 i915_gem_object_get_stride(obj)); 143 143 GEM_BUG_ON(!is_power_of_2(vma->fence_alignment)); 144 144 145 + /* 146 + * We put the GGTT vma at the start of the vma-list, followed 147 + * by the ppGGTT vma. This allows us to break early when 148 + * iterating over only the GGTT vma for an object, see 149 + * for_each_ggtt_vma() 150 + */ 145 151 vma->flags |= I915_VMA_GGTT; 146 152 list_add(&vma->obj_link, &obj->vma_list); 147 153 } else {
+15 -1
drivers/gpu/drm/i915/i915_vma.h
··· 408 408 __i915_vma_unpin_fence(vma); 409 409 } 410 410 411 - #endif 411 + #define for_each_until(cond) if (cond) break; else 412 412 413 + /** 414 + * for_each_ggtt_vma - Iterate over the GGTT VMA belonging to an object. 415 + * @V: the #i915_vma iterator 416 + * @OBJ: the #drm_i915_gem_object 417 + * 418 + * GGTT VMA are placed at the being of the object's vma_list, see 419 + * vma_create(), so we can stop our walk as soon as we see a ppgtt VMA, 420 + * or the list is empty ofc. 421 + */ 422 + #define for_each_ggtt_vma(V, OBJ) \ 423 + list_for_each_entry(V, &(OBJ)->vma_list, obj_link) \ 424 + for_each_until(!i915_vma_is_ggtt(V)) 425 + 426 + #endif