As a prelude to the next step where we want to perform all the object
allocations together under the same lock, we first must delay the
i915_vma_pin() as that implicitly does the allocations for us, one by
one. As it only does the allocations one by one, it is not allowed to
wait/evict, whereas pulling all the allocations together the entire set
can be scheduled as one.

Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>
---
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 43 +++++++++++--------
 1 file changed, 25 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index 60926209b1fc..46fcbdf8161c 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -664,16 +664,6 @@ eb_add_vma(struct i915_execbuffer *eb,
                                                    eb->lut_size)]);
        }
 
-       if (eb_pin_vma(eb, entry, ev)) {
-               if (entry->offset != vma->node.start) {
-                       entry->offset = vma->node.start | UPDATE;
-                       eb->args->flags |= __EXEC_HAS_RELOC;
-               }
-       } else {
-               eb_unreserve_vma(ev);
-               list_add_tail(&ev->bind_link, &eb->unbound);
-       }
-
        list_add_tail(&ev->lock_link, &eb->lock);
 }
 
@@ -1339,18 +1329,37 @@ static int eb_prepare_vma(struct eb_vma *ev)
        return 0;
 }
 
-static int eb_reserve(struct i915_execbuffer *eb)
+static int eb_reserve_vm(struct i915_execbuffer *eb)
 {
        const unsigned int count = eb->buffer_count;
        struct i915_address_space *vm = eb->context->vm;
-       struct list_head last;
        unsigned int i, pass;
-       struct eb_vma *ev;
        int err = 0;
 
+       for (i = 0; i < count; i++) {
+               struct drm_i915_gem_exec_object2 *entry = &eb->exec[i];
+               struct eb_vma *ev = &eb->vma[i];
+
+               if (eb_pin_vma(eb, entry, ev)) {
+                       struct i915_vma *vma = ev->vma;
+
+                       if (entry->offset != vma->node.start) {
+                               entry->offset = vma->node.start | UPDATE;
+                               eb->args->flags |= __EXEC_HAS_RELOC;
+                       }
+               } else {
+                       eb_unreserve_vma(ev);
+                       list_add_tail(&ev->bind_link, &eb->unbound);
+               }
+       }
+       if (list_empty(&eb->unbound))
+               return 0;
+
        pass = 0;
        do {
                struct eb_vm_work *work;
+               struct list_head last;
+               struct eb_vma *ev;
 
                list_for_each_entry(ev, &eb->unbound, bind_link) {
                        err = eb_prepare_vma(ev);
@@ -2404,11 +2413,9 @@ static int eb_relocate(struct i915_execbuffer *eb)
        if (err)
                return err;
 
-       if (!list_empty(&eb->unbound)) {
-               err = eb_reserve(eb);
-               if (err)
-                       return err;
-       }
+       err = eb_reserve_vm(eb);
+       if (err)
+               return err;
 
        /* The objects are in their final locations, apply the relocations. */
        if (eb->args->flags & __EXEC_HAS_RELOC) {
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to