diff mbox series

drm/i915/gem: Avoid gem_context->mutex for simple vma lookup

Message ID 20200317121715.6749-1-chris@chris-wilson.co.uk (mailing list archive)
State New, archived
Headers show
Series drm/i915/gem: Avoid gem_context->mutex for simple vma lookup | expand

Commit Message

Chris Wilson March 17, 2020, 12:17 p.m. UTC
As we store the handle lookup inside a radix tree, we do not need the
gem_context->mutex except until we need to insert our lookup into the
common radix tree. This takes a small bit of rearranging to ensure that
the lut we insert into the tree is ready prior to actually inserting it
(as soon as it is exposed via the radixtree, it is visible to any other
submission).

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

Patch

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index d3f4f28e9468..75529d8e0f08 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -481,7 +481,7 @@  eb_add_vma(struct i915_execbuffer *eb,
 
 	GEM_BUG_ON(i915_vma_is_closed(vma));
 
-	ev->vma = i915_vma_get(vma);
+	ev->vma = vma;
 	ev->exec = entry;
 	ev->flags = entry->flags;
 
@@ -731,24 +731,25 @@  static int eb_select_context(struct i915_execbuffer *eb)
 static int eb_lookup_vmas(struct i915_execbuffer *eb)
 {
 	struct radix_tree_root *handles_vma = &eb->gem_context->handles_vma;
+	unsigned int batch = eb_batch_index(eb);
 	struct drm_i915_gem_object *obj;
-	unsigned int i, batch;
+	unsigned int i;
 	int err;
 
-	if (unlikely(i915_gem_context_is_closed(eb->gem_context)))
-		return -ENOENT;
-
 	INIT_LIST_HEAD(&eb->relocs);
 	INIT_LIST_HEAD(&eb->unbound);
 
-	batch = eb_batch_index(eb);
-
 	for (i = 0; i < eb->buffer_count; i++) {
 		u32 handle = eb->exec[i].handle;
 		struct i915_lut_handle *lut;
 		struct i915_vma *vma;
 
+lookup:
+		rcu_read_lock();
 		vma = radix_tree_lookup(handles_vma, handle);
+		if (likely(vma))
+			vma = i915_vma_tryget(vma);
+		rcu_read_unlock();
 		if (likely(vma))
 			goto add_vma;
 
@@ -770,26 +771,38 @@  static int eb_lookup_vmas(struct i915_execbuffer *eb)
 			goto err_obj;
 		}
 
-		err = radix_tree_insert(handles_vma, handle, vma);
-		if (unlikely(err)) {
-			i915_lut_handle_free(lut);
-			goto err_obj;
-		}
-
 		/* transfer ref to lut */
+		i915_gem_object_get(obj);
 		if (!atomic_fetch_inc(&vma->open_count))
 			i915_vma_reopen(vma);
 		lut->handle = handle;
 		lut->ctx = eb->gem_context;
 
+		mutex_lock(&eb->gem_context->mutex);
+		err = -ENOENT;
+		if (unlikely(!i915_gem_context_is_closed(eb->gem_context)))
+			err = radix_tree_insert(handles_vma, handle, vma);
+		mutex_unlock(&eb->gem_context->mutex);
+		if (unlikely(err)) {
+			atomic_dec(&vma->open_count);
+			i915_gem_object_put(obj);
+			i915_lut_handle_free(lut);
+			i915_gem_object_put(obj);
+			if (err == -EEXIST)
+				goto lookup;
+			goto err_vma;
+		}
+
 		i915_gem_object_lock(obj);
 		list_add(&lut->obj_link, &obj->lut_list);
 		i915_gem_object_unlock(obj);
 
 add_vma:
 		err = eb_validate_vma(eb, &eb->exec[i], vma);
-		if (unlikely(err))
+		if (unlikely(err)) {
+			i915_vma_put(vma);
 			goto err_vma;
+		}
 
 		eb_add_vma(eb, i, batch, vma);
 	}
@@ -1494,9 +1507,7 @@  static int eb_relocate(struct i915_execbuffer *eb)
 {
 	int err;
 
-	mutex_lock(&eb->gem_context->mutex);
 	err = eb_lookup_vmas(eb);
-	mutex_unlock(&eb->gem_context->mutex);
 	if (err)
 		return err;