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

drm/i915/gem: Protect used framebuffers from casual eviction

In the shrinker, we protect framebuffers from light reclaim as we
typically expect framebuffers to be reused in the near future (and with
low latency requirements). We can apply the same logic to the GGTT
eviction and defer framebuffers to the second pass only used if the
caller is desperate enough to wait for space to become available.
In most cases, the caller will use a smaller partial vma instead of
trying to force the object into the GGTT if doing so will cause other
users to be evicted.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210119214336.1463-5-chris@chris-wilson.co.uk

+34 -2
+3 -1
drivers/gpu/drm/i915/display/intel_frontbuffer.c
··· 225 225 struct i915_vma *vma; 226 226 227 227 spin_lock(&obj->vma.lock); 228 - for_each_ggtt_vma(vma, obj) 228 + for_each_ggtt_vma(vma, obj) { 229 + i915_vma_clear_scanout(vma); 229 230 vma->display_alignment = I915_GTT_MIN_ALIGNMENT; 231 + } 230 232 spin_unlock(&obj->vma.lock); 231 233 232 234 RCU_INIT_POINTER(obj->frontbuffer, NULL);
+1
drivers/gpu/drm/i915/gem/i915_gem_domain.c
··· 416 416 } 417 417 418 418 vma->display_alignment = max_t(u64, vma->display_alignment, alignment); 419 + i915_vma_mark_scanout(vma); 419 420 420 421 i915_gem_object_flush_if_display_locked(obj); 421 422
+12 -1
drivers/gpu/drm/i915/i915_gem_evict.c
··· 61 61 return drm_mm_scan_add_block(scan, &vma->node); 62 62 } 63 63 64 + static bool defer_evict(struct i915_vma *vma) 65 + { 66 + if (i915_vma_is_active(vma)) 67 + return true; 68 + 69 + if (i915_vma_is_scanout(vma)) 70 + return true; 71 + 72 + return false; 73 + } 74 + 64 75 /** 65 76 * i915_gem_evict_something - Evict vmas to make room for binding a new one 66 77 * @vm: address space to evict from ··· 161 150 * To notice when we complete one full cycle, we record the 162 151 * first active element seen, before moving it to the tail. 163 152 */ 164 - if (active != ERR_PTR(-EAGAIN) && i915_vma_is_active(vma)) { 153 + if (active != ERR_PTR(-EAGAIN) && defer_evict(vma)) { 165 154 if (!active) 166 155 active = vma; 167 156
+15
drivers/gpu/drm/i915/i915_vma.h
··· 363 363 364 364 void i915_vma_parked(struct intel_gt *gt); 365 365 366 + static inline bool i915_vma_is_scanout(const struct i915_vma *vma) 367 + { 368 + return test_bit(I915_VMA_SCANOUT_BIT, __i915_vma_flags(vma)); 369 + } 370 + 371 + static inline void i915_vma_mark_scanout(struct i915_vma *vma) 372 + { 373 + set_bit(I915_VMA_SCANOUT_BIT, __i915_vma_flags(vma)); 374 + } 375 + 376 + static inline void i915_vma_clear_scanout(struct i915_vma *vma) 377 + { 378 + clear_bit(I915_VMA_SCANOUT_BIT, __i915_vma_flags(vma)); 379 + } 380 + 366 381 #define for_each_until(cond) if (cond) break; else 367 382 368 383 /**
+3
drivers/gpu/drm/i915/i915_vma_types.h
··· 249 249 #define I915_VMA_USERFAULT ((int)BIT(I915_VMA_USERFAULT_BIT)) 250 250 #define I915_VMA_GGTT_WRITE ((int)BIT(I915_VMA_GGTT_WRITE_BIT)) 251 251 252 + #define I915_VMA_SCANOUT_BIT 18 253 + #define I915_VMA_SCANOUT ((int)BIT(I915_VMA_SCANOUT_BIT)) 254 + 252 255 struct i915_active active; 253 256 254 257 #define I915_VMA_PAGES_BIAS 24