mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-05 03:59:04 -04:00
drm/i915: Make ring submission compatible with obj->mm.lock removal, v2.
We map the initial context during first pin. This allows us to remove pin_map from state allocation, which saves us a few retry loops. We won't need this until first pin anyway. intel_ring_submission_setup() is also reworked slightly to do all pinning in a single ww loop. Changes since v1: - Handle -EDEADLK backoff in intel_ring_submission_setup() better. - Handle smatch errors reported by Dan and testbot. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Reported-by: kernel test robot <lkp@intel.com> Reported-by: Dan Carpenter <dan.carpenter@oracle.com> Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: https://patchwork.freedesktop.org/patch/msgid/20210323155059.628690-20-maarten.lankhorst@linux.intel.com
This commit is contained in:
committed by
Daniel Vetter
parent
9c01524d4f
commit
83472bb060
@@ -466,6 +466,26 @@ static void ring_context_destroy(struct kref *ref)
|
||||
intel_context_free(ce);
|
||||
}
|
||||
|
||||
static int ring_context_init_default_state(struct intel_context *ce,
|
||||
struct i915_gem_ww_ctx *ww)
|
||||
{
|
||||
struct drm_i915_gem_object *obj = ce->state->obj;
|
||||
void *vaddr;
|
||||
|
||||
vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB);
|
||||
if (IS_ERR(vaddr))
|
||||
return PTR_ERR(vaddr);
|
||||
|
||||
shmem_read(ce->engine->default_state, 0,
|
||||
vaddr, ce->engine->context_size);
|
||||
|
||||
i915_gem_object_flush_map(obj);
|
||||
__i915_gem_object_release_map(obj);
|
||||
|
||||
__set_bit(CONTEXT_VALID_BIT, &ce->flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ring_context_pre_pin(struct intel_context *ce,
|
||||
struct i915_gem_ww_ctx *ww,
|
||||
void **unused)
|
||||
@@ -473,6 +493,13 @@ static int ring_context_pre_pin(struct intel_context *ce,
|
||||
struct i915_address_space *vm;
|
||||
int err = 0;
|
||||
|
||||
if (ce->engine->default_state &&
|
||||
!test_bit(CONTEXT_VALID_BIT, &ce->flags)) {
|
||||
err = ring_context_init_default_state(ce, ww);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
vm = vm_alias(ce->vm);
|
||||
if (vm)
|
||||
err = gen6_ppgtt_pin(i915_vm_to_ppgtt((vm)), ww);
|
||||
@@ -528,22 +555,6 @@ alloc_context_vma(struct intel_engine_cs *engine)
|
||||
if (IS_IVYBRIDGE(i915))
|
||||
i915_gem_object_set_cache_coherency(obj, I915_CACHE_L3_LLC);
|
||||
|
||||
if (engine->default_state) {
|
||||
void *vaddr;
|
||||
|
||||
vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB);
|
||||
if (IS_ERR(vaddr)) {
|
||||
err = PTR_ERR(vaddr);
|
||||
goto err_obj;
|
||||
}
|
||||
|
||||
shmem_read(engine->default_state, 0,
|
||||
vaddr, engine->context_size);
|
||||
|
||||
i915_gem_object_flush_map(obj);
|
||||
__i915_gem_object_release_map(obj);
|
||||
}
|
||||
|
||||
vma = i915_vma_instance(obj, &engine->gt->ggtt->vm, NULL);
|
||||
if (IS_ERR(vma)) {
|
||||
err = PTR_ERR(vma);
|
||||
@@ -575,8 +586,6 @@ static int ring_context_alloc(struct intel_context *ce)
|
||||
return PTR_ERR(vma);
|
||||
|
||||
ce->state = vma;
|
||||
if (engine->default_state)
|
||||
__set_bit(CONTEXT_VALID_BIT, &ce->flags);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1176,37 +1185,15 @@ static int gen7_ctx_switch_bb_setup(struct intel_engine_cs * const engine,
|
||||
return gen7_setup_clear_gpr_bb(engine, vma);
|
||||
}
|
||||
|
||||
static int gen7_ctx_switch_bb_init(struct intel_engine_cs *engine)
|
||||
static int gen7_ctx_switch_bb_init(struct intel_engine_cs *engine,
|
||||
struct i915_gem_ww_ctx *ww,
|
||||
struct i915_vma *vma)
|
||||
{
|
||||
struct drm_i915_gem_object *obj;
|
||||
struct i915_vma *vma;
|
||||
int size;
|
||||
int err;
|
||||
|
||||
size = gen7_ctx_switch_bb_setup(engine, NULL /* probe size */);
|
||||
if (size <= 0)
|
||||
return size;
|
||||
|
||||
size = ALIGN(size, PAGE_SIZE);
|
||||
obj = i915_gem_object_create_internal(engine->i915, size);
|
||||
if (IS_ERR(obj))
|
||||
return PTR_ERR(obj);
|
||||
|
||||
vma = i915_vma_instance(obj, engine->gt->vm, NULL);
|
||||
if (IS_ERR(vma)) {
|
||||
err = PTR_ERR(vma);
|
||||
goto err_obj;
|
||||
}
|
||||
|
||||
vma->private = intel_context_create(engine); /* dummy residuals */
|
||||
if (IS_ERR(vma->private)) {
|
||||
err = PTR_ERR(vma->private);
|
||||
goto err_obj;
|
||||
}
|
||||
|
||||
err = i915_vma_pin(vma, 0, 0, PIN_USER | PIN_HIGH);
|
||||
err = i915_vma_pin_ww(vma, ww, 0, 0, PIN_USER | PIN_HIGH);
|
||||
if (err)
|
||||
goto err_private;
|
||||
return err;
|
||||
|
||||
err = i915_vma_sync(vma);
|
||||
if (err)
|
||||
@@ -1221,17 +1208,53 @@ static int gen7_ctx_switch_bb_init(struct intel_engine_cs *engine)
|
||||
|
||||
err_unpin:
|
||||
i915_vma_unpin(vma);
|
||||
err_private:
|
||||
intel_context_put(vma->private);
|
||||
err_obj:
|
||||
i915_gem_object_put(obj);
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct i915_vma *gen7_ctx_vma(struct intel_engine_cs *engine)
|
||||
{
|
||||
struct drm_i915_gem_object *obj;
|
||||
struct i915_vma *vma;
|
||||
int size, err;
|
||||
|
||||
if (!IS_GEN(engine->i915, 7) || engine->class != RENDER_CLASS)
|
||||
return 0;
|
||||
|
||||
err = gen7_ctx_switch_bb_setup(engine, NULL /* probe size */);
|
||||
if (err < 0)
|
||||
return ERR_PTR(err);
|
||||
if (!err)
|
||||
return NULL;
|
||||
|
||||
size = ALIGN(err, PAGE_SIZE);
|
||||
|
||||
obj = i915_gem_object_create_internal(engine->i915, size);
|
||||
if (IS_ERR(obj))
|
||||
return ERR_CAST(obj);
|
||||
|
||||
vma = i915_vma_instance(obj, engine->gt->vm, NULL);
|
||||
if (IS_ERR(vma)) {
|
||||
i915_gem_object_put(obj);
|
||||
return ERR_CAST(vma);
|
||||
}
|
||||
|
||||
vma->private = intel_context_create(engine); /* dummy residuals */
|
||||
if (IS_ERR(vma->private)) {
|
||||
err = PTR_ERR(vma->private);
|
||||
vma->private = NULL;
|
||||
i915_gem_object_put(obj);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
return vma;
|
||||
}
|
||||
|
||||
int intel_ring_submission_setup(struct intel_engine_cs *engine)
|
||||
{
|
||||
struct i915_gem_ww_ctx ww;
|
||||
struct intel_timeline *timeline;
|
||||
struct intel_ring *ring;
|
||||
struct i915_vma *gen7_wa_vma;
|
||||
int err;
|
||||
|
||||
setup_common(engine);
|
||||
@@ -1262,43 +1285,72 @@ int intel_ring_submission_setup(struct intel_engine_cs *engine)
|
||||
}
|
||||
GEM_BUG_ON(timeline->has_initial_breadcrumb);
|
||||
|
||||
err = intel_timeline_pin(timeline, NULL);
|
||||
if (err)
|
||||
goto err_timeline;
|
||||
|
||||
ring = intel_engine_create_ring(engine, SZ_16K);
|
||||
if (IS_ERR(ring)) {
|
||||
err = PTR_ERR(ring);
|
||||
goto err_timeline_unpin;
|
||||
goto err_timeline;
|
||||
}
|
||||
|
||||
err = intel_ring_pin(ring, NULL);
|
||||
if (err)
|
||||
goto err_ring;
|
||||
|
||||
GEM_BUG_ON(engine->legacy.ring);
|
||||
engine->legacy.ring = ring;
|
||||
engine->legacy.timeline = timeline;
|
||||
|
||||
gen7_wa_vma = gen7_ctx_vma(engine);
|
||||
if (IS_ERR(gen7_wa_vma)) {
|
||||
err = PTR_ERR(gen7_wa_vma);
|
||||
goto err_ring;
|
||||
}
|
||||
|
||||
i915_gem_ww_ctx_init(&ww, false);
|
||||
|
||||
retry:
|
||||
err = i915_gem_object_lock(timeline->hwsp_ggtt->obj, &ww);
|
||||
if (!err && gen7_wa_vma)
|
||||
err = i915_gem_object_lock(gen7_wa_vma->obj, &ww);
|
||||
if (!err && engine->legacy.ring->vma->obj)
|
||||
err = i915_gem_object_lock(engine->legacy.ring->vma->obj, &ww);
|
||||
if (!err)
|
||||
err = intel_timeline_pin(timeline, &ww);
|
||||
if (!err) {
|
||||
err = intel_ring_pin(ring, &ww);
|
||||
if (err)
|
||||
intel_timeline_unpin(timeline);
|
||||
}
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
GEM_BUG_ON(timeline->hwsp_ggtt != engine->status_page.vma);
|
||||
|
||||
if (IS_GEN(engine->i915, 7) && engine->class == RENDER_CLASS) {
|
||||
err = gen7_ctx_switch_bb_init(engine);
|
||||
if (err)
|
||||
goto err_ring_unpin;
|
||||
if (gen7_wa_vma) {
|
||||
err = gen7_ctx_switch_bb_init(engine, &ww, gen7_wa_vma);
|
||||
if (err) {
|
||||
intel_ring_unpin(ring);
|
||||
intel_timeline_unpin(timeline);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (err == -EDEADLK) {
|
||||
err = i915_gem_ww_ctx_backoff(&ww);
|
||||
if (!err)
|
||||
goto retry;
|
||||
}
|
||||
i915_gem_ww_ctx_fini(&ww);
|
||||
if (err)
|
||||
goto err_gen7_put;
|
||||
|
||||
/* Finally, take ownership and responsibility for cleanup! */
|
||||
engine->release = ring_release;
|
||||
|
||||
return 0;
|
||||
|
||||
err_ring_unpin:
|
||||
intel_ring_unpin(ring);
|
||||
err_gen7_put:
|
||||
if (gen7_wa_vma) {
|
||||
intel_context_put(gen7_wa_vma->private);
|
||||
i915_gem_object_put(gen7_wa_vma->obj);
|
||||
}
|
||||
err_ring:
|
||||
intel_ring_put(ring);
|
||||
err_timeline_unpin:
|
||||
intel_timeline_unpin(timeline);
|
||||
err_timeline:
|
||||
intel_timeline_put(timeline);
|
||||
err:
|
||||
|
||||
Reference in New Issue
Block a user