diff options
author | Tony Ye <tony.ye@intel.com> | 2018-11-06 21:13:30 +0800 |
---|---|---|
committer | Tvrtko Ursulin <tvrtko.ursulin@intel.com> | 2018-11-13 13:37:01 +0000 |
commit | 7aa5105be91c0597860eab1196f72ad5d91d9a6f (patch) | |
tree | d7ec4acde67f67b191c3e4088559d8c14143e6f6 | |
parent | 3be421a4f300967299e618e256d7d76d8f70e463 (diff) |
tests/gem_media_vme: Shut down half of subslices to avoid gpu hang on ICLsseu
On Icelake we need to turn off subslices not containing the VME block or
the VME kernel will hang.
v2: (Tvrtko Ursulin)
* Remove libdrm usage for setting context param.
* Cleanup bitmask operation.
* Only apply the workaround for ICL.
v3:
* Added hang detector. (Chris Wilson)
Signed-off-by: Tony Ye <tony.ye@intel.com>
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
-rw-r--r-- | lib/gpu_cmds.c | 12 | ||||
-rw-r--r-- | lib/gpu_cmds.h | 3 | ||||
-rw-r--r-- | lib/media_fill.c | 2 | ||||
-rw-r--r-- | tests/i915/gem_media_vme.c | 67 |
4 files changed, 82 insertions, 2 deletions
diff --git a/lib/gpu_cmds.c b/lib/gpu_cmds.c index b490a63b..8d270ee8 100644 --- a/lib/gpu_cmds.c +++ b/lib/gpu_cmds.c @@ -36,6 +36,18 @@ gen7_render_flush(struct intel_batchbuffer *batch, uint32_t batch_end) igt_assert(ret == 0); } +void +gen7_render_context_flush(struct intel_batchbuffer *batch, uint32_t batch_end) +{ + int ret; + + ret = drm_intel_bo_subdata(batch->bo, 0, 4096, batch->buffer); + if (ret == 0) + ret = drm_intel_gem_bo_context_exec(batch->bo, batch->ctx, + batch_end, 0); + igt_assert(ret == 0); +} + uint32_t gen7_fill_curbe_buffer_data(struct intel_batchbuffer *batch, uint8_t color) diff --git a/lib/gpu_cmds.h b/lib/gpu_cmds.h index ca671fb5..1321af44 100644 --- a/lib/gpu_cmds.h +++ b/lib/gpu_cmds.h @@ -40,6 +40,9 @@ void gen7_render_flush(struct intel_batchbuffer *batch, uint32_t batch_end); +void +gen7_render_context_flush(struct intel_batchbuffer *batch, uint32_t batch_end); + uint32_t gen7_fill_curbe_buffer_data(struct intel_batchbuffer *batch, uint8_t color); diff --git a/lib/media_fill.c b/lib/media_fill.c index ab613b30..d630f278 100644 --- a/lib/media_fill.c +++ b/lib/media_fill.c @@ -345,7 +345,7 @@ __gen11_media_vme_func(struct intel_batchbuffer *batch, batch_end = intel_batchbuffer_align(batch, 8); assert(batch_end < BATCH_STATE_SPLIT); - gen7_render_flush(batch, batch_end); + gen7_render_context_flush(batch, batch_end); intel_batchbuffer_reset(batch); } diff --git a/tests/i915/gem_media_vme.c b/tests/i915/gem_media_vme.c index 1c2f33a4..a8f78646 100644 --- a/tests/i915/gem_media_vme.c +++ b/tests/i915/gem_media_vme.c @@ -81,6 +81,53 @@ static void scratch_buf_init_dst(drm_intel_bufmgr *bufmgr, struct igt_buf *buf) buf->stride = 1; } +static uint64_t switch_off_n_bits(uint64_t mask, unsigned int n) +{ + unsigned int i; + + igt_assert(n > 0 && n <= (sizeof(mask) * 8)); + igt_assert(n <= __builtin_popcount(mask)); + + for (i = 0; n && i < (sizeof(mask) * 8); i++) { + uint64_t bit = 1ULL << i; + + if (bit & mask) { + mask &= ~bit; + n--; + } + } + + return mask; +} + +static void shut_non_vme_subslices(int drm_fd, uint32_t ctx) +{ + struct drm_i915_gem_context_param_sseu sseu = { }; + struct drm_i915_gem_context_param arg = + { + .param = I915_CONTEXT_PARAM_SSEU, + .ctx_id = ctx, + .size = sizeof(sseu), + .value = to_user_pointer(&sseu), + }; + int ret; + + if (__gem_context_get_param(drm_fd, &arg)) + return; /* no sseu support */ + + ret = __gem_context_set_param(drm_fd, &arg); + igt_assert(ret == 0 || ret == -ENODEV || ret == -EINVAL); + if (ret) + return; /* no sseu support */ + + /* shutdown half subslices*/ + sseu.subslice_mask = + switch_off_n_bits(sseu.subslice_mask, + __builtin_popcount(sseu.subslice_mask) / 2); + + gem_context_set_param(drm_fd, &arg); +} + igt_simple_main { int drm_fd; @@ -91,7 +138,7 @@ igt_simple_main struct igt_buf src, dst; uint8_t dst_linear[OUTPUT_SIZE]; - drm_fd = drm_open_driver_render(DRIVER_INTEL); + drm_fd = drm_open_driver(DRIVER_INTEL); igt_require_gem(drm_fd); devid = intel_get_drm_devid(drm_fd); @@ -108,7 +155,25 @@ igt_simple_main scratch_buf_init_src(bufmgr, &src); scratch_buf_init_dst(bufmgr, &dst); + batch->ctx = drm_intel_gem_context_create(bufmgr); + igt_assert(batch->ctx); + + /* ICL hangs if non-VME enabled slices are enabled with a VME kernel. */ + if (intel_gen(devid) == 11) { + uint32_t ctx_id; + int ret; + + ret = drm_intel_gem_context_get_id(batch->ctx, &ctx_id); + igt_assert_eq(ret, 0); + + shut_non_vme_subslices(drm_fd, ctx_id); + } + + igt_fork_hang_detector(drm_fd); + media_vme(batch, &src, WIDTH, HEIGHT, &dst); gem_read(drm_fd, dst.bo->handle, 0, dst_linear, sizeof(dst_linear)); + + igt_stop_hang_detector(); } |