[PATCH 10/17] drm/i915: Use vma->exec_entry as our double-entry placeholder

Chris Wilson
2016-08-22T08:04:08Z

This has the benefit of not requiring us to manipulate the
vma->exec_link list when tearing down the execbuffer, and is a
marginally cheaper test to detect the user error.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_gem_evict.c | 16 ++-----
drivers/gpu/drm/i915/i915_gem_execbuffer.c | 74 ++++++++++++++++--------------
drivers/gpu/drm/i915/i915_gem_gtt.c | 1 -
3 files changed, 43 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
index a8f6825cf14f..79ce873b4891 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -52,9 +52,6 @@ mark_free(struct i915_vma *vma, unsigned int flags, struct list_head *unwind)
if (i915_vma_is_pinned(vma))
return false;

- if (WARN_ON(!list_empty(&vma->exec_list)))
- return false;
-
if (flags & PIN_NONFAULT && vma->obj->fault_mappable)
return false;

@@ -140,8 +137,6 @@ search_again:
list_for_each_entry_safe(vma, next, &eviction_list, exec_list) {
ret = drm_mm_scan_remove_block(&vma->node);
BUG_ON(ret);
-
- INIT_LIST_HEAD(&vma->exec_list);
}

/* Can we unpin some objects such as idle hw contents,
@@ -188,16 +183,12 @@ found:
if (drm_mm_scan_remove_block(&vma->node))
__i915_vma_pin(vma);
else
- list_del_init(&vma->exec_list);
+ list_del(&vma->exec_list);
}

/* Unbinding will emit any required flushes */
- while (!list_empty(&eviction_list)) {
- vma = list_first_entry(&eviction_list,
- struct i915_vma,
- exec_list);
-
- list_del_init(&vma->exec_list);
+ ret = 0;
+ list_for_each_entry_safe(vma, next, &eviction_list, exec_list) {
__i915_vma_unpin(vma);
if (ret == 0)
ret = i915_vma_unbind(vma);
@@ -273,7 +264,6 @@ int i915_gem_evict_for_vma(struct i915_vma *target, unsigned int flags)
}

list_for_each_entry_safe(vma, next, &eviction_list, exec_list) {
- list_del_init(&vma->exec_list);
__i915_vma_unpin(vma);
if (ret == 0)
ret = i915_vma_unbind(vma);
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 7cb5b9ad9212..82496dd73309 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -103,13 +103,39 @@ eb_create(struct i915_execbuffer *eb)
} else
eb->and = -eb->args->buffer_count;

- INIT_LIST_HEAD(&eb->vmas);
return 0;
}

+static inline void
+__eb_unreserve_vma(struct i915_vma *vma,
+ const struct drm_i915_gem_exec_object2 *entry)
+{
+ if (unlikely(entry->flags & __EXEC_OBJECT_HAS_FENCE))
+ i915_vma_unpin_fence(vma);
+
+ if (entry->flags & __EXEC_OBJECT_HAS_PIN)
+ __i915_vma_unpin(vma);
+}
+
+static void
+eb_unreserve_vma(struct i915_vma *vma)
+{
+ struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
+
+ __eb_unreserve_vma(vma, entry);
+ entry->flags &= ~(__EXEC_OBJECT_HAS_FENCE | __EXEC_OBJECT_HAS_PIN);
+}
+
static void
eb_reset(struct i915_execbuffer *eb)
{
+ struct i915_vma *vma;
+
+ list_for_each_entry(vma, &eb->vmas, exec_list) {
+ eb_unreserve_vma(vma);
+ vma->exec_entry = NULL;
+ }
+
if (eb->and >= 0)
memset(eb->buckets, 0, (eb->and+1)*sizeof(struct hlist_head));
}
@@ -141,6 +167,8 @@ eb_lookup_vmas(struct i915_execbuffer *eb)
struct list_head objects;
int i, ret;

+ INIT_LIST_HEAD(&eb->vmas);
+
INIT_LIST_HEAD(&objects);
spin_lock(&eb->file->table_lock);
/* Grab a reference to the object and release the lock so we can lookup
@@ -246,38 +274,22 @@ static struct i915_vma *eb_get_vma(struct i915_execbuffer *eb, unsigned long han
}
}

-static void
-eb_unreserve_vma(struct i915_vma *vma)
+static void eb_destroy(struct i915_execbuffer *eb)
{
- struct drm_i915_gem_exec_object2 *entry;
-
- if (!drm_mm_node_allocated(&vma->node))
- return;
-
- entry = vma->exec_entry;
-
- if (entry->flags & __EXEC_OBJECT_HAS_FENCE)
- i915_vma_unpin_fence(vma);
+ struct i915_vma *vma;

- if (entry->flags & __EXEC_OBJECT_HAS_PIN)
- __i915_vma_unpin(vma);
+ list_for_each_entry(vma, &eb->vmas, exec_list) {
+ if (!vma->exec_entry)
+ continue;

- entry->flags &= ~(__EXEC_OBJECT_HAS_FENCE | __EXEC_OBJECT_HAS_PIN);
-}
+ __eb_unreserve_vma(vma, vma->exec_entry);
+ vma->exec_entry = NULL;
+ }

-static void eb_destroy(struct i915_execbuffer *eb)
-{
i915_gem_context_put(eb->ctx);

- while (!list_empty(&eb->vmas)) {
- struct i915_vma *vma;
-
- vma = list_first_entry(&eb->vmas,
- struct i915_vma,
- exec_list);
- list_del_init(&vma->exec_list);
- eb_unreserve_vma(vma);
- }
+ if (eb->buckets)
+ kfree(eb->buckets);
}

static inline int use_cpu_reloc(struct drm_i915_gem_object *obj)
@@ -985,12 +997,7 @@ eb_relocate_slow(struct i915_execbuffer *eb)
int i, total, ret;

/* We may process another execbuffer during the unlock... */
- while (!list_empty(&eb->vmas)) {
- vma = list_first_entry(&eb->vmas, struct i915_vma, exec_list);
- list_del_init(&vma->exec_list);
- eb_unreserve_vma(vma);
- }
-
+ eb_reset(eb);
mutex_unlock(&dev->struct_mutex);

total = 0;
@@ -1051,7 +1058,6 @@ eb_relocate_slow(struct i915_execbuffer *eb)
}

/* reacquire the objects */
- eb_reset(eb);
ret = eb_lookup_vmas(eb);
if (ret)
goto err;
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 0061c3841760..f51e483569b9 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -3357,7 +3357,6 @@ __i915_vma_create(struct drm_i915_gem_object *obj,
if (vma == NULL)
return ERR_PTR(-ENOMEM);

- 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_fence, NULL);
--
2.9.3