overlay: Show per-process wait times
authorChris Wilson <chris@chris-wilson.co.uk>
Sat, 17 Aug 2013 20:14:10 +0000 (21:14 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Sat, 17 Aug 2013 20:14:10 +0000 (21:14 +0100)
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
overlay/chart.c
overlay/gpu-perf.c
overlay/gpu-perf.h
overlay/overlay.c

index 185eaf0..46adbac 100644 (file)
@@ -83,9 +83,11 @@ void chart_add_sample(struct chart *chart, double value)
 {
        int pos;
 
-       pos = chart->current_sample % chart->num_samples;
+       if (chart->num_samples == 0)
+               return;
+
+       pos = chart->current_sample++ % chart->num_samples;
        chart->samples[pos] = value;
-       chart->current_sample++;
 }
 
 static void chart_update_range(struct chart *chart)
index 8717437..78d1756 100644 (file)
@@ -169,27 +169,38 @@ static char *get_comm(pid_t pid, char *comm, int len)
        return comm;
 }
 
-static int request_add(struct gpu_perf *gp, const void *event)
+static struct gpu_perf_comm *
+lookup_comm(struct gpu_perf *gp, pid_t pid)
 {
-       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)
+               if (comm->pid == pid)
                        break;
        }
        if (comm == NULL) {
-               comm = malloc(sizeof(*comm));
+               comm = calloc(1, sizeof(*comm));
                if (comm == NULL)
-                       return 0;
+                       return NULL;
 
                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));
+               get_comm(pid, comm->name, sizeof(comm->name));
+               comm->pid = pid;
        }
 
+       return comm;
+}
+
+static int request_add(struct gpu_perf *gp, const void *event)
+{
+       const struct sample_event *sample = event;
+       struct gpu_perf_comm *comm;
+
+       comm = lookup_comm(gp, sample->pid);
+       if (comm == NULL)
+               return 0;
+
        comm->nr_requests[sample->raw[1]]++;
        return 1;
 }
@@ -211,6 +222,32 @@ static int flip_complete(struct gpu_perf *gp, const void *event)
        return 1;
 }
 
+static int wait_begin(struct gpu_perf *gp, const void *event)
+{
+       const struct sample_event *sample = event;
+       struct gpu_perf_comm *comm;
+
+       comm = lookup_comm(gp, sample->pid);
+       if (comm == NULL)
+               return 0;
+
+       comm->wait_begin = sample->time;
+       return 0;
+}
+
+static int wait_end(struct gpu_perf *gp, const void *event)
+{
+       const struct sample_event *sample = event;
+       struct gpu_perf_comm *comm;
+
+       comm = lookup_comm(gp, sample->pid);
+       if (comm == NULL)
+               return 0;
+
+       comm->wait_time += sample->time - comm->wait_begin;
+       return 0;
+}
+
 void gpu_perf_init(struct gpu_perf *gp, unsigned flags)
 {
        memset(gp, 0, sizeof(*gp));
@@ -220,6 +257,8 @@ void gpu_perf_init(struct gpu_perf *gp, unsigned flags)
        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);
+       if (perf_tracepoint_open(gp, "i915", "i915_gem_request_wait_begin", wait_begin) == 0)
+               perf_tracepoint_open(gp, "i915", "i915_gem_request_wait_end", wait_end);
        perf_tracepoint_open(gp, "i915", "i915_flip_complete", flip_complete);
 
        if (gp->nr_events == 0)
index 557e501..5c3e242 100644 (file)
@@ -18,6 +18,9 @@ struct gpu_perf {
                pid_t pid;
                int nr_requests[4];
                void *user_data;
+
+               uint64_t wait_begin;
+               uint64_t wait_time;
        } *comm;
 };
 
index 6297e5e..b41dfc4 100644 (file)
@@ -244,6 +244,8 @@ static void show_gpu_perf(struct overlay_context *ctx, struct overlay_gpu_perf *
        }
 
        for (prev = &gp->gpu_perf.comm; (comm = *prev) != NULL; ) {
+               int need_comma = 0;
+
                if (comm->user_data) {
                        struct chart *c = comm->user_data;
                        cairo_set_source_rgba(ctx->cr,
@@ -259,8 +261,19 @@ static void show_gpu_perf(struct overlay_context *ctx, struct overlay_gpu_perf *
                for (n = 0; n < 3; n++) {
                        if (comm->nr_requests[n] == 0)
                                continue;
-                       sprintf(buf, " %d %s", comm->nr_requests[n], ring_name[n]);
+                       sprintf(buf, "%s %d %s", need_comma ? "," : "", comm->nr_requests[n], ring_name[n]);
                        cairo_show_text(ctx->cr, buf);
+                       need_comma = true;
+               }
+               if (comm->wait_time) {
+                       if (comm->wait_time > 100) {
+                               sprintf(buf, "%s %.1f us waiting",
+                                       need_comma ? "," : "",
+                                       comm->wait_time / 1000.);
+                               cairo_show_text(ctx->cr, buf);
+                               need_comma = true;
+                       }
+                       comm->wait_time = 0;
                }
                y += 14;