diff options
Diffstat (limited to 'drivers/gpu/drm/i915/selftests')
-rw-r--r-- | drivers/gpu/drm/i915/selftests/huge_gem_object.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/selftests/i915_gem_coherency.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/selftests/i915_gem_context.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/selftests/i915_vma.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/selftests/intel_hangcheck.c | 343 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/selftests/mock_context.c | 36 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/selftests/mock_context.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/selftests/mock_engine.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/selftests/mock_engine.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/selftests/mock_gem_device.c | 30 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/selftests/mock_gtt.c | 3 |
12 files changed, 414 insertions, 46 deletions
diff --git a/drivers/gpu/drm/i915/selftests/huge_gem_object.c b/drivers/gpu/drm/i915/selftests/huge_gem_object.c index caf76af36aba..c5c7e8efbdd3 100644 --- a/drivers/gpu/drm/i915/selftests/huge_gem_object.c +++ b/drivers/gpu/drm/i915/selftests/huge_gem_object.c @@ -111,6 +111,7 @@ huge_gem_object(struct drm_i915_private *i915, dma_addr_t dma_size) { struct drm_i915_gem_object *obj; + unsigned int cache_level; GEM_BUG_ON(!phys_size || phys_size > dma_size); GEM_BUG_ON(!IS_ALIGNED(phys_size, PAGE_SIZE)); @@ -128,9 +129,8 @@ huge_gem_object(struct drm_i915_private *i915, obj->base.read_domains = I915_GEM_DOMAIN_CPU; obj->base.write_domain = I915_GEM_DOMAIN_CPU; - obj->cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE; - obj->cache_coherent = i915_gem_object_is_coherent(obj); - obj->cache_dirty = !obj->cache_coherent; + cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE; + i915_gem_object_set_cache_coherency(obj, cache_level); obj->scratch = phys_size; return obj; diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_coherency.c b/drivers/gpu/drm/i915/selftests/i915_gem_coherency.c index 95d4aebc0181..35d778d70626 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_coherency.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_coherency.c @@ -241,7 +241,7 @@ static bool always_valid(struct drm_i915_private *i915) static bool needs_mi_store_dword(struct drm_i915_private *i915) { - return igt_can_mi_store_dword_imm(i915); + return intel_engine_can_store_dword(i915->engine[RCS]); } static const struct igt_coherency_mode { diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/selftests/i915_gem_context.c index 12b85b3278cd..fb0a58fc8348 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_context.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_context.c @@ -38,8 +38,6 @@ gpu_fill_dw(struct i915_vma *vma, u64 offset, unsigned long count, u32 value) u32 *cmd; int err; - GEM_BUG_ON(!igt_can_mi_store_dword_imm(vma->vm->i915)); - size = (4 * count + 1) * sizeof(u32); size = round_up(size, PAGE_SIZE); obj = i915_gem_object_create_internal(vma->vm->i915, size); @@ -123,6 +121,7 @@ static int gpu_fill(struct drm_i915_gem_object *obj, int err; GEM_BUG_ON(obj->base.size > vm->total); + GEM_BUG_ON(!intel_engine_can_store_dword(engine)); vma = i915_vma_instance(obj, vm, NULL); if (IS_ERR(vma)) @@ -359,6 +358,9 @@ static int igt_ctx_exec(void *arg) } for_each_engine(engine, i915, id) { + if (!intel_engine_can_store_dword(engine)) + continue; + if (!obj) { obj = create_test_object(ctx, file, &objects); if (IS_ERR(obj)) { diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c index 50710e3f1caa..6b132caffa18 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c @@ -197,6 +197,9 @@ static int lowlevel_hole(struct drm_i915_private *i915, { I915_RND_STATE(seed_prng); unsigned int size; + struct i915_vma mock_vma; + + memset(&mock_vma, 0, sizeof(struct i915_vma)); /* Keep creating larger objects until one cannot fit into the hole */ for (size = 12; (hole_end - hole_start) >> size; size++) { @@ -255,8 +258,11 @@ static int lowlevel_hole(struct drm_i915_private *i915, vm->allocate_va_range(vm, addr, BIT_ULL(size))) break; - vm->insert_entries(vm, obj->mm.pages, addr, - I915_CACHE_NONE, 0); + mock_vma.pages = obj->mm.pages; + mock_vma.node.size = BIT_ULL(size); + mock_vma.node.start = addr; + + vm->insert_entries(vm, &mock_vma, I915_CACHE_NONE, 0); } count = n; diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c index fb9072d5877f..2e86ec136b35 100644 --- a/drivers/gpu/drm/i915/selftests/i915_vma.c +++ b/drivers/gpu/drm/i915/selftests/i915_vma.c @@ -186,16 +186,20 @@ static int igt_vma_create(void *arg) goto end; } - list_for_each_entry_safe(ctx, cn, &contexts, link) + list_for_each_entry_safe(ctx, cn, &contexts, link) { + list_del_init(&ctx->link); mock_context_close(ctx); + } } end: /* Final pass to lookup all created contexts */ err = create_vmas(i915, &objects, &contexts); out: - list_for_each_entry_safe(ctx, cn, &contexts, link) + list_for_each_entry_safe(ctx, cn, &contexts, link) { + list_del_init(&ctx->link); mock_context_close(ctx); + } list_for_each_entry_safe(obj, on, &objects, st_link) i915_gem_object_put(obj); diff --git a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c index aa31d6c0cdfb..02e52a146ed8 100644 --- a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c +++ b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c @@ -22,8 +22,13 @@ * */ +#include <linux/kthread.h> + #include "../i915_selftest.h" +#include "mock_context.h" +#include "mock_drm.h" + struct hang { struct drm_i915_private *i915; struct drm_i915_gem_object *hws; @@ -248,9 +253,6 @@ static int igt_hang_sanitycheck(void *arg) /* Basic check that we can execute our hanging batch */ - if (!igt_can_mi_store_dword_imm(i915)) - return 0; - mutex_lock(&i915->drm.struct_mutex); err = hang_init(&h, i915); if (err) @@ -259,6 +261,9 @@ static int igt_hang_sanitycheck(void *arg) for_each_engine(engine, i915, id) { long timeout; + if (!intel_engine_can_store_dword(engine)) + continue; + rq = hang_create_request(&h, engine, i915->kernel_context); if (IS_ERR(rq)) { err = PTR_ERR(rq); @@ -292,6 +297,37 @@ unlock: return err; } +static void global_reset_lock(struct drm_i915_private *i915) +{ + struct intel_engine_cs *engine; + enum intel_engine_id id; + + while (test_and_set_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags)) + wait_event(i915->gpu_error.reset_queue, + !test_bit(I915_RESET_BACKOFF, + &i915->gpu_error.flags)); + + for_each_engine(engine, i915, id) { + while (test_and_set_bit(I915_RESET_ENGINE + id, + &i915->gpu_error.flags)) + wait_on_bit(&i915->gpu_error.flags, + I915_RESET_ENGINE + id, + TASK_UNINTERRUPTIBLE); + } +} + +static void global_reset_unlock(struct drm_i915_private *i915) +{ + struct intel_engine_cs *engine; + enum intel_engine_id id; + + for_each_engine(engine, i915, id) + clear_bit(I915_RESET_ENGINE + id, &i915->gpu_error.flags); + + clear_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags); + wake_up_all(&i915->gpu_error.reset_queue); +} + static int igt_global_reset(void *arg) { struct drm_i915_private *i915 = arg; @@ -300,13 +336,13 @@ static int igt_global_reset(void *arg) /* Check that we can issue a global GPU reset */ - set_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags); + global_reset_lock(i915); set_bit(I915_RESET_HANDOFF, &i915->gpu_error.flags); mutex_lock(&i915->drm.struct_mutex); reset_count = i915_reset_count(&i915->gpu_error); - i915_reset(i915); + i915_reset(i915, I915_RESET_QUIET); if (i915_reset_count(&i915->gpu_error) == reset_count) { pr_err("No GPU reset recorded!\n"); @@ -315,7 +351,214 @@ static int igt_global_reset(void *arg) mutex_unlock(&i915->drm.struct_mutex); GEM_BUG_ON(test_bit(I915_RESET_HANDOFF, &i915->gpu_error.flags)); - clear_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags); + global_reset_unlock(i915); + + if (i915_terminally_wedged(&i915->gpu_error)) + err = -EIO; + + return err; +} + +static int igt_reset_engine(void *arg) +{ + struct drm_i915_private *i915 = arg; + struct intel_engine_cs *engine; + enum intel_engine_id id; + unsigned int reset_count, reset_engine_count; + int err = 0; + + /* Check that we can issue a global GPU and engine reset */ + + if (!intel_has_reset_engine(i915)) + return 0; + + for_each_engine(engine, i915, id) { + set_bit(I915_RESET_ENGINE + engine->id, &i915->gpu_error.flags); + reset_count = i915_reset_count(&i915->gpu_error); + reset_engine_count = i915_reset_engine_count(&i915->gpu_error, + engine); + + err = i915_reset_engine(engine, I915_RESET_QUIET); + if (err) { + pr_err("i915_reset_engine failed\n"); + break; + } + + if (i915_reset_count(&i915->gpu_error) != reset_count) { + pr_err("Full GPU reset recorded! (engine reset expected)\n"); + err = -EINVAL; + break; + } + + if (i915_reset_engine_count(&i915->gpu_error, engine) == + reset_engine_count) { + pr_err("No %s engine reset recorded!\n", engine->name); + err = -EINVAL; + break; + } + + clear_bit(I915_RESET_ENGINE + engine->id, + &i915->gpu_error.flags); + } + + if (i915_terminally_wedged(&i915->gpu_error)) + err = -EIO; + + return err; +} + +static int active_engine(void *data) +{ + struct intel_engine_cs *engine = data; + struct drm_i915_gem_request *rq[2] = {}; + struct i915_gem_context *ctx[2]; + struct drm_file *file; + unsigned long count = 0; + int err = 0; + + file = mock_file(engine->i915); + if (IS_ERR(file)) + return PTR_ERR(file); + + mutex_lock(&engine->i915->drm.struct_mutex); + ctx[0] = live_context(engine->i915, file); + mutex_unlock(&engine->i915->drm.struct_mutex); + if (IS_ERR(ctx[0])) { + err = PTR_ERR(ctx[0]); + goto err_file; + } + + mutex_lock(&engine->i915->drm.struct_mutex); + ctx[1] = live_context(engine->i915, file); + mutex_unlock(&engine->i915->drm.struct_mutex); + if (IS_ERR(ctx[1])) { + err = PTR_ERR(ctx[1]); + i915_gem_context_put(ctx[0]); + goto err_file; + } + + while (!kthread_should_stop()) { + unsigned int idx = count++ & 1; + struct drm_i915_gem_request *old = rq[idx]; + struct drm_i915_gem_request *new; + + mutex_lock(&engine->i915->drm.struct_mutex); + new = i915_gem_request_alloc(engine, ctx[idx]); + if (IS_ERR(new)) { + mutex_unlock(&engine->i915->drm.struct_mutex); + err = PTR_ERR(new); + break; + } + + rq[idx] = i915_gem_request_get(new); + i915_add_request(new); + mutex_unlock(&engine->i915->drm.struct_mutex); + + if (old) { + i915_wait_request(old, 0, MAX_SCHEDULE_TIMEOUT); + i915_gem_request_put(old); + } + } + + for (count = 0; count < ARRAY_SIZE(rq); count++) + i915_gem_request_put(rq[count]); + +err_file: + mock_file_free(engine->i915, file); + return err; +} + +static int igt_reset_active_engines(void *arg) +{ + struct drm_i915_private *i915 = arg; + struct intel_engine_cs *engine, *active; + enum intel_engine_id id, tmp; + int err = 0; + + /* Check that issuing a reset on one engine does not interfere + * with any other engine. + */ + + if (!intel_has_reset_engine(i915)) + return 0; + + for_each_engine(engine, i915, id) { + struct task_struct *threads[I915_NUM_ENGINES]; + unsigned long resets[I915_NUM_ENGINES]; + unsigned long global = i915_reset_count(&i915->gpu_error); + IGT_TIMEOUT(end_time); + + memset(threads, 0, sizeof(threads)); + for_each_engine(active, i915, tmp) { + struct task_struct *tsk; + + if (active == engine) + continue; + + resets[tmp] = i915_reset_engine_count(&i915->gpu_error, + active); + + tsk = kthread_run(active_engine, active, + "igt/%s", active->name); + if (IS_ERR(tsk)) { + err = PTR_ERR(tsk); + goto unwind; + } + + threads[tmp] = tsk; + get_task_struct(tsk); + } + + set_bit(I915_RESET_ENGINE + engine->id, &i915->gpu_error.flags); + do { + err = i915_reset_engine(engine, I915_RESET_QUIET); + if (err) { + pr_err("i915_reset_engine(%s) failed, err=%d\n", + engine->name, err); + break; + } + } while (time_before(jiffies, end_time)); + clear_bit(I915_RESET_ENGINE + engine->id, + &i915->gpu_error.flags); + +unwind: + for_each_engine(active, i915, tmp) { + int ret; + + if (!threads[tmp]) + continue; + + ret = kthread_stop(threads[tmp]); + if (ret) { + pr_err("kthread for active engine %s failed, err=%d\n", + active->name, ret); + if (!err) + err = ret; + } + put_task_struct(threads[tmp]); + + if (resets[tmp] != i915_reset_engine_count(&i915->gpu_error, + active)) { + pr_err("Innocent engine %s was reset (count=%ld)\n", + active->name, + i915_reset_engine_count(&i915->gpu_error, + active) - resets[tmp]); + err = -EIO; + } + } + + if (global != i915_reset_count(&i915->gpu_error)) { + pr_err("Global reset (count=%ld)!\n", + i915_reset_count(&i915->gpu_error) - global); + err = -EIO; + } + + if (err) + break; + + cond_resched(); + } + if (i915_terminally_wedged(&i915->gpu_error)) err = -EIO; @@ -356,9 +599,12 @@ static int igt_wait_reset(void *arg) long timeout; int err; + if (!intel_engine_can_store_dword(i915->engine[RCS])) + return 0; + /* Check that we detect a stuck waiter and issue a reset */ - set_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags); + global_reset_lock(i915); mutex_lock(&i915->drm.struct_mutex); err = hang_init(&h, i915); @@ -403,7 +649,7 @@ fini: hang_fini(&h); unlock: mutex_unlock(&i915->drm.struct_mutex); - clear_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags); + global_reset_unlock(i915); if (i915_terminally_wedged(&i915->gpu_error)) return -EIO; @@ -421,10 +667,8 @@ static int igt_reset_queue(void *arg) /* Check that we replay pending requests following a hang */ - if (!igt_can_mi_store_dword_imm(i915)) - return 0; + global_reset_lock(i915); - set_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags); mutex_lock(&i915->drm.struct_mutex); err = hang_init(&h, i915); if (err) @@ -435,6 +679,9 @@ static int igt_reset_queue(void *arg) IGT_TIMEOUT(end_time); unsigned int count; + if (!intel_engine_can_store_dword(engine)) + continue; + prev = hang_create_request(&h, engine, i915->kernel_context); if (IS_ERR(prev)) { err = PTR_ERR(prev); @@ -471,7 +718,7 @@ static int igt_reset_queue(void *arg) reset_count = fake_hangcheck(prev); - i915_reset(i915); + i915_reset(i915, I915_RESET_QUIET); GEM_BUG_ON(test_bit(I915_RESET_HANDOFF, &i915->gpu_error.flags)); @@ -518,7 +765,7 @@ fini: hang_fini(&h); unlock: mutex_unlock(&i915->drm.struct_mutex); - clear_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags); + global_reset_unlock(i915); if (i915_terminally_wedged(&i915->gpu_error)) return -EIO; @@ -526,13 +773,83 @@ unlock: return err; } +static int igt_handle_error(void *arg) +{ + struct drm_i915_private *i915 = arg; + struct intel_engine_cs *engine = i915->engine[RCS]; + struct hang h; + struct drm_i915_gem_request *rq; + struct i915_gpu_state *error; + int err; + + /* Check that we can issue a global GPU and engine reset */ + + if (!intel_has_reset_engine(i915)) + return 0; + + if (!intel_engine_can_store_dword(i915->engine[RCS])) + return 0; + + mutex_lock(&i915->drm.struct_mutex); + + err = hang_init(&h, i915); + if (err) + goto err_unlock; + + rq = hang_create_request(&h, engine, i915->kernel_context); + if (IS_ERR(rq)) { + err = PTR_ERR(rq); + goto err_fini; + } + + i915_gem_request_get(rq); + __i915_add_request(rq, true); + + if (!wait_for_hang(&h, rq)) { + pr_err("Failed to start request %x\n", rq->fence.seqno); + err = -EIO; + goto err_request; + } + + mutex_unlock(&i915->drm.struct_mutex); + + /* Temporarily disable error capture */ + error = xchg(&i915->gpu_error.first_error, (void *)-1); + + engine->hangcheck.stalled = true; + engine->hangcheck.seqno = intel_engine_get_seqno(engine); + + i915_handle_error(i915, intel_engine_flag(engine), "%s", __func__); + + xchg(&i915->gpu_error.first_error, error); + + mutex_lock(&i915->drm.struct_mutex); + + if (rq->fence.error != -EIO) { + pr_err("Guilty request not identified!\n"); + err = -EINVAL; + goto err_request; + } + +err_request: + i915_gem_request_put(rq); +err_fini: + hang_fini(&h); +err_unlock: + mutex_unlock(&i915->drm.struct_mutex); + return err; +} + int intel_hangcheck_live_selftests(struct drm_i915_private *i915) { static const struct i915_subtest tests[] = { SUBTEST(igt_hang_sanitycheck), SUBTEST(igt_global_reset), + SUBTEST(igt_reset_engine), + SUBTEST(igt_reset_active_engines), SUBTEST(igt_wait_reset), SUBTEST(igt_reset_queue), + SUBTEST(igt_handle_error), }; if (!intel_has_gpu_reset(i915)) diff --git a/drivers/gpu/drm/i915/selftests/mock_context.c b/drivers/gpu/drm/i915/selftests/mock_context.c index f8b9cc212b02..098ce643ad07 100644 --- a/drivers/gpu/drm/i915/selftests/mock_context.c +++ b/drivers/gpu/drm/i915/selftests/mock_context.c @@ -40,18 +40,13 @@ mock_context(struct drm_i915_private *i915, INIT_LIST_HEAD(&ctx->link); ctx->i915 = i915; - ctx->vma_lut.ht_bits = VMA_HT_BITS; - ctx->vma_lut.ht_size = BIT(VMA_HT_BITS); - ctx->vma_lut.ht = kcalloc(ctx->vma_lut.ht_size, - sizeof(*ctx->vma_lut.ht), - GFP_KERNEL); - if (!ctx->vma_lut.ht) - goto err_free; - - ret = ida_simple_get(&i915->context_hw_ida, + INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL); + INIT_LIST_HEAD(&ctx->handles_list); + + ret = ida_simple_get(&i915->contexts.hw_ida, 0, MAX_CONTEXT_HW_ID, GFP_KERNEL); if (ret < 0) - goto err_vma_ht; + goto err_handles; ctx->hw_id = ret; if (name) { @@ -66,9 +61,7 @@ mock_context(struct drm_i915_private *i915, return ctx; -err_vma_ht: - kvfree(ctx->vma_lut.ht); -err_free: +err_handles: kfree(ctx); return NULL; @@ -86,3 +79,20 @@ void mock_context_close(struct i915_gem_context *ctx) i915_gem_context_put(ctx); } + +void mock_init_contexts(struct drm_i915_private *i915) +{ + INIT_LIST_HEAD(&i915->contexts.list); + ida_init(&i915->contexts.hw_ida); + + INIT_WORK(&i915->contexts.free_work, contexts_free_worker); + init_llist_head(&i915->contexts.free_list); +} + +struct i915_gem_context * +live_context(struct drm_i915_private *i915, struct drm_file *file) +{ + lockdep_assert_held(&i915->drm.struct_mutex); + + return i915_gem_create_context(i915, file->driver_priv); +} diff --git a/drivers/gpu/drm/i915/selftests/mock_context.h b/drivers/gpu/drm/i915/selftests/mock_context.h index 2427e5c0916a..2f432c03d413 100644 --- a/drivers/gpu/drm/i915/selftests/mock_context.h +++ b/drivers/gpu/drm/i915/selftests/mock_context.h @@ -25,10 +25,15 @@ #ifndef __MOCK_CONTEXT_H #define __MOCK_CONTEXT_H +void mock_init_contexts(struct drm_i915_private *i915); + struct i915_gem_context * mock_context(struct drm_i915_private *i915, const char *name); void mock_context_close(struct i915_gem_context *ctx); +struct i915_gem_context * +live_context(struct drm_i915_private *i915, struct drm_file *file); + #endif /* !__MOCK_CONTEXT_H */ diff --git a/drivers/gpu/drm/i915/selftests/mock_engine.c b/drivers/gpu/drm/i915/selftests/mock_engine.c index 5b18a2dc19a8..fc0fd7498689 100644 --- a/drivers/gpu/drm/i915/selftests/mock_engine.c +++ b/drivers/gpu/drm/i915/selftests/mock_engine.c @@ -123,10 +123,12 @@ static struct intel_ring *mock_ring(struct intel_engine_cs *engine) } struct intel_engine_cs *mock_engine(struct drm_i915_private *i915, - const char *name) + const char *name, + int id) { struct mock_engine *engine; - static int id; + + GEM_BUG_ON(id >= I915_NUM_ENGINES); engine = kzalloc(sizeof(*engine) + PAGE_SIZE, GFP_KERNEL); if (!engine) @@ -141,7 +143,7 @@ struct intel_engine_cs *mock_engine(struct drm_i915_private *i915, /* minimal engine setup for requests */ engine->base.i915 = i915; snprintf(engine->base.name, sizeof(engine->base.name), "%s", name); - engine->base.id = id++; + engine->base.id = id; engine->base.status_page.page_addr = (void *)(engine + 1); engine->base.context_pin = mock_context_pin; diff --git a/drivers/gpu/drm/i915/selftests/mock_engine.h b/drivers/gpu/drm/i915/selftests/mock_engine.h index e5e240216ba3..133d0c21790d 100644 --- a/drivers/gpu/drm/i915/selftests/mock_engine.h +++ b/drivers/gpu/drm/i915/selftests/mock_engine.h @@ -40,7 +40,8 @@ struct mock_engine { }; struct intel_engine_cs *mock_engine(struct drm_i915_private *i915, - const char *name); + const char *name, + int id); void mock_engine_flush(struct intel_engine_cs *engine); void mock_engine_reset(struct intel_engine_cs *engine); void mock_engine_free(struct intel_engine_cs *engine); diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c index 8cdec455cf7d..678723430d78 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c @@ -22,6 +22,7 @@ * */ +#include <linux/pm_domain.h> #include <linux/pm_runtime.h> #include "mock_engine.h" @@ -53,15 +54,17 @@ static void mock_device_release(struct drm_device *dev) mutex_lock(&i915->drm.struct_mutex); mock_device_flush(i915); + i915_gem_contexts_lost(i915); mutex_unlock(&i915->drm.struct_mutex); cancel_delayed_work_sync(&i915->gt.retire_work); cancel_delayed_work_sync(&i915->gt.idle_work); + i915_gem_drain_workqueue(i915); mutex_lock(&i915->drm.struct_mutex); for_each_engine(engine, i915, id) mock_engine_free(engine); - i915_gem_context_fini(i915); + i915_gem_contexts_fini(i915); mutex_unlock(&i915->drm.struct_mutex); drain_workqueue(i915->wq); @@ -108,6 +111,23 @@ static void mock_idle_work_handler(struct work_struct *work) { } +static int pm_domain_resume(struct device *dev) +{ + return pm_generic_runtime_resume(dev); +} + +static int pm_domain_suspend(struct device *dev) +{ + return pm_generic_runtime_suspend(dev); +} + +static struct dev_pm_domain pm_domain = { + .ops = { + .runtime_suspend = pm_domain_suspend, + .runtime_resume = pm_domain_resume, + }, +}; + struct drm_i915_private *mock_gem_device(void) { struct drm_i915_private *i915; @@ -126,8 +146,10 @@ struct drm_i915_private *mock_gem_device(void) dev_set_name(&pdev->dev, "mock"); dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + dev_pm_domain_set(&pdev->dev, &pm_domain); + pm_runtime_enable(&pdev->dev); pm_runtime_dont_use_autosuspend(&pdev->dev); - pm_runtime_get_sync(&pdev->dev); + WARN_ON(pm_runtime_get_sync(&pdev->dev)); i915 = (struct drm_i915_private *)(pdev + 1); pci_set_drvdata(pdev, i915); @@ -160,7 +182,7 @@ struct drm_i915_private *mock_gem_device(void) INIT_LIST_HEAD(&i915->mm.unbound_list); INIT_LIST_HEAD(&i915->mm.bound_list); - ida_init(&i915->context_hw_ida); + mock_init_contexts(i915); INIT_DELAYED_WORK(&i915->gt.retire_work, mock_retire_work_handler); INIT_DELAYED_WORK(&i915->gt.idle_work, mock_idle_work_handler); @@ -204,7 +226,7 @@ struct drm_i915_private *mock_gem_device(void) mutex_unlock(&i915->drm.struct_mutex); mkwrite_device_info(i915)->ring_mask = BIT(0); - i915->engine[RCS] = mock_engine(i915, "mock"); + i915->engine[RCS] = mock_engine(i915, "mock", RCS); if (!i915->engine[RCS]) goto err_priorities; diff --git a/drivers/gpu/drm/i915/selftests/mock_gtt.c b/drivers/gpu/drm/i915/selftests/mock_gtt.c index a61309c7cb3e..f2118cf535a0 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gtt.c +++ b/drivers/gpu/drm/i915/selftests/mock_gtt.c @@ -33,8 +33,7 @@ static void mock_insert_page(struct i915_address_space *vm, } static void mock_insert_entries(struct i915_address_space *vm, - struct sg_table *st, - u64 start, + struct i915_vma *vma, enum i915_cache_level level, u32 flags) { } |