diff options
Diffstat (limited to 'tests/i915/gem_exec_capture.c')
-rw-r--r-- | tests/i915/gem_exec_capture.c | 344 |
1 files changed, 170 insertions, 174 deletions
diff --git a/tests/i915/gem_exec_capture.c b/tests/i915/gem_exec_capture.c index 47ca64dd..c85c198f 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); |