drm/i915: Store a persistent reference for an object in the execbuffer cache
authorChris Wilson <chris@chris-wilson.co.uk>
Fri, 16 Jun 2017 14:05:20 +0000 (15:05 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Fri, 16 Jun 2017 15:54:05 +0000 (16:54 +0100)
If we take a reference to the object/vma when it is first used in an
execbuf, we can keep that reference until the object's file-local handle
is closed. Thereby saving a frequent ref/unref pair.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
drivers/gpu/drm/i915/i915_gem_context.c
drivers/gpu/drm/i915/i915_gem_execbuffer.c
drivers/gpu/drm/i915/i915_vma.c

index 23f74014e158b5cb01ff11944353bd0c141189fa..39ed58a21fc1f517f56d179d48b3b9bef00e9410 100644 (file)
@@ -152,6 +152,7 @@ static void vma_lut_free(struct i915_gem_context *ctx)
                hlist_for_each_entry(vma, &lut->ht[i], ctx_node) {
                        vma->obj->vma_hashed = NULL;
                        vma->ctx = NULL;
+                       i915_vma_put(vma);
                }
        }
        kvfree(lut->ht);
index a052072fe8b32eb4a96d169a93bce7cc91e443ab..d91386f0e8402bfc801283fa86d6a3e0de69d8d0 100644 (file)
 
 #define DBG_USE_CPU_RELOC 0 /* -1 force GTT relocs; 1 force CPU relocs */
 
-#define __EXEC_OBJECT_HAS_PIN          BIT(31)
-#define __EXEC_OBJECT_HAS_FENCE                BIT(30)
-#define __EXEC_OBJECT_NEEDS_MAP                BIT(29)
-#define __EXEC_OBJECT_NEEDS_BIAS       BIT(28)
-#define __EXEC_OBJECT_INTERNAL_FLAGS   (~0u << 28) /* all of the above */
+#define __EXEC_OBJECT_HAS_REF          BIT(31)
+#define __EXEC_OBJECT_HAS_PIN          BIT(30)
+#define __EXEC_OBJECT_HAS_FENCE                BIT(29)
+#define __EXEC_OBJECT_NEEDS_MAP                BIT(28)
+#define __EXEC_OBJECT_NEEDS_BIAS       BIT(27)
+#define __EXEC_OBJECT_INTERNAL_FLAGS   (~0u << 27) /* all of the above */
 #define __EXEC_OBJECT_RESERVED (__EXEC_OBJECT_HAS_PIN | __EXEC_OBJECT_HAS_FENCE)
 
 #define __EXEC_HAS_RELOC       BIT(31)
@@ -465,7 +466,7 @@ eb_add_vma(struct i915_execbuffer *eb,
         * to find the right target VMA when doing relocations.
         */
        vma->exec_entry = entry;
-       __exec_to_vma(entry) = (uintptr_t)i915_vma_get(vma);
+       __exec_to_vma(entry) = (uintptr_t)vma;
 
        err = 0;
        if (vma->node.size)
@@ -769,11 +770,19 @@ next_vma: ;
                                GEM_BUG_ON(obj->vma_hashed);
                                obj->vma_hashed = vma;
                        }
+
+                       i915_vma_get(vma);
                }
 
                err = eb_add_vma(eb, &eb->exec[i], vma);
                if (unlikely(err))
                        goto err;
+
+               /* Only after we validated the user didn't use our bits */
+               if (vma->ctx != eb->ctx) {
+                       i915_vma_get(vma);
+                       eb->exec[i].flags |= __EXEC_OBJECT_HAS_REF;
+               }
        }
 
        if (lut->ht_size & I915_CTX_RESIZE_IN_PROGRESS) {
@@ -850,9 +859,14 @@ static void eb_release_vmas(const struct i915_execbuffer *eb)
                GEM_BUG_ON(vma->exec_entry != entry);
                vma->exec_entry = NULL;
 
-               eb_unreserve_vma(vma, entry);
+               if (entry->flags & __EXEC_OBJECT_HAS_PIN)
+                       __eb_unreserve_vma(vma, entry);
+
+               if (entry->flags & __EXEC_OBJECT_HAS_REF)
+                       i915_vma_put(vma);
 
-               i915_vma_put(vma);
+               entry->flags &=
+                       ~(__EXEC_OBJECT_RESERVED | __EXEC_OBJECT_HAS_REF);
        }
 }
 
@@ -1623,7 +1637,8 @@ skip_flushes:
                struct i915_vma *vma = exec_to_vma(entry);
 
                eb_export_fence(vma->obj, eb->request, entry->flags);
-               i915_vma_put(vma);
+               if (unlikely(entry->flags & __EXEC_OBJECT_HAS_REF))
+                       i915_vma_put(vma);
        }
        eb->exec = NULL;
 
@@ -1752,7 +1767,7 @@ static struct i915_vma *eb_parse(struct i915_execbuffer *eb, bool is_master)
        vma->exec_entry =
                memset(&eb->exec[eb->buffer_count++],
                       0, sizeof(*vma->exec_entry));
-       vma->exec_entry->flags = __EXEC_OBJECT_HAS_PIN;
+       vma->exec_entry->flags = __EXEC_OBJECT_HAS_PIN | __EXEC_OBJECT_HAS_REF;
        __exec_to_vma(vma->exec_entry) = (uintptr_t)i915_vma_get(vma);
 
 out:
index 9e6a473233625653ef4f5adf2b4c97e4ea675c1c..f5c57dff288e18e241379b3308c14d81cd123ebe 100644 (file)
@@ -605,6 +605,8 @@ void i915_vma_unlink_ctx(struct i915_vma *vma)
        if (i915_vma_is_ggtt(vma))
                vma->obj->vma_hashed = NULL;
        vma->ctx = NULL;
+
+       i915_vma_put(vma);
 }
 
 void i915_vma_close(struct i915_vma *vma)