[PATCH 55/55] lut
Chris Wilson
chris at chris-wilson.co.uk
Sat Jun 30 15:38:08 UTC 2018
---
drivers/gpu/drm/i915/gvt/scheduler.c | 6 +-
drivers/gpu/drm/i915/i915_drv.h | 1 +
drivers/gpu/drm/i915/i915_gem.c | 14 ++--
drivers/gpu/drm/i915/i915_gem_context.c | 9 +++
drivers/gpu/drm/i915/i915_gem_context.h | 2 +
drivers/gpu/drm/i915/i915_gem_execbuffer.c | 11 ++-
drivers/gpu/drm/i915/i915_gem_object.h | 1 +
drivers/gpu/drm/i915/i915_gem_render_state.c | 2 +-
drivers/gpu/drm/i915/i915_vma.c | 73 +++++++++++++------
drivers/gpu/drm/i915/i915_vma.h | 14 +++-
drivers/gpu/drm/i915/intel_engine_cs.c | 10 +--
drivers/gpu/drm/i915/intel_ringbuffer.c | 6 +-
drivers/gpu/drm/i915/selftests/huge_pages.c | 28 ++++---
.../gpu/drm/i915/selftests/i915_gem_context.c | 5 +-
.../gpu/drm/i915/selftests/mock_gem_device.c | 1 +
15 files changed, 118 insertions(+), 65 deletions(-)
diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c
index a4756a9b82cd..4bc2789f8c7b 100644
--- a/drivers/gpu/drm/i915/gvt/scheduler.c
+++ b/drivers/gpu/drm/i915/gvt/scheduler.c
@@ -557,8 +557,10 @@ static void release_shadow_batch_buffer(struct intel_vgpu_workload *workload)
i915_gem_object_unpin_map(bb->obj);
if (bb->vma && !IS_ERR(bb->vma)) {
- i915_vma_unpin(bb->vma);
- i915_vma_close(bb->vma);
+ mutex_lock(&bb->vma->vm->mutex);
+ __i915_vma_unpin(bb->vma);
+ __i915_vma_close(bb->vma);
+ mutex_unlock(&bb->vma->vm->mutex);
}
i915_gem_object_put(bb->obj);
}
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index c3408efa7d07..77ac188443ca 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2074,6 +2074,7 @@ struct drm_i915_private {
struct list_head timelines;
+ spinlock_t closed_lock;
struct list_head active_rings;
struct list_head closed_vma;
u32 active_requests;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index cf4d340b8819..8ca292e296b9 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3174,8 +3174,7 @@ void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file)
struct drm_i915_file_private *fpriv = file->driver_priv;
struct i915_lut_handle *lut, *ln;
- mutex_lock(&i915->drm.struct_mutex);
-
+ i915_gem_object_lock(obj);
list_for_each_entry_safe(lut, ln, &obj->lut_list, obj_link) {
struct i915_gem_context *ctx = lut->ctx;
struct i915_vma *vma;
@@ -3187,12 +3186,15 @@ void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file)
vma = radix_tree_delete(&ctx->handles_vma, lut->handle);
GEM_BUG_ON(vma->obj != obj);
- /* We allow the process to have multiple handles to the same
+ /*
+ * We allow the process to have multiple handles to the same
* vma, in the same fd namespace, by virtue of flink/open.
*/
+ mutex_lock(&vma->vm->mutex);
GEM_BUG_ON(!vma->open_count);
if (!--vma->open_count && !i915_vma_is_ggtt(vma))
- i915_vma_close(vma);
+ __i915_vma_close(vma);
+ mutex_unlock(&vma->vm->mutex);
list_del(&lut->obj_link);
list_del(&lut->ctx_link);
@@ -3200,8 +3202,7 @@ void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file)
kmem_cache_free(i915->luts, lut);
i915_gem_object_put(obj);
}
-
- mutex_unlock(&i915->drm.struct_mutex);
+ i915_gem_object_unlock(obj);
}
static unsigned long to_wait_timeout(s64 timeout_ns)
@@ -5228,6 +5229,7 @@ int i915_gem_init_early(struct drm_i915_private *dev_priv)
if (!dev_priv->priorities)
goto err_dependencies;
+ spin_lock_init(&dev_priv->gt.closed_lock);
INIT_LIST_HEAD(&dev_priv->gt.timelines);
INIT_LIST_HEAD(&dev_priv->gt.active_rings);
INIT_LIST_HEAD(&dev_priv->gt.closed_vma);
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index e3723e9e17aa..da79f54b35a8 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -103,7 +103,9 @@ static void lut_close(struct i915_gem_context *ctx)
void __rcu **slot;
list_for_each_entry_safe(lut, ln, &ctx->handles_list, ctx_link) {
+ i915_gem_object_lock(lut->obj);
list_del(&lut->obj_link);
+ i915_gem_object_unlock(lut->obj);
kmem_cache_free(ctx->i915->luts, lut);
}
@@ -112,9 +114,15 @@ static void lut_close(struct i915_gem_context *ctx)
struct i915_vma *vma = rcu_dereference_raw(*slot);
radix_tree_iter_delete(&ctx->handles_vma, &iter, slot);
+ rcu_read_unlock();
+ i915_gem_object_lock(vma->obj);
vma->open_count--;
+ i915_gem_object_unlock(vma->obj);
+
i915_gem_object_put(vma->obj);
+
+ rcu_read_lock();
}
rcu_read_unlock();
}
@@ -294,6 +302,7 @@ __create_hw_context(struct drm_i915_private *dev_priv,
return ERR_PTR(ret);
}
+ mutex_init(&ctx->mutex);
kref_init(&ctx->ref);
list_add_tail(&ctx->link, &dev_priv->contexts.list);
ctx->i915 = dev_priv;
diff --git a/drivers/gpu/drm/i915/i915_gem_context.h b/drivers/gpu/drm/i915/i915_gem_context.h
index 95c0abfc6d9c..1bcb2b8151b6 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.h
+++ b/drivers/gpu/drm/i915/i915_gem_context.h
@@ -61,6 +61,8 @@ struct intel_context_ops {
* logical hardware state for a particular client.
*/
struct i915_gem_context {
+ struct mutex mutex;
+
/** i915: i915 device backpointer */
struct drm_i915_private *i915;
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 37e1af2ebe7d..fdf7d41b9b3d 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -762,6 +762,7 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb)
batch = eb_batch_index(eb);
+ mutex_lock(&eb->ctx->mutex);
mutex_lock(&eb->vm->mutex);
for (i = 0; i < eb->buffer_count; i++) {
u32 handle = eb->exec[i].handle;
@@ -798,16 +799,18 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb)
goto err_obj;
}
- mutex_lock(&eb->vm->mutex);
-
- /* transfer ref to ctx */
+ /* transfer ref to obj/ctx */
+ i915_gem_object_lock(obj);
if (!vma->open_count++)
i915_vma_reopen(vma);
list_add(&lut->obj_link, &obj->lut_list);
list_add(&lut->ctx_link, &eb->ctx->handles_list);
+ lut->obj = obj;
lut->ctx = eb->ctx;
lut->handle = handle;
+ i915_gem_object_unlock(obj);
+ mutex_lock(&eb->vm->mutex);
add_vma:
err = eb_add_vma(eb, i, batch, vma);
if (unlikely(err)) {
@@ -824,12 +827,14 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb)
eb->args->flags |= __EXEC_VALIDATED;
err = eb_reserve(eb);
mutex_unlock(&eb->vm->mutex);
+ mutex_unlock(&eb->ctx->mutex);
return err;
err_obj:
i915_gem_object_put(obj);
err_vma:
eb->vma[i] = NULL;
+ mutex_unlock(&eb->ctx->mutex);
return err;
}
diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
index 5d153e0f1601..198d7f465ac5 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/i915_gem_object.h
@@ -47,6 +47,7 @@ struct drm_i915_gem_object;
struct i915_lut_handle {
struct list_head obj_link;
struct list_head ctx_link;
+ struct drm_i915_gem_object *obj;
struct i915_gem_context *ctx;
u32 handle;
};
diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c
index fcc221b260d2..a64038d87aeb 100644
--- a/drivers/gpu/drm/i915/i915_gem_render_state.c
+++ b/drivers/gpu/drm/i915/i915_gem_render_state.c
@@ -236,7 +236,7 @@ int i915_gem_render_state_emit(struct i915_request *rq)
mutex_lock(&ggtt->vm.mutex);
__i915_vma_unpin(so.vma);
err_vma_locked:
- i915_vma_close(so.vma);
+ __i915_vma_close(so.vma);
mutex_unlock(&ggtt->vm.mutex);
err_obj:
i915_gem_object_put(so.obj);
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index de64041b9ac3..63484f46aa97 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -433,8 +433,11 @@ void i915_vma_unpin_and_release(struct i915_vma **p_vma)
if (!vma)
return;
- i915_vma_unpin(vma);
- i915_vma_close(vma);
+ mutex_lock(&vma->vm->mutex);
+ __i915_vma_unpin(vma);
+ __i915_vma_close(vma);
+ mutex_unlock(&vma->vm->mutex);
+
i915_vma_put(vma);
}
@@ -805,9 +808,12 @@ int __i915_vma_do_pin(struct i915_vma *vma,
return ret;
}
-void i915_vma_close(struct i915_vma *vma)
+void __i915_vma_close(struct i915_vma *vma)
{
- lockdep_assert_held(&vma->vm->i915->drm.struct_mutex);
+ struct drm_i915_private *i915 = vma->vm->i915;
+
+ lockdep_assert_held(&vma->vm->mutex);
+ GEM_BUG_ON(i915_vma_is_pinned(vma));
GEM_BUG_ON(i915_vma_is_closed(vma));
vma->flags |= I915_VMA_CLOSED;
@@ -824,16 +830,24 @@ void i915_vma_close(struct i915_vma *vma)
* causing us to rebind the VMA once more. This ends up being a lot
* of wasted work for the steady state.
*/
- list_add_tail(&vma->closed_link, &vma->vm->i915->gt.closed_vma);
+
+ spin_lock(&i915->gt.closed_lock);
+ list_add_tail(&vma->closed_link, &i915->gt.closed_vma);
+ spin_unlock(&i915->gt.closed_lock);
}
void i915_vma_reopen(struct i915_vma *vma)
{
- lockdep_assert_held(&vma->vm->i915->drm.struct_mutex);
+ i915_vma_assert_held(vma);
if (vma->flags & I915_VMA_CLOSED) {
+ struct drm_i915_private *i915 = vma->vm->i915;
+
vma->flags &= ~I915_VMA_CLOSED;
+
+ spin_lock(&i915->gt.closed_lock);
list_del(&vma->closed_link);
+ spin_unlock(&i915->gt.closed_lock);
}
}
@@ -842,7 +856,15 @@ static void __i915_vma_destroy(struct i915_vma *vma)
struct drm_i915_private *i915 = vma->vm->i915;
struct i915_vma_active *iter, *n;
- GEM_BUG_ON(vma->node.allocated);
+ GEM_BUG_ON(i915_vma_is_pinned(vma));
+
+ if (drm_mm_node_allocated(&vma->node)) {
+ mutex_lock(&vma->vm->mutex);
+ i915_vma_unbind(vma);
+ mutex_unlock(&vma->vm->mutex);
+ }
+
+ GEM_BUG_ON(drm_mm_node_allocated(&vma->node));
GEM_BUG_ON(vma->fence);
GEM_BUG_ON(i915_gem_active_isset(&vma->last_fence));
@@ -869,33 +891,42 @@ static void __i915_vma_destroy(struct i915_vma *vma)
void i915_vma_destroy(struct i915_vma *vma)
{
- struct i915_address_space *vm = vma->vm;
-
- lockdep_assert_held(&vma->vm->i915->drm.struct_mutex);
-
GEM_BUG_ON(i915_vma_is_active(vma));
GEM_BUG_ON(i915_vma_is_pinned(vma));
- if (i915_vma_is_closed(vma))
- list_del(&vma->closed_link);
+ if (i915_vma_is_closed(vma)) {
+ struct drm_i915_private *i915 = vma->vm->i915;
- mutex_lock(&vm->mutex);
- WARN_ON(i915_vma_unbind(vma));
- mutex_unlock(&vm->mutex);
+ spin_lock(&i915->gt.closed_lock);
+ list_del(&vma->closed_link);
+ spin_unlock(&i915->gt.closed_lock);
+ }
__i915_vma_destroy(vma);
}
void i915_vma_parked(struct drm_i915_private *i915)
{
- struct i915_vma *vma, *next;
+ if (list_empty(&i915->gt.closed_vma))
+ return;
+
+ spin_lock(&i915->gt.closed_lock);
+ while (!list_empty(&i915->gt.closed_vma)) {
+ struct i915_vma *vma;
+
+ vma = list_first_entry(&i915->gt.closed_vma,
+ typeof(*vma), closed_link);
- list_for_each_entry_safe(vma, next, &i915->gt.closed_vma, closed_link) {
GEM_BUG_ON(!i915_vma_is_closed(vma));
- i915_vma_destroy(vma);
- }
+ vma->flags &= ~I915_VMA_CLOSED;
+ list_del(&vma->closed_link);
+ spin_unlock(&i915->gt.closed_lock);
- GEM_BUG_ON(!list_empty(&i915->gt.closed_vma));
+ __i915_vma_destroy(vma);
+
+ spin_lock(&i915->gt.closed_lock);
+ }
+ spin_unlock(&i915->gt.closed_lock);
}
static void __i915_vma_iounmap(struct i915_vma *vma)
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index aef9877652d9..c6d4ae404eaa 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -283,10 +283,8 @@ bool i915_vma_misplaced(const struct i915_vma *vma,
u64 size, u64 alignment, u64 flags);
void __i915_vma_set_map_and_fenceable(struct i915_vma *vma);
void i915_vma_revoke_mmap(struct i915_vma *vma);
-int __must_check i915_vma_unbind(struct i915_vma *vma);
+int i915_vma_unbind(struct i915_vma *vma);
void i915_vma_unlink_ctx(struct i915_vma *vma);
-void i915_vma_close(struct i915_vma *vma);
-void i915_vma_reopen(struct i915_vma *vma);
void i915_vma_destroy(struct i915_vma *vma);
static inline void ____i915_vma_pin(struct i915_vma *vma)
@@ -359,6 +357,16 @@ static inline void i915_vma_unpin(struct i915_vma *vma)
mutex_unlock(&vma->vm->mutex);
}
+void __i915_vma_close(struct i915_vma *vma);
+static inline void i915_vma_close(struct i915_vma *vma)
+{
+ mutex_lock(&vma->vm->mutex);
+ __i915_vma_close(vma);
+ mutex_unlock(&vma->vm->mutex);
+}
+
+void i915_vma_reopen(struct i915_vma *vma);
+
static inline bool i915_vma_is_bound(const struct i915_vma *vma,
unsigned int where)
{
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
index 4ae04144c30a..881014c518d1 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -543,19 +543,13 @@ static void cleanup_phys_status_page(struct intel_engine_cs *engine)
static void cleanup_status_page(struct intel_engine_cs *engine)
{
struct i915_vma *vma;
- struct drm_i915_gem_object *obj;
vma = fetch_and_zero(&engine->status_page.vma);
if (!vma)
return;
- obj = vma->obj;
-
- i915_vma_unpin(vma);
- i915_vma_close(vma);
-
- i915_gem_object_unpin_map(obj);
- i915_gem_object_put(obj);
+ i915_gem_object_unpin_map(vma->obj);
+ i915_vma_unpin_and_release(&vma);
}
static int init_status_page(struct intel_engine_cs *engine)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index fa947f374e6f..41f47a57944d 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1194,8 +1194,10 @@ intel_engine_create_ring(struct intel_engine_cs *engine,
void
intel_ring_free(struct intel_ring *ring)
{
- i915_vma_close(ring->vma);
- i915_vma_put(ring->vma);
+ struct drm_i915_gem_object *obj = ring->vma->obj;
+
+ i915_vma_destroy(ring->vma);
+ i915_gem_object_put(obj);
i915_timeline_put(ring->timeline);
kfree(ring);
diff --git a/drivers/gpu/drm/i915/selftests/huge_pages.c b/drivers/gpu/drm/i915/selftests/huge_pages.c
index 5acce448a150..b1357aba02cb 100644
--- a/drivers/gpu/drm/i915/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/selftests/huge_pages.c
@@ -433,8 +433,10 @@ static int igt_mock_exhaust_device_supported_pages(void *arg)
err = -EINVAL;
}
- i915_vma_unpin(vma);
- i915_vma_close(vma);
+ mutex_lock(&vma->vm->mutex);
+ __i915_vma_unpin(vma);
+ __i915_vma_close(vma);
+ mutex_unlock(&vma->vm->mutex);
i915_gem_object_put(obj);
@@ -512,7 +514,6 @@ static int igt_mock_ppgtt_misaligned_dma(void *arg)
goto out_unpin;
}
-
err = igt_check_page_sizes(vma);
if (vma->page_sizes.gtt != page_size) {
@@ -862,8 +863,10 @@ static int igt_mock_ppgtt_64K(void *arg)
goto out_vma_unpin;
}
- i915_vma_unpin(vma);
- i915_vma_close(vma);
+ mutex_lock(&vma->vm->mutex);
+ __i915_vma_unpin(vma);
+ __i915_vma_close(vma);
+ mutex_lock(&vma->vm->mutex);
i915_gem_object_unpin_pages(obj);
i915_gem_object_put(obj);
@@ -989,17 +992,13 @@ static int gpu_write(struct i915_vma *vma,
err = i915_vma_move_to_active(batch, rq, 0);
i915_vma_unlock(batch);
if (err)
- goto err_request;
-
- i915_vma_unpin(batch);
- i915_vma_close(batch);
- i915_vma_put(batch);
+ goto err_unpin;
err = engine->emit_bb_start(rq,
batch->node.start, batch->node.size,
flags);
if (err)
- goto err_request;
+ goto err_unpin;
i915_vma_lock(vma);
err = i915_vma_move_to_active(vma, rq, EXEC_OBJECT_WRITE);
@@ -1007,6 +1006,8 @@ static int gpu_write(struct i915_vma *vma,
if (err)
i915_request_skip(rq, err);
+err_unpin:
+ i915_vma_unpin_and_release(&batch);
err_request:
i915_request_add(rq);
@@ -1490,10 +1491,7 @@ static int igt_ppgtt_pin_update(void *arg)
if (err)
goto out_unpin;
- i915_vma_unpin(vma);
- i915_vma_close(vma);
-
- i915_gem_object_put(obj);
+ i915_vma_unpin_and_release(&vma);
}
obj = i915_gem_object_create_internal(dev_priv, PAGE_SIZE);
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/selftests/i915_gem_context.c
index 3ae29cb2050c..6331a1f02914 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_context.c
@@ -183,10 +183,7 @@ static int gpu_fill(struct drm_i915_gem_object *obj,
if (err)
goto skip_request;
- i915_vma_unpin(batch);
- i915_vma_close(batch);
- i915_vma_put(batch);
-
+ i915_vma_unpin_and_release(&batch);
i915_vma_unpin(vma);
i915_request_add(rq);
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index c97075c5ccaf..0cd0ba90a5a3 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -222,6 +222,7 @@ struct drm_i915_private *mock_gem_device(void)
if (!i915->priorities)
goto err_dependencies;
+ spin_lock_init(&i915->gt.closed_lock);
INIT_LIST_HEAD(&i915->gt.timelines);
INIT_LIST_HEAD(&i915->gt.active_rings);
INIT_LIST_HEAD(&i915->gt.closed_vma);
--
2.18.0
More information about the Intel-gfx-trybot
mailing list