mirror of
https://github.com/tiagovignatti/intel-gpu-tools.git
synced 2025-06-12 02:16:17 +00:00
overlay: Track requests per-process
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
be9937b65c
commit
cbbd55af15
@ -30,6 +30,8 @@ struct sample_event {
|
|||||||
uint64_t time;
|
uint64_t time;
|
||||||
uint64_t id;
|
uint64_t id;
|
||||||
uint32_t raw_size;
|
uint32_t raw_size;
|
||||||
|
uint32_t raw_hdr0;
|
||||||
|
uint32_t raw_hdr1;
|
||||||
uint32_t raw[0];
|
uint32_t raw[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -117,7 +119,6 @@ static int perf_tracepoint_open(struct gpu_perf *gp,
|
|||||||
|
|
||||||
if (gp->nr_events)
|
if (gp->nr_events)
|
||||||
ioctl(fd[n], PERF_EVENT_IOC_SET_OUTPUT, gp->fd[n]);
|
ioctl(fd[n], PERF_EVENT_IOC_SET_OUTPUT, gp->fd[n]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gp->nr_events++;
|
gp->nr_events++;
|
||||||
@ -149,8 +150,53 @@ err:
|
|||||||
return EINVAL;
|
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)
|
static int seqno_start(struct gpu_perf *gp, const void *event)
|
||||||
{
|
{
|
||||||
|
printf ("seqno_start\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,9 +217,9 @@ void gpu_perf_init(struct gpu_perf *gp, unsigned flags)
|
|||||||
gp->nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
|
gp->nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
|
||||||
gp->page_size = getpagesize();
|
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)
|
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_gem_ring_dispatch", seqno_start);
|
||||||
|
|
||||||
perf_tracepoint_open(gp, "i915", "i915_flip_complete", flip_complete);
|
perf_tracepoint_open(gp, "i915", "i915_flip_complete", flip_complete);
|
||||||
|
|
||||||
if (gp->nr_events == 0)
|
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];
|
struct perf_event_mmap_page *mmap = gp->map[n];
|
||||||
const uint8_t *data;
|
const uint8_t *data;
|
||||||
uint64_t head, tail;
|
uint64_t head, tail;
|
||||||
|
int wrap = 0;
|
||||||
|
|
||||||
tail = mmap->data_tail;
|
tail = mmap->data_tail;
|
||||||
head = mmap->data_head;
|
head = mmap->data_head;
|
||||||
rmb();
|
rmb();
|
||||||
|
|
||||||
if (head < tail)
|
if (head < tail) {
|
||||||
|
wrap = 1;
|
||||||
|
tail &= mask;
|
||||||
|
head &= mask;
|
||||||
head += size;
|
head += size;
|
||||||
|
}
|
||||||
|
|
||||||
data = (uint8_t *)mmap + gp->page_size;
|
data = (uint8_t *)mmap + gp->page_size;
|
||||||
while (head - tail >= sizeof (struct perf_event_header)) {
|
while (head - tail >= sizeof (struct perf_event_header)) {
|
||||||
@ -259,7 +310,9 @@ int gpu_perf_update(struct gpu_perf *gp)
|
|||||||
tail += header->size;
|
tail += header->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
mmap->data_tail = tail & mask;
|
if (wrap)
|
||||||
|
tail &= mask;
|
||||||
|
mmap->data_tail = tail;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
@ -12,6 +12,12 @@ struct gpu_perf {
|
|||||||
} *sample;
|
} *sample;
|
||||||
|
|
||||||
int flip_complete;
|
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);
|
void gpu_perf_init(struct gpu_perf *gp, unsigned flags);
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
#include <X11/Xlib.h>
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <cairo.h>
|
#include <cairo.h>
|
||||||
@ -7,6 +6,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "overlay.h"
|
#include "overlay.h"
|
||||||
@ -52,6 +52,11 @@ static void overlay_hide(cairo_surface_t *surface)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct overlay_context {
|
||||||
|
cairo_t *cr;
|
||||||
|
int last_y;
|
||||||
|
};
|
||||||
|
|
||||||
struct overlay_gpu_top {
|
struct overlay_gpu_top {
|
||||||
struct gpu_top gpu_top;
|
struct gpu_top gpu_top;
|
||||||
struct chart busy[MAX_RINGS];
|
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;
|
int y, n, update;
|
||||||
|
|
||||||
@ -109,16 +114,16 @@ static void show_gpu_top(cairo_t *cr, struct overlay_gpu_top *gt)
|
|||||||
if (update)
|
if (update)
|
||||||
chart_add_sample(>->wait[n],
|
chart_add_sample(>->wait[n],
|
||||||
gt->gpu_top.ring[n].u.u.wait + gt->gpu_top.ring[n].u.u.sema);
|
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++) {
|
for (n = 0; n < gt->gpu_top.num_rings; n++) {
|
||||||
if (update)
|
if (update)
|
||||||
chart_add_sample(>->busy[n],
|
chart_add_sample(>->busy[n],
|
||||||
gt->gpu_top.ring[n].u.u.busy);
|
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;
|
y = 12;
|
||||||
for (n = 0; n < gt->gpu_top.num_rings; n++) {
|
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",
|
len += sprintf(txt + len, ", %d%% sema",
|
||||||
gt->gpu_top.ring[n].u.u.sema);
|
gt->gpu_top.ring[n].u.u.sema);
|
||||||
|
|
||||||
cairo_move_to(cr, 12, y);
|
cairo_move_to(ctx->cr, 12, y);
|
||||||
cairo_show_text(cr, txt);
|
cairo_show_text(ctx->cr, txt);
|
||||||
y += 14;
|
y += 14;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx->last_y = 112;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct overlay_gpu_perf {
|
struct overlay_gpu_perf {
|
||||||
@ -146,29 +153,75 @@ struct overlay_gpu_perf {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void init_gpu_perf(struct overlay_gpu_perf *gp,
|
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);
|
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];
|
char buf[1024];
|
||||||
int y;
|
int y, n;
|
||||||
|
|
||||||
gpu_perf_update(&gp->gpu_perf);
|
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);
|
sprintf(buf, "Flips: %d", gp->gpu_perf.flip_complete);
|
||||||
cairo_move_to(cr, 12, y);
|
gp->gpu_perf.flip_complete = 0;
|
||||||
cairo_show_text(cr, buf);
|
cairo_move_to(ctx->cr, 12, y);
|
||||||
|
cairo_show_text(ctx->cr, buf);
|
||||||
y += 14;
|
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;
|
char gem_objects[1024], *s, *t, *end;
|
||||||
int len, y;
|
int len, y;
|
||||||
@ -177,7 +230,7 @@ static void show_gem_objects(cairo_t *cr)
|
|||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
y = 150;
|
y = ctx->last_y + 18;
|
||||||
|
|
||||||
s = gem_objects;
|
s = gem_objects;
|
||||||
end = s + len - 1;
|
end = s + len - 1;
|
||||||
@ -187,12 +240,14 @@ static void show_gem_objects(cairo_t *cr)
|
|||||||
t = end;
|
t = end;
|
||||||
*t = '\0';
|
*t = '\0';
|
||||||
|
|
||||||
cairo_move_to(cr, 12, y);
|
cairo_move_to(ctx->cr, 12, y);
|
||||||
cairo_show_text(cr, s);
|
cairo_show_text(ctx->cr, s);
|
||||||
y += 14;
|
y += 14;
|
||||||
|
|
||||||
s = t+1;
|
s = t+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx->last_y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
@ -215,32 +270,33 @@ int main(int argc, char **argv)
|
|||||||
init_gpu_perf(&gpu_perf, surface);
|
init_gpu_perf(&gpu_perf, surface);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
cairo_t *cr;
|
struct overlay_context ctx;
|
||||||
|
|
||||||
usleep(500*1000);
|
usleep(500*1000);
|
||||||
|
|
||||||
cr = cairo_create(surface);
|
ctx.cr = cairo_create(surface);
|
||||||
cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
|
cairo_set_operator(ctx.cr, CAIRO_OPERATOR_CLEAR);
|
||||||
cairo_paint(cr);
|
cairo_paint(ctx.cr);
|
||||||
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
|
cairo_set_operator(ctx.cr, CAIRO_OPERATOR_OVER);
|
||||||
|
ctx.last_y = 6;
|
||||||
|
|
||||||
{
|
{
|
||||||
char buf[80];
|
char buf[80];
|
||||||
cairo_text_extents_t extents;
|
cairo_text_extents_t extents;
|
||||||
sprintf(buf, "%d", i++);
|
sprintf(buf, "%d", i++);
|
||||||
cairo_set_source_rgb(cr, .5, .5, .5);
|
cairo_set_source_rgb(ctx.cr, .5, .5, .5);
|
||||||
cairo_text_extents(cr, buf, &extents);
|
cairo_text_extents(ctx.cr, buf, &extents);
|
||||||
cairo_move_to(cr,
|
cairo_move_to(ctx.cr,
|
||||||
cairo_image_surface_get_width(surface)-extents.width-6,
|
cairo_image_surface_get_width(surface)-extents.width-6,
|
||||||
6+extents.height);
|
6+extents.height);
|
||||||
cairo_show_text(cr, buf);
|
cairo_show_text(ctx.cr, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
show_gpu_top(cr, &gpu_top);
|
show_gpu_top(&ctx, &gpu_top);
|
||||||
show_gpu_perf(cr, &gpu_perf);
|
show_gpu_perf(&ctx, &gpu_perf);
|
||||||
show_gem_objects(cr);
|
show_gem_objects(&ctx);
|
||||||
|
|
||||||
cairo_destroy(cr);
|
cairo_destroy(ctx.cr);
|
||||||
|
|
||||||
overlay_show(surface);
|
overlay_show(surface);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user