aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2017-10-13 16:26:16 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2017-10-16 15:44:19 -0400
commit3d574a6bbb12a6c3bbeea807a1724b44a0f6ebbb (patch)
tree03aab19734eab1742c772553d93c71c759609ced
parentf46250e4773149ab0fd8262cdc28764bb58a2d62 (diff)
drm/i915: Remove walk over obj->vma_list for the shrinker
In the next patch, we want to reduce the lock coverage within the shrinker, and one of the dangerous walks we have is over obj->vma_list. We are only walking the obj->vma_list in order to check whether it has been permanently pinned by HW access, typically via use on the scanout. But we have a couple of other long term pins, the context objects for which we currently have to check the individual vma pin_count. If we instead mark these using obj->pin_display, we can forgo the dangerous and sometimes slow list iteration. v2: Rearrange code to try and avoid confusion from false associations due to arrangement of whitespace along with rebasing on obj->pin_global. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20171013202621.7276-4-chris@chris-wilson.co.uk
-rw-r--r--drivers/gpu/drm/i915/i915_gem_shrinker.c27
-rw-r--r--drivers/gpu/drm/i915/intel_lrc.c2
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c8
3 files changed, 16 insertions, 21 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c
index b5c87d89777b..575a6b735f39 100644
--- a/drivers/gpu/drm/i915/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c
@@ -71,25 +71,6 @@ static void shrinker_unlock(struct drm_i915_private *dev_priv, bool unlock)
71 mutex_unlock(&dev_priv->drm.struct_mutex); 71 mutex_unlock(&dev_priv->drm.struct_mutex);
72} 72}
73 73
74static bool any_vma_pinned(struct drm_i915_gem_object *obj)
75{
76 struct i915_vma *vma;
77
78 list_for_each_entry(vma, &obj->vma_list, obj_link) {
79 /* Only GGTT vma may be permanently pinned, and are always
80 * at the start of the list. We can stop hunting as soon
81 * as we see a ppGTT vma.
82 */
83 if (!i915_vma_is_ggtt(vma))
84 break;
85
86 if (i915_vma_is_pinned(vma))
87 return true;
88 }
89
90 return false;
91}
92
93static bool swap_available(void) 74static bool swap_available(void)
94{ 75{
95 return get_nr_swap_pages() > 0; 76 return get_nr_swap_pages() > 0;
@@ -115,7 +96,13 @@ static bool can_release_pages(struct drm_i915_gem_object *obj)
115 if (atomic_read(&obj->mm.pages_pin_count) > obj->bind_count) 96 if (atomic_read(&obj->mm.pages_pin_count) > obj->bind_count)
116 return false; 97 return false;
117 98
118 if (any_vma_pinned(obj)) 99 /* If any vma are "permanently" pinned, it will prevent us from
100 * reclaiming the obj->mm.pages. We only allow scanout objects to claim
101 * a permanent pin, along with a few others like the context objects.
102 * To simplify the scan, and to avoid walking the list of vma under the
103 * object, we just check the count of its permanently pinned.
104 */
105 if (obj->pin_global)
119 return false; 106 return false;
120 107
121 /* We can only return physical pages to the system if we can either 108 /* We can only return physical pages to the system if we can either
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 766552f2cfae..7f45dd7dc3e5 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -1093,6 +1093,7 @@ execlists_context_pin(struct intel_engine_cs *engine,
1093 i915_ggtt_offset(ce->ring->vma); 1093 i915_ggtt_offset(ce->ring->vma);
1094 1094
1095 ce->state->obj->mm.dirty = true; 1095 ce->state->obj->mm.dirty = true;
1096 ce->state->obj->pin_global++;
1096 1097
1097 i915_gem_context_get(ctx); 1098 i915_gem_context_get(ctx);
1098out: 1099out:
@@ -1120,6 +1121,7 @@ static void execlists_context_unpin(struct intel_engine_cs *engine,
1120 1121
1121 intel_ring_unpin(ce->ring); 1122 intel_ring_unpin(ce->ring);
1122 1123
1124 ce->state->obj->pin_global--;
1123 i915_gem_object_unpin_map(ce->state->obj); 1125 i915_gem_object_unpin_map(ce->state->obj);
1124 i915_vma_unpin(ce->state); 1126 i915_vma_unpin(ce->state);
1125 1127
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index b2a6cb09c6e7..8da1bde442dd 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1244,6 +1244,8 @@ int intel_ring_pin(struct intel_ring *ring,
1244 if (IS_ERR(addr)) 1244 if (IS_ERR(addr))
1245 goto err; 1245 goto err;
1246 1246
1247 vma->obj->pin_global++;
1248
1247 ring->vaddr = addr; 1249 ring->vaddr = addr;
1248 return 0; 1250 return 0;
1249 1251
@@ -1275,6 +1277,7 @@ void intel_ring_unpin(struct intel_ring *ring)
1275 i915_gem_object_unpin_map(ring->vma->obj); 1277 i915_gem_object_unpin_map(ring->vma->obj);
1276 ring->vaddr = NULL; 1278 ring->vaddr = NULL;
1277 1279
1280 ring->vma->obj->pin_global--;
1278 i915_vma_unpin(ring->vma); 1281 i915_vma_unpin(ring->vma);
1279} 1282}
1280 1283
@@ -1439,6 +1442,7 @@ intel_ring_context_pin(struct intel_engine_cs *engine,
1439 goto err; 1442 goto err;
1440 1443
1441 ce->state->obj->mm.dirty = true; 1444 ce->state->obj->mm.dirty = true;
1445 ce->state->obj->pin_global++;
1442 } 1446 }
1443 1447
1444 /* The kernel context is only used as a placeholder for flushing the 1448 /* The kernel context is only used as a placeholder for flushing the
@@ -1473,8 +1477,10 @@ static void intel_ring_context_unpin(struct intel_engine_cs *engine,
1473 if (--ce->pin_count) 1477 if (--ce->pin_count)
1474 return; 1478 return;
1475 1479
1476 if (ce->state) 1480 if (ce->state) {
1481 ce->state->obj->pin_global--;
1477 i915_vma_unpin(ce->state); 1482 i915_vma_unpin(ce->state);
1483 }
1478 1484
1479 i915_gem_context_put(ctx); 1485 i915_gem_context_put(ctx);
1480} 1486}