[PATCH i-g-t v2 62/66] tests/xe_eudebug_online: Add caching tests
Piatkowski, Dominik Karol
dominik.karol.piatkowski at intel.com
Thu Aug 1 12:52:16 UTC 2024
> -----Original Message-----
> From: Manszewski, Christoph <christoph.manszewski at intel.com>
> Sent: Tuesday, July 30, 2024 1:45 PM
> To: igt-dev at lists.freedesktop.org
> Cc: Kempczynski, Zbigniew <zbigniew.kempczynski at intel.com>; Kamil
> Konieczny <kamil.konieczny at linux.intel.com>; Grzegorzek, Dominik
> <dominik.grzegorzek at intel.com>; Patelczyk, Maciej
> <maciej.patelczyk at intel.com>; Piatkowski, Dominik Karol
> <dominik.karol.piatkowski at intel.com>; Sikora, Pawel
> <pawel.sikora at intel.com>; Hajda, Andrzej <andrzej.hajda at intel.com>;
> Kolanupaka Naveena <kolanupaka.naveena at intel.com>; Kuoppala, Mika
> <mika.kuoppala at intel.com>; Mun, Gwan-gyeong <gwan-
> gyeong.mun at intel.com>
> Subject: [PATCH i-g-t v2 62/66] tests/xe_eudebug_online: Add caching tests
>
> From: Dominik Karol Piatkowski <dominik.karol.piatkowski at intel.com>
Please change to Piątkowski, as checkpatch will complain (FROM_SIGN_OFF_MISMATCH)
>
> Add caching tests that write incrementing values to 2-page-long target
> surface, poisoning the data one breakpoint before each write instruction and
> restoring it when the poisoned instruction breakpoint is hit. Expect to never
> see poison values in target surface.
>
> Signed-off-by: Dominik Karol Piątkowski
> <dominik.karol.piatkowski at intel.com>
> Cc: Dominik Grzegorzek <dominik.grzegorzek at intel.com>
> ---
> tests/intel/xe_eudebug_online.c | 194
> +++++++++++++++++++++++++++++++-
> 1 file changed, 192 insertions(+), 2 deletions(-)
>
> diff --git a/tests/intel/xe_eudebug_online.c b/tests/intel/xe_eudebug_online.c
> index c3c82b061..96129c06a 100644
> --- a/tests/intel/xe_eudebug_online.c
> +++ b/tests/intel/xe_eudebug_online.c
> @@ -26,6 +26,8 @@
> #define SIP_SINGLE_STEP (1 << 3)
> #define DISABLE_DEBUG_MODE (1 << 4)
> #define SHADER_N_NOOP_BREAKPOINT (1 << 5)
> +#define SHADER_CACHING_SRAM (1 << 6)
> +#define SHADER_CACHING_VRAM (1 << 7)
> #define TRIGGER_RESUME_SINGLE_WALK (1 << 25)
> #define TRIGGER_RESUME_PARALLEL_WALK (1 << 26)
> #define TRIGGER_RECONNECT (1 << 27)
> @@ -42,6 +44,10 @@
> #define STEERING_CONTINUE 0x00c0ffee
> #define STEERING_END_LOOP 0xdeadca11
>
> +#define CACHING_INIT_VALUE 0xcafe0000
> +#define CACHING_POISON_VALUE 0xcafedead
> +#define CACHING_VALUE(n) (CACHING_INIT_VALUE + n)
> +
> #define SHADER_CANARY 0x01010101
>
> #define WALKER_X_DIM 4
> @@ -103,15 +109,31 @@ static struct intel_buf *create_uc_buf(int fd, int
> width, int height) static int get_number_of_threads(uint64_t flags) {
> if (flags & (TRIGGER_RESUME_ONE |
> TRIGGER_RESUME_SINGLE_WALK |
> - TRIGGER_RESUME_PARALLEL_WALK))
> + TRIGGER_RESUME_PARALLEL_WALK |
> SHADER_CACHING_SRAM |
> +SHADER_CACHING_VRAM))
> return 32;
>
> return 512;
> }
>
> +static int caching_get_instruction_count(int fd, uint32_t s_dim__x, int
> +flags) {
> + uint64_t memory;
> +
> + igt_assert((flags & SHADER_CACHING_SRAM) || (flags &
> +SHADER_CACHING_VRAM));
> +
> + if (flags & SHADER_CACHING_SRAM)
> + memory = system_memory(fd);
> + else
> + memory = vram_memory(fd, 0);
> +
> + /* each instruction writes to given y offset */
> + return (2 * xe_min_page_size(fd, memory)) / s_dim__x; }
> +
> static struct gpgpu_shader *get_shader(int fd, const unsigned int flags) {
> struct dim_t w_dim =
> walker_dimensions(get_number_of_threads(flags));
> + struct dim_t s_dim =
> surface_dimensions(get_number_of_threads(flags));
> static struct gpgpu_shader *shader;
>
> shader = gpgpu_shader_create(fd);
> @@ -135,6 +157,13 @@ static struct gpgpu_shader *get_shader(int fd, const
> unsigned int flags)
> gpgpu_shader__nop(shader);
> gpgpu_shader__breakpoint(shader);
> }
> + } else if ((flags & SHADER_CACHING_SRAM) || (flags &
> SHADER_CACHING_VRAM)) {
> + gpgpu_shader__nop(shader);
> + gpgpu_shader__breakpoint(shader);
> + for (int i = 0; i < caching_get_instruction_count(fd, s_dim.x,
> flags); i++)
> + gpgpu_shader__common_target_write_u32(shader,
> s_dim.y + i, CACHING_VALUE(i));
> + gpgpu_shader__nop(shader);
> + gpgpu_shader__breakpoint(shader);
> }
>
> gpgpu_shader__eot(shader);
> @@ -791,6 +820,108 @@ static void create_metadata_trigger(struct
> xe_eudebug_debugger *d, struct drm_xe
> }
> }
>
> +static void overwrite_immediate_value_in_common_target_write(int vm_fd,
> uint64_t offset,
> + uint32_t old_val,
> uint32_t new_val) {
> + uint64_t addr = offset;
> + int vals_changed = 0;
> + uint32_t val;
> +
> + while (vals_changed < 4) {
> + igt_assert_eq(pread(vm_fd, &val, sizeof(uint32_t), addr),
> sizeof(uint32_t));
> + if (val == old_val) {
> + igt_debug("val_before_write[%d]: %08x\n",
> vals_changed, val);
> + igt_assert_eq(pwrite(vm_fd, &new_val,
> sizeof(uint32_t), addr),
> + sizeof(uint32_t));
> + igt_assert_eq(pread(vm_fd, &val, sizeof(uint32_t),
> addr),
> + sizeof(uint32_t));
> + igt_debug("val_before_fsync[%d]: %08x\n",
> vals_changed, val);
> + fsync(vm_fd);
> + igt_assert_eq(pread(vm_fd, &val, sizeof(uint32_t),
> addr),
> + sizeof(uint32_t));
> + igt_debug("val_after_fsync[%d]: %08x\n",
> vals_changed, val);
> + igt_assert_eq_u32(val, new_val);
> + vals_changed++;
> + }
> + addr += sizeof(uint32_t);
> + }
> +}
> +
> +static void eu_attention_resume_caching_trigger(struct
> xe_eudebug_debugger *d,
> + struct
> drm_xe_eudebug_event *e)
> +{
> + struct drm_xe_eudebug_event_eu_attention *att = (void *) e;
> + struct online_debug_data *data = d->ptr;
> + static int counter = 0;
> + static int kernel_in_bb = 0;
> + struct dim_t s_dim = surface_dimensions(get_number_of_threads(d-
> >flags));
> + int val;
> + uint32_t instr_usdw;
> + struct gpgpu_shader *kernel;
> + const uint32_t breakpoint_bit = 1 << 30;
> + struct gpgpu_shader *shader_preamble;
> + struct gpgpu_shader *shader_write_instr;
> +
> + shader_preamble = gpgpu_shader_create(d->master_fd);
> + gpgpu_shader__write_dword(shader_preamble, SHADER_CANARY,
> 0);
> + gpgpu_shader__nop(shader_preamble);
> + gpgpu_shader__breakpoint(shader_preamble);
> +
> + shader_write_instr = gpgpu_shader_create(d->master_fd);
> + gpgpu_shader__common_target_write_u32(shader_write_instr, 0, 0);
> +
> + if (!kernel_in_bb) {
> + kernel = get_shader(d->master_fd, d->flags);
> + kernel_in_bb = find_kernel_in_bb(kernel, data);
> + gpgpu_shader_destroy(kernel);
> + }
> +
> + /* set breakpoint on next write instruction */
> + if (counter < caching_get_instruction_count(d->master_fd, s_dim.x, d-
> >flags)) {
> + igt_assert_eq(pread(data->vm_fd, &instr_usdw,
> sizeof(instr_usdw),
> + data->bb_offset + kernel_in_bb +
> shader_preamble->size * 4 +
> + shader_write_instr->size * 4 * counter),
> sizeof(instr_usdw));
> + instr_usdw |= breakpoint_bit;
> + igt_assert_eq(pwrite(data->vm_fd, &instr_usdw,
> sizeof(instr_usdw),
> + data->bb_offset + kernel_in_bb +
> shader_preamble->size * 4 +
> + shader_write_instr->size * 4 * counter),
> sizeof(instr_usdw));
> + fsync(data->vm_fd);
> + }
> +
> + /* restore current instruction */
> + if (counter && counter <= caching_get_instruction_count(d-
> >master_fd, s_dim.x, d->flags))
> + overwrite_immediate_value_in_common_target_write(data-
> >vm_fd,
> + data-
> >bb_offset + kernel_in_bb +
> +
> shader_preamble->size * 4 +
> +
> shader_write_instr->size * 4 * (counter - 1),
> +
> CACHING_POISON_VALUE,
> +
> CACHING_VALUE(counter - 1));
> +
> + /* poison next instruction */
> + if (counter < caching_get_instruction_count(d->master_fd, s_dim.x, d-
> >flags))
> + overwrite_immediate_value_in_common_target_write(data-
> >vm_fd,
> + data-
> >bb_offset + kernel_in_bb +
> +
> shader_preamble->size * 4 +
> +
> shader_write_instr->size * 4 * counter,
> +
> CACHING_VALUE(counter),
> +
> CACHING_POISON_VALUE);
> +
> + gpgpu_shader_destroy(shader_write_instr);
> + gpgpu_shader_destroy(shader_preamble);
> +
> + for (int i = 0; i < data->target_size; i += sizeof(uint32_t)) {
> + igt_assert_eq(pread(data->vm_fd, &val, sizeof(val), data-
> >target_offset + i),
> + sizeof(val));
> + igt_assert_f(val != CACHING_POISON_VALUE, "Poison value
> found at %04d!\n", i);
> + }
> +
> + eu_ctl_resume(d->master_fd, d->fd, att->client_handle,
> + att->exec_queue_handle, att->lrc_handle,
> + att->bitmask, att->bitmask_size);
> +
> + counter++;
> +}
> +
> static struct intel_bb *xe_bb_create_on_offset(int fd, uint32_t exec_queue,
> uint32_t vm,
> uint64_t offset, uint32_t size) {
> @@ -806,12 +937,20 @@ static struct intel_bb *xe_bb_create_on_offset(int
> fd, uint32_t exec_queue, uint
> return ibb;
> }
>
> +static size_t get_bb_size(int flags)
> +{
> + if ((flags & SHADER_CACHING_SRAM) || (flags &
> SHADER_CACHING_VRAM))
> + return 32768;
> +
> + return 4096;
> +}
> +
> static void run_online_client(struct xe_eudebug_client *c) {
> int threads = get_number_of_threads(c->flags);
> const uint64_t target_offset = 0x1a000000;
> const uint64_t bb_offset = 0x1b000000;
> - const size_t bb_size = 4096;
> + const size_t bb_size = get_bb_size(c->flags);
> struct online_debug_data *data = c->ptr;
> struct drm_xe_engine_class_instance hwe = data->hwe;
> struct drm_xe_ext_set_property ext = { @@ -847,6 +986,9 @@ static
> void run_online_client(struct xe_eudebug_client *c)
> /* Additional memory for steering control */
> if (c->flags & SHADER_LOOP || c->flags & SHADER_SINGLE_STEP)
> s_dim.y++;
> + /* Additional memory for caching check */
> + if ((c->flags & SHADER_CACHING_SRAM) || (c->flags &
> SHADER_CACHING_VRAM))
> + s_dim.y += caching_get_instruction_count(fd, s_dim.x, c-
> >flags);
> buf = create_uc_buf(fd, s_dim.x, s_dim.y);
>
> buf->addr.offset = target_offset;
> @@ -1567,6 +1709,48 @@ static void test_debugger_reopen(int fd, struct
> drm_xe_engine_class_instance *hw
> online_debug_data_destroy(data);
> }
>
> +/**
> + * SUBTEST: writes-caching-%s
> + * Description:
> + * Write incrementing values to 2-page-long target surface, poisoning the
> data one breakpoint
> + * before each write instruction and restoring it when the poisoned
> instruction breakpoint
> + * is hit. Expect to never see poison values in target surface.
> + *
> + *
> + * arg[1]:
> + *
> + * @sram: Use page size of SRAM
> + * @vram: Use page size of VRAM
> + */
> +static void test_caching(int fd, struct drm_xe_engine_class_instance
> +*hwe, int flags) {
> + struct xe_eudebug_session *s;
> + struct online_debug_data *data;
> +
> + if (flags & SHADER_CACHING_VRAM)
> + igt_skip_on_f(!xe_has_vram(fd), "Device does not have
> VRAM.\n");
> +
> + data = online_debug_data_create(hwe);
> + s = xe_eudebug_session_create(fd, run_online_client, flags, data);
> +
> + xe_eudebug_debugger_add_trigger(s->d,
> DRM_XE_EUDEBUG_EVENT_OPEN,
> + open_trigger);
> + xe_eudebug_debugger_add_trigger(s->d,
> DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
> + eu_attention_debug_trigger);
> + xe_eudebug_debugger_add_trigger(s->d,
> DRM_XE_EUDEBUG_EVENT_EU_ATTENTION,
> +
> eu_attention_resume_caching_trigger);
> + xe_eudebug_debugger_add_trigger(s->d,
> DRM_XE_EUDEBUG_EVENT_VM, vm_open_trigger);
> + xe_eudebug_debugger_add_trigger(s->d,
> DRM_XE_EUDEBUG_EVENT_METADATA,
> + create_metadata_trigger);
> + xe_eudebug_debugger_add_trigger(s->d,
> DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE,
> + ufence_ack_trigger);
> +
> + xe_eudebug_session_run(s);
> + online_session_check(s, s->flags);
> + xe_eudebug_session_destroy(s);
> + online_debug_data_destroy(data);
> +}
> +
> static struct drm_xe_engine_class_instance *pick_compute(int fd, int gt) {
> struct drm_xe_engine_class_instance *hwe; @@ -1646,6 +1830,12
> @@ igt_main
> test_gt_render_or_compute("debugger-reopen", fd, hwe)
> test_debugger_reopen(fd, hwe,
> SHADER_N_NOOP_BREAKPOINT);
>
> + test_gt_render_or_compute("writes-caching-sram", fd, hwe)
> + test_caching(fd, hwe, SHADER_CACHING_SRAM);
> +
> + test_gt_render_or_compute("writes-caching-vram", fd, hwe)
> + test_caching(fd, hwe, SHADER_CACHING_VRAM);
> +
> igt_fixture {
> xe_eudebug_enable(fd, was_enabled);
>
> --
> 2.34.1
More information about the igt-dev
mailing list