[Mesa-dev] [PATCH 2/2] intel: aubinator: enable loading dumps from standard input
Ben Widawsky
ben at bwidawsk.net
Tue Oct 4 16:49:13 UTC 2016
On 16-10-04 15:38:53, Lionel Landwerlin wrote:
>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);
Can't you just use realloc()?
>+ } 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 */
Thanks for doing this. It seems like a good idea to me.
More information about the mesa-dev
mailing list