From: Chris Wilson Date: Sun, 18 Aug 2013 17:17:05 +0000 (+0100) Subject: overlay: Parse gem objects X-Git-Tag: intel-gpu-tools-1.4~179 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e1ed5606c6dd9d320b97582a9575e2b86a17e844;p=profile%2Fextras%2Fintel-gpu-tools.git overlay: Parse gem objects Condense the information and begin graphing it. Remaining todo for memory is to measure bind/evict flux, and perhaps clflush. Signed-off-by: Chris Wilson --- diff --git a/overlay/gem-objects.c b/overlay/gem-objects.c index 37d6726..ffc13f9 100644 --- a/overlay/gem-objects.c +++ b/overlay/gem-objects.c @@ -1,19 +1,134 @@ #include #include +#include +#include +#include +#include #include "gem-objects.h" -int gem_objects_update(char *buf, int buflen) +/* /sys/kernel/debug/dri/0/i915_gem_objects: + * 46 objects, 20107264 bytes + * 42 [42] objects, 15863808 [15863808] bytes in gtt + * 0 [0] active objects, 0 [0] bytes + * 42 [42] inactive objects, 15863808 [15863808] bytes + * 0 unbound objects, 0 bytes + * 3 purgeable objects, 4456448 bytes + * 30 pinned mappable objects, 3821568 bytes + * 1 fault mappable objects, 3145728 bytes + * 2145386496 [536870912] gtt total + * + * Xorg: 35 objects, 16347136 bytes (0 active, 12103680 inactive, 0 unbound) + */ + +int gem_objects_init(struct gem_objects *obj) { - int fd, len = -1; + char buf[8192], *b; + int fd, len; + + memset(obj, 0, sizeof(*obj)); fd = open("/sys/kernel/debug/dri/0/i915_gem_objects", 0); - if (fd >= 0) { - len = read(fd, buf, buflen-1); - if (len >= 0) - buf[len] = '\0'; - close(fd); + if (fd < 0) + return errno; + len = read(fd, buf, sizeof(buf)-1); + close(fd); + + if (len < 0) + return EIO; + + b = strstr(buf, "gtt total"); + if (b == NULL) + return EIO; + + while (*b != '\n') + b--; + + sscanf(b, "%ld [%ld]", + &obj->max_gtt, &obj->max_aperture); + + return 0; +} + +static void insert_sorted(struct gem_objects *obj, + struct gem_objects_comm *comm) +{ + struct gem_objects_comm *next, **prev; + + for (prev = &obj->comm; (next = *prev) != NULL; prev = &next->next) + if (comm->bytes > next->bytes) + break; + + comm->next = *prev; + *prev = comm; +} + +int gem_objects_update(struct gem_objects *obj) +{ + char buf[8192], *b; + struct gem_objects_comm *comm; + struct gem_objects_comm *freed; + int fd, len, ret; + + freed = obj->comm; + obj->comm = NULL; + + fd = open("/sys/kernel/debug/dri/0/i915_gem_objects", 0); + if (fd < 0) { + ret = errno; + goto done; + } + len = read(fd, buf, sizeof(buf)-1); + close(fd); + + if (len < 0) { + ret = EIO; + goto done; + } + + buf[len] = '\0'; + while (buf[--len] == '\n') + buf[len] = '\0'; + + b = buf; + + sscanf(b, "%d objects, %ld bytes", + &obj->total_count, &obj->total_bytes); + + b = strchr(b, '\n'); + sscanf(b, "%*d [%*d] objects, %ld [%ld] bytes in gtt", + &obj->total_gtt, &obj->total_aperture); + + ret = 0; + b = strchr(b, ':'); + if (b == NULL) + goto done; + + while (*b != '\n') + b--; + + do { + comm = freed; + if (comm) + freed = comm->next; + else + comm = malloc(sizeof(*comm)); + if (comm == NULL) + break; + + /* Xorg: 35 objects, 16347136 bytes (0 active, 12103680 inactive, 0 unbound) */ + sscanf(++b, "%256s %u objects, %lu bytes", + comm->name, &comm->count, &comm->bytes); + + insert_sorted(obj, comm); + } while ((b = strchr(b, '\n')) != NULL); + +done: + while (freed) { + comm = freed; + freed = comm->next; + free(comm); } - return len; + return ret; } diff --git a/overlay/gem-objects.h b/overlay/gem-objects.h index 898d18f..b0c4519 100644 --- a/overlay/gem-objects.h +++ b/overlay/gem-objects.h @@ -1 +1,17 @@ -int gem_objects_update(char *buf, int buflen); +#include + +struct gem_objects { + uint64_t total_bytes; + uint32_t total_count; + uint64_t total_gtt, total_aperture; + uint64_t max_gtt, max_aperture; + struct gem_objects_comm { + struct gem_objects_comm *next; + char name[256]; + uint64_t bytes; + uint32_t count; + } *comm; +}; + +int gem_objects_init(struct gem_objects *obj); +int gem_objects_update(struct gem_objects *obj); diff --git a/overlay/overlay.c b/overlay/overlay.c index b888962..56dd2e1 100644 --- a/overlay/overlay.c +++ b/overlay/overlay.c @@ -435,33 +435,76 @@ static void show_gpu_freq(struct overlay_context *ctx, struct overlay_gpu_freq * ctx->last_y += 112; } -static void show_gem_objects(struct overlay_context *ctx) +struct overlay_gem_objects { + struct gem_objects gem_objects; + struct chart aperture; + struct chart gtt; + int error; +}; + +static void init_gem_objects(struct overlay_gem_objects *go, + cairo_surface_t *surface) { - char gem_objects[1024], *s, *t, *end; - int len, y; + go->error = gem_objects_init(&go->gem_objects); + if (go->error) + return; + + chart_init(&go->aperture, "aperture", 120); + chart_set_size(&go->aperture, + cairo_image_surface_get_width(surface)-24, + 100); + chart_set_stroke_rgba(&go->aperture, 0.75, 0.25, 0.50, 1.); + chart_set_mode(&go->aperture, CHART_STROKE); + chart_set_range(&go->aperture, 0, go->gem_objects.max_gtt); - len = gem_objects_update(gem_objects, sizeof(gem_objects)); - if (len <= 0) + chart_init(&go->gtt, "gtt", 120); + chart_set_size(&go->gtt, + cairo_image_surface_get_width(surface)-24, + 100); + chart_set_fill_rgba(&go->gtt, 0.25, 0.75, 0.50, 1.); + chart_set_mode(&go->gtt, CHART_FILL); + chart_set_range(&go->gtt, 0, go->gem_objects.max_gtt); +} + +static void show_gem_objects(struct overlay_context *ctx, struct overlay_gem_objects *go) +{ + struct gem_objects_comm *comm; + char buf[160]; + int y; + + if (go->error == 0) + go->error = gem_objects_update(&go->gem_objects); + if (go->error) return; - y = ctx->last_y + 18; + chart_add_sample(&go->gtt, go->gem_objects.total_gtt); + chart_add_sample(&go->aperture, go->gem_objects.total_aperture); + + y = ctx->last_y + 6; - s = gem_objects; - end = s + len - 1; - while (s < end) { - t = strchr(s, '\n'); - if (t == NULL) - t = end; - *t = '\0'; + chart_set_position(&go->gtt, 12, y); + chart_set_position(&go->aperture, 12, y); + chart_draw(&go->gtt, ctx->cr); + chart_draw(&go->aperture, ctx->cr); + + sprintf(buf, "Total: %ld bytes, %d objects", + go->gem_objects.total_bytes, go->gem_objects.total_count); + cairo_set_source_rgba(ctx->cr, 1, 1, 1, 1); + cairo_move_to(ctx->cr, 12, y); + cairo_show_text(ctx->cr, buf); + y += 14; + + for (comm = go->gem_objects.comm; comm; comm = comm->next) { + sprintf(buf, " %s: %ld bytes, %d objects", + comm->name, comm->bytes, comm->count); + cairo_set_source_rgba(ctx->cr, 1, 1, 1, 1); cairo_move_to(ctx->cr, 12, y); - cairo_show_text(ctx->cr, s); + cairo_show_text(ctx->cr, buf); y += 14; - - s = t+1; } - ctx->last_y = y; + ctx->last_y += 112; } int main(int argc, char **argv) @@ -470,6 +513,7 @@ int main(int argc, char **argv) struct overlay_gpu_top gpu_top; struct overlay_gpu_perf gpu_perf; struct overlay_gpu_freq gpu_freq; + struct overlay_gem_objects gem_objects; int i = 0; if (argc > 1) { @@ -484,6 +528,7 @@ int main(int argc, char **argv) init_gpu_top(&gpu_top, surface); init_gpu_perf(&gpu_perf, surface); init_gpu_freq(&gpu_freq, surface); + init_gem_objects(&gem_objects, surface); while (1) { struct overlay_context ctx; @@ -511,7 +556,7 @@ int main(int argc, char **argv) show_gpu_top(&ctx, &gpu_top); show_gpu_perf(&ctx, &gpu_perf); show_gpu_freq(&ctx, &gpu_freq); - show_gem_objects(&ctx); + show_gem_objects(&ctx, &gem_objects); cairo_destroy(ctx.cr);