summaryrefslogtreecommitdiff
path: root/tests/i915/gem_exec_capture.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/i915/gem_exec_capture.c')
-rw-r--r--tests/i915/gem_exec_capture.c344
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);