Since we have asynchronous vma bindings, we are ready to utilise asynchronous page allocations. All we have to do is ask for the get_pages not to wait on our behalf, as our workqueue will. Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> --- .../gpu/drm/i915/gem/i915_gem_execbuffer.c | 2 + drivers/gpu/drm/i915/gem/i915_gem_object.h | 1 + drivers/gpu/drm/i915/gem/i915_gem_pages.c | 2 +- drivers/gpu/drm/i915/i915_vma.c | 42 +++++++++---------- drivers/gpu/drm/i915/i915_vma_types.h | 1 + 5 files changed, 25 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index 678e7f82f6c9..59750edd617f 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -699,6 +699,8 @@ static int set_bind_fence(struct i915_vma *vma, struct eb_vm_work *work) lockdep_assert_held(&vma->vm->mutex); prev = i915_active_set_exclusive(&vma->active, &work->base.dma); + if (!prev) + prev = i915_active_fence_get(&vma->obj->mm.active.excl); if (unlikely(prev)) { err = i915_sw_fence_await_dma_fence(&work->base.chain, prev, 0, GFP_NOWAIT | __GFP_NOWARN); diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index 03a1b859aeef..3bb0939dce99 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -275,6 +275,7 @@ void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, struct sg_table *pages, unsigned int sg_page_sizes); +int ____i915_gem_object_get_pages_async(struct drm_i915_gem_object *obj); int ____i915_gem_object_get_pages(struct drm_i915_gem_object *obj); int __i915_gem_object_get_pages(struct drm_i915_gem_object *obj); int __i915_gem_object_get_pages_locked(struct drm_i915_gem_object *obj); diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c index d0cdf1c93a67..4efd1aeedc2d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c @@ -95,7 +95,7 @@ static int __i915_gem_object_wait_for_pages(struct drm_i915_gem_object *obj) return 0; } -static int ____i915_gem_object_get_pages_async(struct drm_i915_gem_object *obj) +int ____i915_gem_object_get_pages_async(struct drm_i915_gem_object *obj) { int err; diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index dc656c7d3191..dc8fdb656e8b 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -123,6 +123,7 @@ vma_create(struct drm_i915_gem_object *obj, vma->display_alignment = I915_GTT_MIN_ALIGNMENT; i915_active_init(&vma->active, __i915_vma_active, __i915_vma_retire); + vma->fence_context = dma_fence_context_alloc(1); /* Declare ourselves safe for use inside shrinkers */ if (IS_ENABLED(CONFIG_LOCKDEP)) { @@ -295,7 +296,6 @@ i915_vma_instance(struct drm_i915_gem_object *obj, struct i915_vma_work { struct dma_fence_work base; struct i915_vma *vma; - struct drm_i915_gem_object *pinned; struct i915_sw_dma_fence_cb cb; enum i915_cache_level cache_level; unsigned int flags; @@ -331,9 +331,6 @@ static int __vma_bind(struct dma_fence_work *work) static void __vma_release(struct dma_fence_work *work) { struct i915_vma_work *vw = container_of(work, typeof(*vw), base); - - if (vw->pinned) - __i915_gem_object_unpin_pages(vw->pinned); } static const struct dma_fence_work_ops bind_ops = { @@ -444,6 +441,8 @@ int i915_vma_bind(struct i915_vma *vma, * execution and not content or object's backing store lifetime. */ prev = i915_active_set_exclusive(&vma->active, &work->base.dma); + if (!prev && vma->obj) + prev = i915_active_fence_get(&vma->obj->mm.active.excl); if (prev) { __i915_sw_fence_await_dma_fence(&work->base.chain, prev, @@ -453,11 +452,6 @@ int i915_vma_bind(struct i915_vma *vma, work->base.dma.error = 0; /* enable the queue_work() */ - if (vma->obj) { - __i915_gem_object_pin_pages(vma->obj); - work->pinned = vma->obj; - } - atomic_or(bind_flags, &vma->flags); return 0; } @@ -826,20 +820,27 @@ int i915_vma_pin(struct i915_vma *vma, u64 size, u64 alignment, u64 flags) if (try_qad_pin(vma, flags & I915_VMA_BIND_MASK)) return 0; - if (vma->obj) { - err = i915_gem_object_pin_pages(vma->obj); - if (err) - return err; - } - err = __wait_for_unbind(vma, flags); if (err) - goto err_pages; + return err; work = i915_vma_work(); - if (!work) { - err = -ENOMEM; - goto err_pages; + if (!work) + return -ENOMEM; + + if (vma->obj) { + if (dma_resv_lock_interruptible(vma->resv, NULL)) + return -EINTR; + + err = ____i915_gem_object_get_pages_async(vma->obj); + if (err == 0) { + err = i915_active_ref(&vma->obj->mm.active, + vma->fence_context, + &work->base.dma); + } + dma_resv_unlock(vma->resv); + if (err) + return err; } if (flags & PIN_GLOBAL) @@ -934,9 +935,6 @@ int i915_vma_pin(struct i915_vma *vma, u64 size, u64 alignment, u64 flags) dma_fence_work_commit_imm(&work->base); if (wakeref) intel_runtime_pm_put(&vma->vm->i915->runtime_pm, wakeref); -err_pages: - if (vma->obj) - i915_gem_object_unpin_pages(vma->obj); return err; } diff --git a/drivers/gpu/drm/i915/i915_vma_types.h b/drivers/gpu/drm/i915/i915_vma_types.h index 02c1640bb034..10757319c2a4 100644 --- a/drivers/gpu/drm/i915/i915_vma_types.h +++ b/drivers/gpu/drm/i915/i915_vma_types.h @@ -250,6 +250,7 @@ struct i915_vma { #define I915_VMA_GGTT_WRITE ((int)BIT(I915_VMA_GGTT_WRITE_BIT)) struct i915_active active; + u64 fence_context; /** * Support different GGTT views into the same object. -- 2.20.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx