diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2017-02-23 07:44:18 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2017-02-23 14:50:42 +0000 |
commit | 591c0fb85d1c351d28334fb249bf1faaafcf326b (patch) | |
tree | 9a6efa9e1d1726bfe173051706d5daa9c49e5496 /drivers/gpu/drm/i915/selftests/i915_gem_request.c | |
parent | d6a2289d9d6b3ea47514cf29fed56340fb8fec7e (diff) |
drm/i915: Exercise request cancellation using a mock selftest
Add a mock selftest to preempt a request and check that we cancel it,
requeue the request and then complete its execution.
v2: Error leaks no more.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: http://patchwork.freedesktop.org/patch/msgid/20170223074422.4125-13-chris@chris-wilson.co.uk
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Diffstat (limited to 'drivers/gpu/drm/i915/selftests/i915_gem_request.c')
-rw-r--r-- | drivers/gpu/drm/i915/selftests/i915_gem_request.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_request.c b/drivers/gpu/drm/i915/selftests/i915_gem_request.c index 9d056a86723d..42bdeac93324 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_request.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_request.c @@ -26,6 +26,7 @@ #include "../i915_selftest.h" +#include "mock_context.h" #include "mock_gem_device.h" static int igt_add_request(void *arg) @@ -181,12 +182,75 @@ out_locked: return err; } +static int igt_request_rewind(void *arg) +{ + struct drm_i915_private *i915 = arg; + struct drm_i915_gem_request *request, *vip; + struct i915_gem_context *ctx[2]; + int err = -EINVAL; + + mutex_lock(&i915->drm.struct_mutex); + ctx[0] = mock_context(i915, "A"); + request = mock_request(i915->engine[RCS], ctx[0], 2 * HZ); + if (!request) { + err = -ENOMEM; + goto err_context_0; + } + + i915_gem_request_get(request); + i915_add_request(request); + + ctx[1] = mock_context(i915, "B"); + vip = mock_request(i915->engine[RCS], ctx[1], 0); + if (!vip) { + err = -ENOMEM; + goto err_context_1; + } + + /* Simulate preemption by manual reordering */ + if (!mock_cancel_request(request)) { + pr_err("failed to cancel request (already executed)!\n"); + i915_add_request(vip); + goto err_context_1; + } + i915_gem_request_get(vip); + i915_add_request(vip); + request->engine->submit_request(request); + + mutex_unlock(&i915->drm.struct_mutex); + + if (i915_wait_request(vip, 0, HZ) == -ETIME) { + pr_err("timed out waiting for high priority request, vip.seqno=%d, current seqno=%d\n", + vip->global_seqno, intel_engine_get_seqno(i915->engine[RCS])); + goto err; + } + + if (i915_gem_request_completed(request)) { + pr_err("low priority request already completed\n"); + goto err; + } + + err = 0; +err: + i915_gem_request_put(vip); + mutex_lock(&i915->drm.struct_mutex); +err_context_1: + mock_context_close(ctx[1]); + i915_gem_request_put(request); +err_context_0: + mock_context_close(ctx[0]); + mock_device_flush(i915); + mutex_unlock(&i915->drm.struct_mutex); + return err; +} + int i915_gem_request_mock_selftests(void) { static const struct i915_subtest tests[] = { SUBTEST(igt_add_request), SUBTEST(igt_wait_request), SUBTEST(igt_fence_wait), + SUBTEST(igt_request_rewind), }; struct drm_i915_private *i915; int err; |