[Mesa-dev] [PATCH 2/2] intel: aubinator: enable loading dumps from standard input
Lionel Landwerlin
llandwerlin at gmail.com
Tue Oct 4 14:38:53 UTC 2016
In conjuction with an intel_aubdump change, you can now look at your
application's output like this :
$ intel_aubdump -c '/path/to/aubinator --gen=hsw' my_gl_app
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Cc: Sirisha Gandikota <Sirisha.Gandikota at intel.com>
Cc: Kristian Høgsberg <krh at bitplanet.net>
---
src/intel/tools/aubinator.c | 162 +++++++++++++++++++++++++++++++++++---------
1 file changed, 130 insertions(+), 32 deletions(-)
diff --git a/src/intel/tools/aubinator.c b/src/intel/tools/aubinator.c
index 83328b5..73e6012 100644
--- a/src/intel/tools/aubinator.c
+++ b/src/intel/tools/aubinator.c
@@ -834,48 +834,51 @@ handle_trace_block(struct gen_spec *spec, uint32_t *p)
}
struct aub_file {
- char *filename;
- int fd;
- struct stat sb;
+ FILE *stream;
+
uint32_t *map, *end, *cursor;
+ uint32_t *mem_end;
};
static struct aub_file *
aub_file_open(const char *filename)
{
struct aub_file *file;
+ struct stat sb;
+ int fd;
- file = malloc(sizeof *file);
- file->filename = strdup(filename);
- file->fd = open(file->filename, O_RDONLY);
- if (file->fd == -1) {
- fprintf(stderr, "open %s failed: %s", file->filename, strerror(errno));
+ file = calloc(1, sizeof *file);
+ fd = open(filename, O_RDONLY);
+ if (fd == -1) {
+ fprintf(stderr, "open %s failed: %s", filename, strerror(errno));
exit(EXIT_FAILURE);
}
- if (fstat(file->fd, &file->sb) == -1) {
+ if (fstat(fd, &sb) == -1) {
fprintf(stderr, "stat failed: %s", strerror(errno));
exit(EXIT_FAILURE);
}
- file->map = mmap(NULL, file->sb.st_size,
- PROT_READ, MAP_SHARED, file->fd, 0);
+ file->map = mmap(NULL, sb.st_size,
+ PROT_READ, MAP_SHARED, fd, 0);
if (file->map == MAP_FAILED) {
fprintf(stderr, "mmap failed: %s", strerror(errno));
exit(EXIT_FAILURE);
}
file->cursor = file->map;
- file->end = file->map + file->sb.st_size / 4;
+ file->end = file->map + sb.st_size / 4;
- /* mmap a terabyte for our gtt space. */
- gtt_size = 1ul << 40;
- gtt = mmap(NULL, gtt_size, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
- if (gtt == MAP_FAILED) {
- fprintf(stderr, "failed to alloc gtt space: %s", strerror(errno));
- exit(1);
- }
+ return file;
+}
+
+static struct aub_file *
+aub_file_stdin(void)
+{
+ struct aub_file *file;
+
+ file = calloc(1, sizeof *file);
+ file->stream = stdin;
return file;
}
@@ -925,12 +928,21 @@ struct {
{ "bxt", MAKE_GEN(9, 0) }
};
-static void
+enum {
+ AUB_ITEM_DECODE_OK,
+ AUB_ITEM_DECODE_FAILED,
+ AUB_ITEM_DECODE_NEED_MORE_DATA,
+};
+
+static int
aub_file_decode_batch(struct aub_file *file, struct gen_spec *spec)
{
- uint32_t *p, h, device, data_type;
+ uint32_t *p, h, device, data_type, *new_cursor;
int header_length, payload_size, bias;
+ if (file->end - file->cursor < 12)
+ return AUB_ITEM_DECODE_NEED_MORE_DATA;
+
p = file->cursor;
h = *p;
header_length = h & 0xffff;
@@ -946,8 +958,7 @@ aub_file_decode_batch(struct aub_file *file, struct gen_spec *spec)
printf("unknown opcode %d at %ld/%ld\n",
OPCODE(h), file->cursor - file->map,
file->end - file->map);
- file->cursor = file->end;
- return;
+ return AUB_ITEM_DECODE_FAILED;
}
payload_size = 0;
@@ -959,9 +970,22 @@ aub_file_decode_batch(struct aub_file *file, struct gen_spec *spec)
payload_size = p[4];
handle_trace_block(spec, p);
break;
- case MAKE_HEADER(TYPE_AUB, OPCODE_AUB, SUBOPCODE_BMP):
+ default:
break;
+ }
+
+ new_cursor = p + header_length + bias + payload_size / 4;
+ if (new_cursor > file->end)
+ return AUB_ITEM_DECODE_NEED_MORE_DATA;
+ switch (h & 0xffff0000) {
+ case MAKE_HEADER(TYPE_AUB, OPCODE_AUB, SUBOPCODE_HEADER):
+ break;
+ case MAKE_HEADER(TYPE_AUB, OPCODE_AUB, SUBOPCODE_BLOCK):
+ handle_trace_block(spec, p);
+ break;
+ case MAKE_HEADER(TYPE_AUB, OPCODE_AUB, SUBOPCODE_BMP):
+ break;
case MAKE_HEADER(TYPE_AUB, OPCODE_NEW_AUB, SUBOPCODE_VERSION):
printf("version block: dw1 %08x\n", p[1]);
device = (p[1] >> 8) & 0xff;
@@ -987,13 +1011,65 @@ aub_file_decode_batch(struct aub_file *file, struct gen_spec *spec)
"subopcode=0x%x (%08x)\n", TYPE(h), OPCODE(h), SUBOPCODE(h), h);
break;
}
- file->cursor = p + header_length + bias + payload_size / 4;
+ file->cursor = new_cursor;
+
+ return AUB_ITEM_DECODE_OK;
}
static int
aub_file_more_stuff(struct aub_file *file)
{
- return file->cursor < file->end;
+ return file->cursor < file->end || (file->stream && !feof(file->stream));
+}
+
+#define AUB_READ_BUFFER_SIZE (4096)
+#define MAX(a, b) ((a) < (b) ? (b) : (a))
+
+static void
+aub_file_data_grow(struct aub_file *file)
+{
+ size_t old_size = (file->mem_end - file->map) * 4;
+ size_t new_size = MAX(old_size * 2, AUB_READ_BUFFER_SIZE);
+ uint32_t *new_start = malloc(new_size);
+
+ if (file->map) {
+ memcpy(new_start, file->map, old_size);
+ file->cursor = new_start + (file->cursor - file->map);
+ file->end = new_start + (file->end - file->map);
+ free(file->map);
+ } else {
+ file->cursor = new_start;
+ file->end = new_start;
+ }
+
+ file->map = new_start;
+ file->mem_end = file->map + (new_size / 4);
+}
+
+static bool
+aub_file_data_load(struct aub_file *file)
+{
+ size_t r;
+
+ if (file->stream == NULL)
+ return false;
+
+ /* First remove any consumed data */
+ if (file->cursor > file->map) {
+ memmove(file->map, file->cursor,
+ (file->end - file->cursor) * 4);
+ file->end -= file->cursor - file->map;
+ file->cursor = file->map;
+ }
+
+ /* Then load some new data in */
+ if ((file->mem_end - file->end) < (AUB_READ_BUFFER_SIZE / 4))
+ aub_file_data_grow(file);
+
+ r = fread(file->end, 1, (file->mem_end - file->end) * 4, file->stream);
+ file->end += r / 4;
+
+ return r != 0;
}
static void
@@ -1159,14 +1235,36 @@ int main(int argc, char *argv[])
disasm = gen_disasm_create(gen->pci_id);
if (input_file == NULL) {
- print_help(argv[0], stderr);
- exit(EXIT_FAILURE);
+ file = aub_file_stdin();
} else {
- file = aub_file_open(input_file);
+ file = aub_file_open(input_file);
+ }
+
+ /* mmap a terabyte for our gtt space. */
+ gtt_size = 1ul << 30;
+ gtt = mmap(NULL, gtt_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
+ if (gtt == MAP_FAILED) {
+ fprintf(stderr, "failed to alloc gtt space: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ while (aub_file_more_stuff(file)) {
+ switch (aub_file_decode_batch(file, spec)) {
+ case AUB_ITEM_DECODE_OK:
+ break;
+ case AUB_ITEM_DECODE_NEED_MORE_DATA:
+ if (!aub_file_data_load(file)) {
+ fprintf(stderr, "failed to load data from stdin\n");
+ exit(EXIT_FAILURE);
+ }
+ break;
+ default:
+ fprintf(stderr, "failed to parse aubdump data\n");
+ exit(EXIT_FAILURE);
+ }
}
- while (aub_file_more_stuff(file))
- aub_file_decode_batch(file, spec);
fflush(stdout);
/* close the stdout which is opened to write the output */
--
2.9.3
More information about the mesa-dev
mailing list