On Thu, Oct 21, 2021 at 04:40:39PM -0700, john.c.harri...@intel.com wrote:
> From: John Harrison <john.c.harri...@intel.com>
> 
> The decode of the error capture contents was happening in two
> different sub-tests with two very different pieces of code. One being
> much more extensive than the other (actually decodes and verifies the
> contents of the captured buffers rather than just the address). So,
> move the code into a common helper function and use that in both
> places.
> 
> Signed-off-by: John Harrison <john.c.harri...@intel.com>

Reviewed-by: Matthew Brost <matthew.br...@intel.com>

> ---
>  tests/i915/gem_exec_capture.c | 344 +++++++++++++++++-----------------
>  1 file changed, 170 insertions(+), 174 deletions(-)
> 
> diff --git a/tests/i915/gem_exec_capture.c b/tests/i915/gem_exec_capture.c
> index 47ca64dd6..c85c198f7 100644
> --- a/tests/i915/gem_exec_capture.c
> +++ b/tests/i915/gem_exec_capture.c
> @@ -33,32 +33,175 @@
>  
>  IGT_TEST_DESCRIPTION("Check that we capture the user specified objects on a 
> hang");
>  
> -static void check_error_state(int dir, struct drm_i915_gem_exec_object2 *obj)
> +struct offset {
> +     uint64_t addr;
> +     unsigned long idx;
> +     bool found;
> +};
> +
> +static unsigned long zlib_inflate(uint32_t **ptr, unsigned long len)
> +{
> +     struct z_stream_s zstream;
> +     void *out;
> +
> +     memset(&zstream, 0, sizeof(zstream));
> +
> +     zstream.next_in = (unsigned char *)*ptr;
> +     zstream.avail_in = 4*len;
> +
> +     if (inflateInit(&zstream) != Z_OK)
> +             return 0;
> +
> +     out = malloc(128*4096); /* approximate obj size */
> +     zstream.next_out = out;
> +     zstream.avail_out = 128*4096;
> +
> +     do {
> +             switch (inflate(&zstream, Z_SYNC_FLUSH)) {
> +             case Z_STREAM_END:
> +                     goto end;
> +             case Z_OK:
> +                     break;
> +             default:
> +                     inflateEnd(&zstream);
> +                     return 0;
> +             }
> +
> +             if (zstream.avail_out)
> +                     break;
> +
> +             out = realloc(out, 2*zstream.total_out);
> +             if (out == NULL) {
> +                     inflateEnd(&zstream);
> +                     return 0;
> +             }
> +
> +             zstream.next_out = (unsigned char *)out + zstream.total_out;
> +             zstream.avail_out = zstream.total_out;
> +     } while (1);
> +end:
> +     inflateEnd(&zstream);
> +     free(*ptr);
> +     *ptr = out;
> +     return zstream.total_out / 4;
> +}
> +
> +static unsigned long
> +ascii85_decode(char *in, uint32_t **out, bool inflate, char **end)
> +{
> +     unsigned long len = 0, size = 1024;
> +
> +     *out = realloc(*out, sizeof(uint32_t)*size);
> +     if (*out == NULL)
> +             return 0;
> +
> +     while (*in >= '!' && *in <= 'z') {
> +             uint32_t v = 0;
> +
> +             if (len == size) {
> +                     size *= 2;
> +                     *out = realloc(*out, sizeof(uint32_t)*size);
> +                     if (*out == NULL)
> +                             return 0;
> +             }
> +
> +             if (*in == 'z') {
> +                     in++;
> +             } else {
> +                     v += in[0] - 33; v *= 85;
> +                     v += in[1] - 33; v *= 85;
> +                     v += in[2] - 33; v *= 85;
> +                     v += in[3] - 33; v *= 85;
> +                     v += in[4] - 33;
> +                     in += 5;
> +             }
> +             (*out)[len++] = v;
> +     }
> +     *end = in;
> +
> +     if (!inflate)
> +             return len;
> +
> +     return zlib_inflate(out, len);
> +}
> +
> +static int check_error_state(int dir, struct offset *obj_offsets, int 
> obj_count,
> +                          uint64_t obj_size, bool incremental)
>  {
>       char *error, *str;
> -     bool found = false;
> +     int blobs = 0;
>  
>       error = igt_sysfs_get(dir, "error");
>       igt_sysfs_set(dir, "error", "Begone!");
> -
>       igt_assert(error);
>       igt_debug("%s\n", error);
>  
>       /* render ring --- user = 0x00000000 ffffd000 */
> -     for (str = error; (str = strstr(str, "--- user = ")); str++) {
> +     for (str = error; (str = strstr(str, "--- user = ")); ) {
> +             uint32_t *data = NULL;
>               uint64_t addr;
> -             uint32_t hi, lo;
> +             unsigned long i, sz;
> +             unsigned long start;
> +             unsigned long end;
>  
> -             igt_assert(sscanf(str, "--- user = 0x%x %x", &hi, &lo) == 2);
> -             addr = hi;
> +             if (strncmp(str, "--- user = 0x", 13))
> +                     break;
> +             str += 13;
> +             addr = strtoul(str, &str, 16);
>               addr <<= 32;
> -             addr |= lo;
> -             igt_assert_eq_u64(addr, obj->offset);
> -             found = true;
> +             addr |= strtoul(str + 1, &str, 16);
> +             igt_assert(*str++ == '\n');
> +
> +             start = 0;
> +             end = obj_count;
> +             while (end > start) {
> +                     i = (end - start) / 2 + start;
> +                     if (obj_offsets[i].addr < addr)
> +                             start = i + 1;
> +                     else if (obj_offsets[i].addr > addr)
> +                             end = i;
> +                     else
> +                             break;
> +             }
> +             igt_assert(obj_offsets[i].addr == addr);
> +             igt_assert(!obj_offsets[i].found);
> +             obj_offsets[i].found = true;
> +             igt_debug("offset:%"PRIx64", index:%ld\n",
> +                       addr, obj_offsets[i].idx);
> +
> +             /* gtt_page_sizes = 0x00010000 */
> +             if (strncmp(str, "gtt_page_sizes = 0x", 19) == 0) {
> +                     str += 19 + 8;
> +                     igt_assert(*str++ == '\n');
> +             }
> +
> +             if (!(*str == ':' || *str == '~'))
> +                     continue;
> +
> +             igt_debug("blob:%.64s\n", str);
> +             sz = ascii85_decode(str + 1, &data, *str == ':', &str);
> +
> +             igt_assert_eq(4 * sz, obj_size);
> +             igt_assert(*str++ == '\n');
> +             str = strchr(str, '-');
> +
> +             if (incremental) {
> +                     uint32_t expect;
> +
> +                     expect = obj_offsets[i].idx * obj_size;
> +                     for (i = 0; i < sz; i++)
> +                             igt_assert_eq(data[i], expect++);
> +             } else {
> +                     for (i = 0; i < sz; i++)
> +                             igt_assert_eq(data[i], 0);
> +             }
> +
> +             blobs++;
> +             free(data);
>       }
>  
>       free(error);
> -     igt_assert(found);
> +     return blobs;
>  }
>  
>  static void __capture1(int fd, int dir, uint64_t ahnd, const intel_ctx_t 
> *ctx,
> @@ -73,6 +216,7 @@ static void __capture1(int fd, int dir, uint64_t ahnd, 
> const intel_ctx_t *ctx,
>       struct drm_i915_gem_relocation_entry reloc[2];
>       struct drm_i915_gem_execbuffer2 execbuf;
>       uint32_t *batch, *seqno;
> +     struct offset offset;
>       int i;
>  
>       memset(obj, 0, sizeof(obj));
> @@ -168,7 +312,10 @@ static void __capture1(int fd, int dir, uint64_t ahnd, 
> const intel_ctx_t *ctx,
>  
>       /* Check that only the buffer we marked is reported in the error */
>       igt_force_gpu_reset(fd);
> -     check_error_state(dir, &obj[CAPTURE]);
> +     memset(&offset, 0, sizeof(offset));
> +     offset.addr = obj[CAPTURE].offset;
> +     igt_assert_eq(check_error_state(dir, &offset, 1, target_size, false), 
> 1);
> +     igt_assert(offset.found);
>  
>       gem_sync(fd, obj[BATCH].handle);
>  
> @@ -183,11 +330,12 @@ static void capture(int fd, int dir, const intel_ctx_t 
> *ctx, unsigned ring)
>  {
>       uint32_t handle;
>       uint64_t ahnd;
> +     int obj_size = 4096;
>  
> -     handle = gem_create(fd, 4096);
> +     handle = gem_create(fd, obj_size);
>       ahnd = get_reloc_ahnd(fd, ctx->id);
>  
> -     __capture1(fd, dir, ahnd, ctx, ring, handle, 4096);
> +     __capture1(fd, dir, ahnd, ctx, ring, handle, obj_size);
>  
>       gem_close(fd, handle);
>       put_ahnd(ahnd);
> @@ -206,10 +354,8 @@ static int cmp(const void *A, const void *B)
>       return 0;
>  }
>  
> -static struct offset {
> -     uint64_t addr;
> -     unsigned long idx;
> -} *__captureN(int fd, int dir, uint64_t ahnd, unsigned ring,
> +static struct offset *
> +__captureN(int fd, int dir, uint64_t ahnd, unsigned ring,
>             unsigned int size, int count,
>             unsigned int flags)
>  #define INCREMENTAL 0x1
> @@ -357,98 +503,11 @@ static struct offset {
>       return offsets;
>  }
>  
> -static unsigned long zlib_inflate(uint32_t **ptr, unsigned long len)
> -{
> -     struct z_stream_s zstream;
> -     void *out;
> -
> -     memset(&zstream, 0, sizeof(zstream));
> -
> -     zstream.next_in = (unsigned char *)*ptr;
> -     zstream.avail_in = 4*len;
> -
> -     if (inflateInit(&zstream) != Z_OK)
> -             return 0;
> -
> -     out = malloc(128*4096); /* approximate obj size */
> -     zstream.next_out = out;
> -     zstream.avail_out = 128*4096;
> -
> -     do {
> -             switch (inflate(&zstream, Z_SYNC_FLUSH)) {
> -             case Z_STREAM_END:
> -                     goto end;
> -             case Z_OK:
> -                     break;
> -             default:
> -                     inflateEnd(&zstream);
> -                     return 0;
> -             }
> -
> -             if (zstream.avail_out)
> -                     break;
> -
> -             out = realloc(out, 2*zstream.total_out);
> -             if (out == NULL) {
> -                     inflateEnd(&zstream);
> -                     return 0;
> -             }
> -
> -             zstream.next_out = (unsigned char *)out + zstream.total_out;
> -             zstream.avail_out = zstream.total_out;
> -     } while (1);
> -end:
> -     inflateEnd(&zstream);
> -     free(*ptr);
> -     *ptr = out;
> -     return zstream.total_out / 4;
> -}
> -
> -static unsigned long
> -ascii85_decode(char *in, uint32_t **out, bool inflate, char **end)
> -{
> -     unsigned long len = 0, size = 1024;
> -
> -     *out = realloc(*out, sizeof(uint32_t)*size);
> -     if (*out == NULL)
> -             return 0;
> -
> -     while (*in >= '!' && *in <= 'z') {
> -             uint32_t v = 0;
> -
> -             if (len == size) {
> -                     size *= 2;
> -                     *out = realloc(*out, sizeof(uint32_t)*size);
> -                     if (*out == NULL)
> -                             return 0;
> -             }
> -
> -             if (*in == 'z') {
> -                     in++;
> -             } else {
> -                     v += in[0] - 33; v *= 85;
> -                     v += in[1] - 33; v *= 85;
> -                     v += in[2] - 33; v *= 85;
> -                     v += in[3] - 33; v *= 85;
> -                     v += in[4] - 33;
> -                     in += 5;
> -             }
> -             (*out)[len++] = v;
> -     }
> -     *end = in;
> -
> -     if (!inflate)
> -             return len;
> -
> -     return zlib_inflate(out, len);
> -}
> -
>  static void many(int fd, int dir, uint64_t size, unsigned int flags)
>  {
>       uint64_t ram, gtt, ahnd;
>       unsigned long count, blobs;
>       struct offset *offsets;
> -     char *error, *str;
>  
>       gtt = gem_aperture_size(fd) / size;
>       ram = (intel_get_avail_ram_mb() << 20) / size;
> @@ -463,75 +522,10 @@ static void many(int fd, int dir, uint64_t size, 
> unsigned int flags)
>  
>       offsets = __captureN(fd, dir, ahnd, 0, size, count, flags);
>  
> -     error = igt_sysfs_get(dir, "error");
> -     igt_sysfs_set(dir, "error", "Begone!");
> -     igt_assert(error);
> -
> -     blobs = 0;
> -     /* render ring --- user = 0x00000000 ffffd000 */
> -     str = strstr(error, "--- user = ");
> -     while (str) {
> -             uint32_t *data = NULL;
> -             unsigned long i, sz;
> -             uint64_t addr;
> -
> -             if (strncmp(str, "--- user = 0x", 13))
> -                     break;
> -
> -             str += 13;
> -             addr = strtoul(str, &str, 16);
> -             addr <<= 32;
> -             addr |= strtoul(str + 1, &str, 16);
> -             igt_assert(*str++ == '\n');
> -
> -             /* gtt_page_sizes = 0x00010000 */
> -             if (strncmp(str, "gtt_page_sizes = 0x", 19) == 0) {
> -                     str += 19 + 8;
> -                     igt_assert(*str++ == '\n');
> -             }
> -
> -             if (!(*str == ':' || *str == '~'))
> -                     continue;
> -
> -             igt_debug("blob:%.64s\n", str);
> -             sz = ascii85_decode(str + 1, &data, *str == ':', &str);
> -             igt_assert_eq(4 * sz, size);
> -             igt_assert(*str++ == '\n');
> -             str = strchr(str, '-');
> -
> -             if (flags & INCREMENTAL) {
> -                     unsigned long start = 0;
> -                     unsigned long end = count;
> -                     uint32_t expect;
> -
> -                     while (end > start) {
> -                             i = (end - start) / 2 + start;
> -                             if (offsets[i].addr < addr)
> -                                     start = i + 1;
> -                             else if (offsets[i].addr > addr)
> -                                     end = i;
> -                             else
> -                                     break;
> -                     }
> -                     igt_assert(offsets[i].addr == addr);
> -                     igt_debug("offset:%"PRIx64", index:%ld\n",
> -                               addr, offsets[i].idx);
> -
> -                     expect = offsets[i].idx * size;
> -                     for (i = 0; i < sz; i++)
> -                             igt_assert_eq(data[i], expect++);
> -             } else {
> -                     for (i = 0; i < sz; i++)
> -                             igt_assert_eq(data[i], 0);
> -             }
> -
> -             blobs++;
> -             free(data);
> -     }
> +     blobs = check_error_state(dir, offsets, count, size, !!(flags & 
> INCREMENTAL));
>       igt_info("Captured %lu %"PRId64"-blobs out of a total of %lu\n",
>                blobs, size >> 12, count);
>  
> -     free(error);
>       free(offsets);
>       put_ahnd(ahnd);
>  }
> @@ -625,12 +619,14 @@ static void userptr(int fd, int dir)
>       uint32_t handle;
>       uint64_t ahnd;
>       void *ptr;
> +     int obj_size = 4096;
>  
> -     igt_assert(posix_memalign(&ptr, 4096, 4096) == 0);
> -     igt_require(__gem_userptr(fd, ptr, 4096, 0, 0, &handle) == 0);
> +     igt_assert(posix_memalign(&ptr, obj_size, obj_size) == 0);
> +     memset(ptr, 0, obj_size);
> +     igt_require(__gem_userptr(fd, ptr, obj_size, 0, 0, &handle) == 0);
>       ahnd = get_reloc_ahnd(fd, ctx->id);
>  
> -     __capture1(fd, dir, ahnd, intel_ctx_0(fd), 0, handle, 4096);
> +     __capture1(fd, dir, ahnd, intel_ctx_0(fd), 0, handle, obj_size);
>  
>       gem_close(fd, handle);
>       put_ahnd(ahnd);
> -- 
> 2.25.1
> 

Reply via email to