From: Chris Wilson Date: Sat, 17 Aug 2013 19:04:11 +0000 (+0100) Subject: overlay: Track requests per-process X-Git-Tag: intel-gpu-tools-1.4~190 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cbbd55af154f88fdd2c58c0398408f242124b005;p=profile%2Fextras%2Fintel-gpu-tools.git overlay: Track requests per-process Signed-off-by: Chris Wilson --- diff --git a/overlay/gpu-perf.c b/overlay/gpu-perf.c index 59176f9..8717437 100644 --- a/overlay/gpu-perf.c +++ b/overlay/gpu-perf.c @@ -30,6 +30,8 @@ struct sample_event { uint64_t time; uint64_t id; uint32_t raw_size; + uint32_t raw_hdr0; + uint32_t raw_hdr1; uint32_t raw[0]; }; @@ -117,7 +119,6 @@ static int perf_tracepoint_open(struct gpu_perf *gp, if (gp->nr_events) ioctl(fd[n], PERF_EVENT_IOC_SET_OUTPUT, gp->fd[n]); - } gp->nr_events++; @@ -149,8 +150,53 @@ err: return EINVAL; } +static char *get_comm(pid_t pid, char *comm, int len) +{ + char filename[1024]; + int fd; + + *comm = '\0'; + snprintf(filename, sizeof(filename), "/proc/%d/comm", pid); + + fd = open(filename, 0); + if (fd >= 0) { + len = read(fd, comm, len-1); + if (len >= 0) + comm[len-1] = '\0'; + close(fd); + } + + return comm; +} + +static int request_add(struct gpu_perf *gp, const void *event) +{ + const struct sample_event *sample = event; + struct gpu_perf_comm *comm; + + for (comm = gp->comm; comm != NULL; comm = comm->next) { + if (comm->pid == sample->pid) + break; + } + if (comm == NULL) { + comm = malloc(sizeof(*comm)); + if (comm == NULL) + return 0; + + comm->next = gp->comm; + gp->comm = comm; + get_comm(sample->pid, comm->name, sizeof(comm->name)); + comm->pid = sample->pid; + memset(comm->nr_requests, 0, sizeof(comm->nr_requests)); + } + + comm->nr_requests[sample->raw[1]]++; + return 1; +} + static int seqno_start(struct gpu_perf *gp, const void *event) { + printf ("seqno_start\n"); return 0; } @@ -171,9 +217,9 @@ void gpu_perf_init(struct gpu_perf *gp, unsigned flags) gp->nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); gp->page_size = getpagesize(); + perf_tracepoint_open(gp, "i915", "i915_gem_request_add", request_add); if (perf_tracepoint_open(gp, "i915", "i915_gem_ring_complete", seqno_end) == 0) perf_tracepoint_open(gp, "i915", "i915_gem_ring_dispatch", seqno_start); - perf_tracepoint_open(gp, "i915", "i915_flip_complete", flip_complete); if (gp->nr_events == 0) @@ -218,13 +264,18 @@ int gpu_perf_update(struct gpu_perf *gp) struct perf_event_mmap_page *mmap = gp->map[n]; const uint8_t *data; uint64_t head, tail; + int wrap = 0; tail = mmap->data_tail; head = mmap->data_head; rmb(); - if (head < tail) + if (head < tail) { + wrap = 1; + tail &= mask; + head &= mask; head += size; + } data = (uint8_t *)mmap + gp->page_size; while (head - tail >= sizeof (struct perf_event_header)) { @@ -259,7 +310,9 @@ int gpu_perf_update(struct gpu_perf *gp) tail += header->size; } - mmap->data_tail = tail & mask; + if (wrap) + tail &= mask; + mmap->data_tail = tail; } free(buffer); diff --git a/overlay/gpu-perf.h b/overlay/gpu-perf.h index 6a3e00d..95debc9 100644 --- a/overlay/gpu-perf.h +++ b/overlay/gpu-perf.h @@ -12,6 +12,12 @@ struct gpu_perf { } *sample; int flip_complete; + struct gpu_perf_comm { + struct gpu_perf_comm *next; + char name[256]; + pid_t pid; + int nr_requests[4]; + } *comm; }; void gpu_perf_init(struct gpu_perf *gp, unsigned flags); diff --git a/overlay/overlay.c b/overlay/overlay.c index c079004..0bd5792 100644 --- a/overlay/overlay.c +++ b/overlay/overlay.c @@ -1,4 +1,3 @@ -#include #include #include #include @@ -7,6 +6,7 @@ #include #include #include +#include #include #include "overlay.h" @@ -52,6 +52,11 @@ static void overlay_hide(cairo_surface_t *surface) } #endif +struct overlay_context { + cairo_t *cr; + int last_y; +}; + struct overlay_gpu_top { struct gpu_top gpu_top; struct chart busy[MAX_RINGS]; @@ -100,7 +105,7 @@ static void init_gpu_top(struct overlay_gpu_top *gt, } } -static void show_gpu_top(cairo_t *cr, struct overlay_gpu_top *gt) +static void show_gpu_top(struct overlay_context *ctx, struct overlay_gpu_top *gt) { int y, n, update; @@ -109,16 +114,16 @@ static void show_gpu_top(cairo_t *cr, struct overlay_gpu_top *gt) if (update) chart_add_sample(>->wait[n], gt->gpu_top.ring[n].u.u.wait + gt->gpu_top.ring[n].u.u.sema); - chart_draw(>->wait[n], cr); + chart_draw(>->wait[n], ctx->cr); } for (n = 0; n < gt->gpu_top.num_rings; n++) { if (update) chart_add_sample(>->busy[n], gt->gpu_top.ring[n].u.u.busy); - chart_draw(>->busy[n], cr); + chart_draw(>->busy[n], ctx->cr); } - cairo_set_source_rgb(cr, 1, 1, 1); + cairo_set_source_rgb(ctx->cr, 1, 1, 1); y = 12; for (n = 0; n < gt->gpu_top.num_rings; n++) { @@ -135,10 +140,12 @@ static void show_gpu_top(cairo_t *cr, struct overlay_gpu_top *gt) len += sprintf(txt + len, ", %d%% sema", gt->gpu_top.ring[n].u.u.sema); - cairo_move_to(cr, 12, y); - cairo_show_text(cr, txt); + cairo_move_to(ctx->cr, 12, y); + cairo_show_text(ctx->cr, txt); y += 14; } + + ctx->last_y = 112; } struct overlay_gpu_perf { @@ -146,29 +153,75 @@ struct overlay_gpu_perf { }; static void init_gpu_perf(struct overlay_gpu_perf *gp, - cairo_surface_t *surface) + cairo_surface_t *surface) { gpu_perf_init(&gp->gpu_perf, 0); } -static void show_gpu_perf(cairo_t *cr, struct overlay_gpu_perf *gp) +static char *get_comm(pid_t pid, char *comm, int len) +{ + char filename[1024]; + int fd; + + *comm = '\0'; + snprintf(filename, sizeof(filename), "/proc/%d/comm", pid); + + fd = open(filename, 0); + if (fd >= 0) { + len = read(fd, comm, len-1); + if (len >= 0) + comm[len-1] = '\0'; + close(fd); + } + + return comm; +} + +static void show_gpu_perf(struct overlay_context *ctx, struct overlay_gpu_perf *gp) { + struct gpu_perf_comm *comm, **prev; + const char *ring_name[] = { + "render", + "video", + "blt", + }; char buf[1024]; - int y; + int y, n; gpu_perf_update(&gp->gpu_perf); - y = 130; + y = ctx->last_y + 18; + + for (prev = &gp->gpu_perf.comm; (comm = *prev) != NULL; ) { + cairo_move_to(ctx->cr, 12, y); + sprintf(buf, "%s:", comm->name); + cairo_show_text(ctx->cr, buf); + for (n = 0; n < 3; n++) { + if (comm->nr_requests[n] == 0) + continue; + sprintf(buf, " %d %s", comm->nr_requests[n], ring_name[n]); + cairo_show_text(ctx->cr, buf); + } + y += 14; + + memset(comm->nr_requests, 0, sizeof(comm->nr_requests)); + if (strcmp(comm->name, get_comm(comm->pid, buf, sizeof(buf)))) { + *prev = comm->next; + free(comm); + } else + prev = &comm->next; + } sprintf(buf, "Flips: %d", gp->gpu_perf.flip_complete); - cairo_move_to(cr, 12, y); - cairo_show_text(cr, buf); + gp->gpu_perf.flip_complete = 0; + cairo_move_to(ctx->cr, 12, y); + cairo_show_text(ctx->cr, buf); y += 14; - gp->gpu_perf.flip_complete = 0; + ctx->last_y = y; } -static void show_gem_objects(cairo_t *cr) +static void show_gem_objects(struct overlay_context *ctx) { char gem_objects[1024], *s, *t, *end; int len, y; @@ -177,7 +230,7 @@ static void show_gem_objects(cairo_t *cr) if (len <= 0) return; - y = 150; + y = ctx->last_y + 18; s = gem_objects; end = s + len - 1; @@ -187,12 +240,14 @@ static void show_gem_objects(cairo_t *cr) t = end; *t = '\0'; - cairo_move_to(cr, 12, y); - cairo_show_text(cr, s); + cairo_move_to(ctx->cr, 12, y); + cairo_show_text(ctx->cr, s); y += 14; s = t+1; } + + ctx->last_y = y; } int main(int argc, char **argv) @@ -215,32 +270,33 @@ int main(int argc, char **argv) init_gpu_perf(&gpu_perf, surface); while (1) { - cairo_t *cr; + struct overlay_context ctx; usleep(500*1000); - cr = cairo_create(surface); - cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); - cairo_paint(cr); - cairo_set_operator(cr, CAIRO_OPERATOR_OVER); + ctx.cr = cairo_create(surface); + cairo_set_operator(ctx.cr, CAIRO_OPERATOR_CLEAR); + cairo_paint(ctx.cr); + cairo_set_operator(ctx.cr, CAIRO_OPERATOR_OVER); + ctx.last_y = 6; { char buf[80]; cairo_text_extents_t extents; sprintf(buf, "%d", i++); - cairo_set_source_rgb(cr, .5, .5, .5); - cairo_text_extents(cr, buf, &extents); - cairo_move_to(cr, + cairo_set_source_rgb(ctx.cr, .5, .5, .5); + cairo_text_extents(ctx.cr, buf, &extents); + cairo_move_to(ctx.cr, cairo_image_surface_get_width(surface)-extents.width-6, 6+extents.height); - cairo_show_text(cr, buf); + cairo_show_text(ctx.cr, buf); } - show_gpu_top(cr, &gpu_top); - show_gpu_perf(cr, &gpu_perf); - show_gem_objects(cr); + show_gpu_top(&ctx, &gpu_top); + show_gpu_perf(&ctx, &gpu_perf); + show_gem_objects(&ctx); - cairo_destroy(cr); + cairo_destroy(ctx.cr); overlay_show(surface); }