From 03d144d16ffef63cedca81ccb4708b173b16868f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 20 Jan 2014 15:57:16 +0000 Subject: [PATCH] kms_flip: Try to consume all fences after a flip As a flip is outstanding, there is an issue that the kernel may not be able to release one of the fences that userspace requires and erroneous report EDEADLK (on gen2, gen3). Signed-off-by: Chris Wilson Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=73696 --- tests/kms_flip.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/tests/kms_flip.c b/tests/kms_flip.c index ee9834f..c397c90 100644 --- a/tests/kms_flip.c +++ b/tests/kms_flip.c @@ -65,6 +65,7 @@ #define TEST_NO_2X_OUTPUT (1 << 20) #define TEST_DPMS_OFF_OTHERS (1 << 21) #define TEST_ENOENT (1 << 22) +#define TEST_FENCE_STRESS (1 << 23) #define EVENT_FLIP (1 << 0) #define EVENT_VBLANK (1 << 1) @@ -199,6 +200,48 @@ static void emit_dummy_load__bcs(struct test_output *o) drm_intel_bo_unreference(target_bo); } +static void emit_fence_stress(struct test_output *o) +{ + const int num_fences = gem_available_fences(drm_fd); + struct kmstest_fb *fb_info = &o->fb_info[o->current_fb_id]; + struct drm_i915_gem_execbuffer2 execbuf; + struct drm_i915_gem_exec_object2 *exec; + uint32_t buf[2] = { MI_BATCH_BUFFER_END, 0 }; + drm_intel_bo **bo; + int i; + + bo = calloc(sizeof(*bo), num_fences); + exec = calloc(sizeof(*exec), num_fences+1); + for (i = 0; i < num_fences - 1; i++) { + uint32_t tiling = I915_TILING_X; + unsigned long pitch = 0; + bo[i] = drm_intel_bo_alloc_tiled(bufmgr, + "tiled bo", 1024, 1024, 4, + &tiling, &pitch, 0); + exec[i].handle = bo[i]->handle; + exec[i].flags = EXEC_OBJECT_NEEDS_FENCE; + } + exec[i].handle = fb_info->gem_handle; + exec[i].flags = EXEC_OBJECT_NEEDS_FENCE; + exec[++i].handle = gem_create(drm_fd, 4096); + gem_write(drm_fd, exec[i].handle, 0, buf, sizeof(buf)); + + memset(&execbuf, 0, sizeof(execbuf)); + execbuf.buffers_ptr = (uintptr_t)exec; + execbuf.buffer_count = i + 1; + execbuf.batch_len = sizeof(buf); + if (HAS_BLT_RING(intel_get_drm_devid(drm_fd))) + execbuf.flags = I915_EXEC_BLT; + + gem_execbuf(drm_fd, &execbuf); + + gem_close(drm_fd, exec[i].handle); + for (i = 0; i < num_fences - 1; i++) + drm_intel_bo_unreference(bo[i]); + free(bo); + free(exec); +} + static void emit_dummy_load__rcs(struct test_output *o) { const struct kmstest_fb *fb_info = &o->fb_info[o->current_fb_id]; @@ -830,6 +873,9 @@ static unsigned int run_test_step(struct test_output *o) if (do_flip) do_or_die(do_page_flip(o, new_fb_id, !(o->flags & TEST_NOEVENT))); + if (o->flags & TEST_FENCE_STRESS) + emit_fence_stress(o); + if (do_vblank) { do_or_die(do_wait_for_vblank(o, o->pipe, target_seq, &vbl_reply)); @@ -1145,6 +1191,7 @@ static void run_test_on_crtc_set(struct test_output *o, int *crtc_idxs, { char test_name[128]; unsigned elapsed; + bool tiled; int i; switch (crtc_count) { @@ -1176,10 +1223,14 @@ static void run_test_on_crtc_set(struct test_output *o, int *crtc_idxs, if (o->flags & TEST_PAN) o->fb_width *= 2; + tiled = false; + if (o->flags & TEST_FENCE_STRESS) + tiled = true; + o->fb_ids[0] = kmstest_create_fb(drm_fd, o->fb_width, o->fb_height, - o->bpp, o->depth, false, &o->fb_info[0]); + o->bpp, o->depth, tiled, &o->fb_info[0]); o->fb_ids[1] = kmstest_create_fb(drm_fd, o->fb_width, o->fb_height, - o->bpp, o->depth, false, &o->fb_info[1]); + o->bpp, o->depth, tiled, &o->fb_info[1]); o->fb_ids[2] = kmstest_create_fb(drm_fd, o->fb_width, o->fb_height, o->bpp, o->depth, true, &o->fb_info[2]); igt_assert(o->fb_ids[0]); @@ -1417,6 +1468,7 @@ int main(int argc, char **argv) "rcs-wf_vblank-vs-modeset" }, { 30, TEST_FLIP | TEST_EBUSY , "plain-flip" }, + { 30, TEST_FLIP | TEST_FENCE_STRESS , "flip-vs-fences" }, { 30, TEST_FLIP | TEST_CHECK_TS | TEST_EBUSY , "plain-flip-ts-check" }, { 30, TEST_FLIP | TEST_CHECK_TS | TEST_EBUSY | TEST_FB_RECREATE, "plain-flip-fb-recreate" }, -- 2.7.4