* [RFC i-g-t 0/3] New intel-gpu-top
@ 2018-02-14 18:52 Tvrtko Ursulin
2018-02-14 18:52 ` [RFC i-g-t 1/3] intel-gpu-top: Rename to intel-legacy-top Tvrtko Ursulin
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Tvrtko Ursulin @ 2018-02-14 18:52 UTC (permalink / raw)
To: Intel-gfx
From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
I've found a new potential lead vehicle to sell my per-client engine busyness
patches and that is a rewrite of intel-gpu-top.
Old one is neglected and dangerous - so how about a new one which looks like
this?
intel-gpu-top - load avg 9.47, 3.34, 0.13; 1000/ 950 MHz; 0% RC6; 5202mW; 1206 irqs/s
rcs0 100.00% ( 0.56/ 4.78/ 3.86) |██████████████████████████████████████████████████████████████████| 0.00% wait, 0.00% sema
bcs0 17.72% ( 0.81/ 0.00/ 0.17) |███████████▋ | 0.00% wait, 0.00% sema
vcs0 61.08% ( 0.81/ 0.00/ 0.63) |████████████████████████████████████████▎ | 0.00% wait, 0.00% sema
vecs0 0.00% ( 0.00/ 0.00/ 0.00) | | 0.00% wait, 0.00% sema
PID NAME rcs0 bcs0 vcs0 vecs0
9654 neverball |████████████ || || || |
7792 Xorg |████████▊ || || || |
9659 gem_wsim |████ ||████▍ ||███████████████▎ || |
7846 xfwm4 | || || || |
So this series renames the old one to intel_legacy_top and replaces it with a
new one which uses PMU and some extra patches as well.
Code is not production quality but an attempt to spark some interest on the
topic.
Tvrtko Ursulin (3):
intel-gpu-top: Rename to intel-legacy-top
intel-gpu-top: New version using PMU
intel-gpu-top: Support for client stats
tools/.gitignore | 1 +
tools/Makefile.am | 2 +
tools/Makefile.sources | 1 +
tools/intel_gpu_top.c | 1311 +++++++++++++++++++++++++---------------------
tools/intel_legacy_top.c | 718 +++++++++++++++++++++++++
tools/meson.build | 3 +-
6 files changed, 1446 insertions(+), 590 deletions(-)
create mode 100644 tools/intel_legacy_top.c
--
2.14.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 9+ messages in thread
* [RFC i-g-t 1/3] intel-gpu-top: Rename to intel-legacy-top
2018-02-14 18:52 [RFC i-g-t 0/3] New intel-gpu-top Tvrtko Ursulin
@ 2018-02-14 18:52 ` Tvrtko Ursulin
2018-02-15 9:10 ` Petri Latvala
2018-02-14 18:52 ` [RFC i-g-t 2/3] intel-gpu-top: New version using PMU Tvrtko Ursulin
` (2 subsequent siblings)
3 siblings, 1 reply; 9+ messages in thread
From: Tvrtko Ursulin @ 2018-02-14 18:52 UTC (permalink / raw)
To: Intel-gfx
From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
tools/.gitignore | 2 +-
tools/Makefile.sources | 2 +-
tools/{intel_gpu_top.c => intel_legacy_top.c} | 0
tools/meson.build | 2 +-
4 files changed, 3 insertions(+), 3 deletions(-)
rename tools/{intel_gpu_top.c => intel_legacy_top.c} (100%)
diff --git a/tools/.gitignore b/tools/.gitignore
index 2de665a36688..19a1f7cb8e50 100644
--- a/tools/.gitignore
+++ b/tools/.gitignore
@@ -17,7 +17,7 @@ intel_framebuffer_dump
intel_gem_info
intel_gpu_frequency
intel_gpu_time
-intel_gpu_top
+intel_legacy_top
intel_gtt
intel_guc_logger
intel_gvtg_test
diff --git a/tools/Makefile.sources b/tools/Makefile.sources
index abd23a0f4628..9699b7d2f737 100644
--- a/tools/Makefile.sources
+++ b/tools/Makefile.sources
@@ -17,7 +17,7 @@ tools_prog_lists = \
intel_gpu_frequency \
intel_firmware_decode \
intel_gpu_time \
- intel_gpu_top \
+ intel_legacy_top \
intel_gtt \
intel_guc_logger \
intel_infoframes \
diff --git a/tools/intel_gpu_top.c b/tools/intel_legacy_top.c
similarity index 100%
rename from tools/intel_gpu_top.c
rename to tools/intel_legacy_top.c
diff --git a/tools/meson.build b/tools/meson.build
index a96735c2244d..ebce4e305d00 100644
--- a/tools/meson.build
+++ b/tools/meson.build
@@ -23,7 +23,7 @@ tools_progs = [
'intel_gpu_frequency',
'intel_firmware_decode',
'intel_gpu_time',
- 'intel_gpu_top',
+ 'intel_legacy_top',
'intel_gtt',
'intel_guc_logger',
'intel_infoframes',
--
2.14.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [RFC i-g-t 2/3] intel-gpu-top: New version using PMU
2018-02-14 18:52 [RFC i-g-t 0/3] New intel-gpu-top Tvrtko Ursulin
2018-02-14 18:52 ` [RFC i-g-t 1/3] intel-gpu-top: Rename to intel-legacy-top Tvrtko Ursulin
@ 2018-02-14 18:52 ` Tvrtko Ursulin
2018-02-14 18:52 ` [RFC i-g-t 3/3] intel-gpu-top: Support for client stats Tvrtko Ursulin
2018-02-14 19:30 ` ✓ Fi.CI.BAT: success for New intel-gpu-top Patchwork
3 siblings, 0 replies; 9+ messages in thread
From: Tvrtko Ursulin @ 2018-02-14 18:52 UTC (permalink / raw)
To: Intel-gfx
From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
tools/.gitignore | 1 +
tools/Makefile.am | 2 +
tools/Makefile.sources | 1 +
tools/intel_gpu_top.c | 593 +++++++++++++++++++++++++++++++++++++++++++++++++
tools/meson.build | 1 +
5 files changed, 598 insertions(+)
create mode 100644 tools/intel_gpu_top.c
diff --git a/tools/.gitignore b/tools/.gitignore
index 19a1f7cb8e50..6e3042810176 100644
--- a/tools/.gitignore
+++ b/tools/.gitignore
@@ -17,6 +17,7 @@ intel_framebuffer_dump
intel_gem_info
intel_gpu_frequency
intel_gpu_time
+intel_gpu_top
intel_legacy_top
intel_gtt
intel_guc_logger
diff --git a/tools/Makefile.am b/tools/Makefile.am
index dcf282eaff4e..8f6c15791a3b 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -30,6 +30,8 @@ intel_aubdump_la_LDFLAGS = -module -avoid-version -no-undefined
intel_aubdump_la_SOURCES = aubdump.c
intel_aubdump_la_LIBADD = $(top_builddir)/lib/libintel_tools.la -ldl
+intel_gpu_top_LDADD = $(top_builddir)/lib/libigt_perf.la -lm
+
bin_SCRIPTS = intel_aubdump
CLEANFILES = $(bin_SCRIPTS)
diff --git a/tools/Makefile.sources b/tools/Makefile.sources
index 9699b7d2f737..6f8668bd4d56 100644
--- a/tools/Makefile.sources
+++ b/tools/Makefile.sources
@@ -17,6 +17,7 @@ tools_prog_lists = \
intel_gpu_frequency \
intel_firmware_decode \
intel_gpu_time \
+ intel_gpu_top \
intel_legacy_top \
intel_gtt \
intel_guc_logger \
diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c
new file mode 100644
index 000000000000..59a112240092
--- /dev/null
+++ b/tools/intel_gpu_top.c
@@ -0,0 +1,593 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <stdint.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <math.h>
+
+#include "igt_perf.h"
+
+struct pmu_pair {
+ uint64_t cur;
+ uint64_t prev;
+};
+
+struct pmu_counter {
+ uint64_t config;
+ unsigned int idx;
+ struct pmu_pair val;
+};
+
+#define NUM_LOADS (3)
+
+struct engine {
+ const char *name;
+ double qd[3];
+ double load_avg[NUM_LOADS];
+ struct pmu_counter busy;
+ struct pmu_counter wait;
+ struct pmu_counter sema;
+ struct pmu_counter queued;
+ struct pmu_counter runnable;
+ struct pmu_counter running;
+};
+
+struct engines {
+ unsigned int num_engines;
+ unsigned int num_counters;
+ DIR *root;
+ int fd;
+ struct pmu_pair ts;
+
+ int rapl_fd;
+ double rapl_scale;
+
+ struct pmu_counter freq_req;
+ struct pmu_counter freq_act;
+ struct pmu_counter irq;
+ struct pmu_counter rc6;
+ struct pmu_counter rapl;
+
+ double qd_scale;
+
+ double load_exp[NUM_LOADS];
+ double load_avg[NUM_LOADS];
+
+ struct engine engine;
+};
+
+static uint64_t
+get_pmu_config(int dirfd, const char *name, const char *counter)
+{
+ char buf[128], *p;
+ int fd, ret;
+
+ ret = snprintf(buf, sizeof(buf), "%s-%s", name, counter);
+ if (ret < 0 || ret == sizeof(buf))
+ return -1;
+
+ fd = openat(dirfd, buf, O_RDONLY);
+ if (fd < 0)
+ return -1;
+
+ ret = read(fd, buf, sizeof(buf));
+ close(fd);
+ if (ret <= 0)
+ return -1;
+
+ p = index(buf, '0');
+ if (!p)
+ return -1;
+
+ return strtoul(p, NULL, 0);
+}
+
+#define engine_ptr(engines, n) \
+ ((struct engine *)((unsigned char *)(&engines->engine) + (n) * sizeof(struct engine)))
+
+static struct engines *discover_engines(void)
+{
+ const char *sysfs_root = "/sys/devices/i915/events";
+ struct engines *engines;
+ struct dirent *dent;
+ int ret = 0;
+ DIR *d;
+
+ engines = malloc(sizeof(struct engines));
+ if (!engines)
+ return NULL;
+ memset(engines, 0, sizeof(*engines));
+
+ engines->num_engines = 0;
+
+ d = opendir(sysfs_root);
+ if (!d)
+ return NULL;
+
+ while ((dent = readdir(d)) != NULL) {
+ const char *endswith = "-busy";
+ const unsigned int endlen = strlen(endswith);
+ struct engine *engine =
+ engine_ptr(engines, engines->num_engines);
+ char buf[256];
+
+ if (dent->d_type != DT_REG)
+ continue;
+
+ if (strlen(dent->d_name) >= sizeof(buf)) {
+ ret = -1;
+ break;
+ }
+
+ strcpy(buf, dent->d_name);
+
+ /* xxxN-busy */
+ if (strlen(buf) < (endlen + 4))
+ continue;
+ if (strcmp(&buf[strlen(buf) - endlen], endswith))
+ continue;
+
+ memset(engine, 0, sizeof(*engine));
+
+ buf[strlen(buf) - endlen] = 0;
+ engine->name = strdup(buf);
+ if (!engine->name) {
+ ret = -1;
+ break;
+ }
+
+ engine->busy.config = get_pmu_config(dirfd(d),
+ engine->name,
+ "busy");
+ if (engine->busy.config == -1) {
+ ret = -1;
+ break;
+ }
+
+ engines->num_engines++;
+ engines = realloc(engines, sizeof(struct engines) +
+ engines->num_engines * sizeof(struct engine));
+ if (!engines) {
+ ret = -ENOMEM;
+ break;
+ }
+ }
+
+ if (ret)
+ free(engines);
+ else
+ engines->root = d;
+
+ return ret == 0 ? engines : NULL;
+}
+
+static int
+filename_to_buf(const char *filename, char *buf, unsigned int bufsize)
+{
+ int fd;
+ ssize_t ret;
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ return -1;
+
+ ret = read(fd, buf, bufsize - 1);
+ close(fd);
+ if (ret < 1)
+ return -1;
+
+ buf[ret] = '\0';
+
+ return 0;
+}
+
+static uint64_t filename_to_u64(const char *filename, int base)
+{
+ char buf[64], *b;
+
+ if (filename_to_buf(filename, buf, sizeof(buf)))
+ return 0;
+
+ /*
+ * Handle both single integer and key=value formats by skipping
+ * leading non-digits.
+ */
+ b = buf;
+ while (*b && !isdigit(*b))
+ b++;
+
+ return strtoull(b, NULL, base);
+}
+
+static uint64_t rapl_type_id(void)
+{
+ return filename_to_u64("/sys/devices/power/type", 10);
+}
+
+static uint64_t rapl_gpu_power(void)
+{
+ return filename_to_u64("/sys/devices/power/events/energy-gpu", 0);
+}
+
+static double filename_to_double(const char *filename)
+{
+ char buf[64];
+
+ if (filename_to_buf(filename, buf, sizeof(buf)))
+ return 0;
+
+ return strtod(buf, NULL);
+}
+
+static double rapl_gpu_power_scale(void)
+{
+ return filename_to_double("/sys/devices/power/events/energy-gpu.scale");
+}
+
+static double i915_qd_scale(void)
+{
+ return filename_to_double("/sys/devices/i915/events/rcs0-queued.scale");
+}
+
+#define __open_pmu(engines, pmu, idx) \
+({ \
+ int fd__; \
+\
+ fd__ = perf_i915_open_group((pmu)->config, (engines)->fd); \
+ if (fd__ >= 0) { \
+ if ((engines)->fd == -1) \
+ (engines)->fd = fd__; \
+ (pmu)->idx = (idx)++; \
+ (engines)->num_counters++; \
+ } \
+\
+ fd__; \
+})
+
+static int pmu_init(struct engines *engines)
+{
+ unsigned int idx = 0;
+ unsigned int i;
+ int fd;
+
+ engines->fd = -1;
+ engines->num_counters = 0;
+
+ engines->freq_req.config = I915_PMU_REQUESTED_FREQUENCY;
+ fd = __open_pmu(engines, &engines->freq_req, idx);
+ if (fd < 0)
+ return -1;
+
+ engines->freq_act.config = I915_PMU_ACTUAL_FREQUENCY;
+ fd = __open_pmu(engines, &engines->freq_act, idx);
+ if (fd < 0)
+ return -1;
+
+ engines->irq.config = I915_PMU_INTERRUPTS;
+ fd = __open_pmu(engines, &engines->irq, idx);
+ if (fd < 0)
+ return -1;
+
+ engines->rc6.config = I915_PMU_RC6_RESIDENCY;
+ fd = __open_pmu(engines, &engines->rc6, idx);
+ if (fd < 0)
+ return -1;
+
+ engines->qd_scale = i915_qd_scale();
+
+ for (i = 0; i < engines->num_engines; i++) {
+ struct engine *engine = engine_ptr(engines, i);
+ struct {
+ struct pmu_counter *pmu;
+ const char *counter;
+ } *cnt, counters[] = {
+ { .pmu = &engine->busy, .counter = "busy" },
+ { .pmu = &engine->wait, .counter = "wait" },
+ { .pmu = &engine->sema, .counter = "sema" },
+ { .pmu = &engine->queued, .counter = "queued" },
+ { .pmu = &engine->runnable, .counter = "runnable" },
+ { .pmu = &engine->running, .counter = "running" },
+ { .pmu = NULL, .counter = NULL },
+ };
+
+ for (cnt = counters; cnt->pmu; cnt++) {
+ if (!cnt->pmu->config)
+ cnt->pmu->config =
+ get_pmu_config(dirfd(engines->root),
+ engine->name,
+ cnt->counter);
+ fd = __open_pmu(engines, cnt->pmu, idx);
+ if (fd < 0)
+ return -1;
+ }
+ }
+
+ engines->rapl_scale = rapl_gpu_power_scale();
+ if (engines->rapl_scale != NAN)
+ engines->rapl_scale *= 1e3; /* from nano to micro */
+ engines->rapl.config = rapl_gpu_power();
+ engines->rapl_fd = igt_perf_open(rapl_type_id(), engines->rapl.config);
+ if (engines->rapl_fd < 0)
+ return -1;
+
+ return 0;
+}
+
+static uint64_t pmu_read_multi(int fd, unsigned int num, uint64_t *val)
+{
+ uint64_t buf[2 + num];
+ unsigned int i;
+
+ assert(read(fd, buf, sizeof(buf)) == sizeof(buf));
+
+ for (i = 0; i < num; i++)
+ val[i] = buf[2 + i];
+
+ return buf[1];
+}
+
+
+static double pmu_calc(struct pmu_pair *p, double d, double t, double s)
+{
+ double pct;
+
+ pct = p->cur - p->prev;
+ pct /= d;
+ pct /= t;
+ pct *= s;
+
+ if (s == 100.0 && pct > 100.0)
+ pct = 100.0;
+
+ return pct;
+}
+
+static uint64_t __pmu_read_single(int fd, uint64_t *ts)
+{
+ uint64_t data[2];
+
+ assert(read(fd, data, sizeof(data)) == sizeof(data));
+
+ if (ts)
+ *ts = data[1];
+
+ return data[0];
+}
+
+static uint64_t pmu_read_single(int fd)
+{
+ return __pmu_read_single(fd, NULL);
+}
+
+static void __update_sample(struct pmu_counter *counter, uint64_t val)
+{
+ counter->val.prev = counter->val.cur;
+ counter->val.cur = val;
+}
+
+static void update_sample(struct pmu_counter *counter, uint64_t *val)
+{
+ __update_sample(counter, val[counter->idx]);
+}
+
+static void pmu_sample(struct engines *engines)
+{
+ const int num_val = engines->num_counters;
+ uint64_t val[num_val];
+ unsigned int i;
+
+ engines->ts.prev = engines->ts.cur;
+ engines->ts.cur = pmu_read_multi(engines->fd, num_val, val);
+
+ __update_sample(&engines->rapl, pmu_read_single(engines->rapl_fd));
+
+ update_sample(&engines->freq_req, val);
+ update_sample(&engines->freq_act, val);
+ update_sample(&engines->irq, val);
+ update_sample(&engines->rc6, val);
+
+ for (i = 0; i < engines->num_engines; i++) {
+ struct engine *engine = engine_ptr(engines, i);
+
+ update_sample(&engine->busy, val);
+ update_sample(&engine->sema, val);
+ update_sample(&engine->wait, val);
+ update_sample(&engine->queued, val);
+ update_sample(&engine->runnable, val);
+ update_sample(&engine->running, val);
+ }
+}
+
+static const char *bars[] = { " ", "▏", "▎", "▍", "▌", "▋", "▊", "▉", "█" };
+
+static void
+print_percentage_bar(double percent, int max_len)
+{
+ int bar_len = percent * (8 * (max_len - 2)) / 100.0;
+ int i;
+
+ putchar('|');
+
+ for (i = bar_len; i >= 8; i -= 8)
+ printf("%s", bars[8]);
+ if (i)
+ printf("%s", bars[i]);
+
+ for (i = 0; i < (max_len - 2 - (bar_len + 7) / 8); i++)
+ putchar(' ');
+
+ putchar('|');
+}
+
+#define DEFAULT_PERIOD_MS (1000)
+
+static void
+usage(const char *appname)
+{
+ printf("intel_gpu_top - Display a top-like summary of Intel GPU usage\n"
+ "\n"
+ "Usage: %s [parameters]\n"
+ "\n"
+ "\tThe following parameters are optional:\n"
+ "\t[-s <samples>] refresh period in ms (default %ums)\n"
+ "\t[-h] show this help text\n"
+ "\n",
+ appname, DEFAULT_PERIOD_MS);
+}
+
+static double update_load(double load, double exp, double val)
+{
+ return val + exp * (load - val);
+}
+
+int main(int argc, char **argv)
+{
+ unsigned int period_us = DEFAULT_PERIOD_MS * 1000;
+ const double load_period[NUM_LOADS] = { 1.0, 30.0, 900.0 };
+ struct engines *engines;
+ int con_w = -1, con_h = -1;
+ struct winsize ws;
+ unsigned int i;
+ double period;
+ int ret, ch;
+
+ /* Parse options */
+ while ((ch = getopt(argc, argv, "s:h")) != -1) {
+ switch (ch) {
+ case 's':
+ period_us = atoi(optarg) * 1000;
+ break;
+ case 'h':
+ usage(argv[0]);
+ exit(0);
+ default:
+ fprintf(stderr, "Invalid option %c!\n", (char)optopt);
+ usage(argv[0]);
+ exit(1);
+ }
+ }
+
+ /* Get terminal size. */
+ if (ioctl(0, TIOCGWINSZ, &ws) != -1) {
+ con_w = ws.ws_col;
+ con_h = ws.ws_row;
+ }
+
+ engines = discover_engines();
+ if (!engines) {
+ fprintf(stderr, "Failed to detect engines!\n");
+ return 1;
+ }
+
+ ret = pmu_init(engines);
+ if (ret) {
+ fprintf(stderr, "Failed to initialize PMU!\n");
+ return 1;
+ }
+
+ /* Load average setup. */
+ period = (double)period_us / 1e6;
+ for (i = 0; i < NUM_LOADS; i++)
+ engines->load_exp[i] = exp(-period / load_period[i]);
+
+ pmu_sample(engines);
+
+ for (;;) {
+ double t, freq[2], irq, rc6, power;
+ double qd = 0;
+ int lines = 0;
+ unsigned int j;
+
+ usleep(period_us);
+
+ pmu_sample(engines);
+ t = (double)(engines->ts.cur - engines->ts.prev) / 1e9;
+
+ printf("\033[H\033[J");
+
+ freq[0] = pmu_calc(&engines->freq_req.val, 1.0, t, 1);
+ freq[1] = pmu_calc(&engines->freq_act.val, 1.0, t, 1);
+ irq = pmu_calc(&engines->irq.val, 1.0, t, 1);
+ rc6 = pmu_calc(&engines->rc6.val, 1e9, t, 100);
+ power = pmu_calc(&engines->rapl.val, 1.0, t, engines->rapl_scale);
+
+ for (i = 0; i < engines->num_engines; i++) {
+ struct engine *engine = engine_ptr(engines, i);
+
+ engine->qd[0] = pmu_calc(&engine->queued.val, 1, t,
+ engines->qd_scale);
+ engine->qd[1] = pmu_calc(&engine->runnable.val, 1, t,
+ engines->qd_scale);
+ engine->qd[2] = pmu_calc(&engine->running.val, 1, t,
+ engines->qd_scale);
+
+ qd += engine->qd[1] + engine->qd[2];
+
+ for (j = 0; j < NUM_LOADS; j++) {
+ engine->load_avg[j] =
+ update_load(engine->load_avg[j],
+ engines->load_exp[j],
+ engine->qd[1] +
+ engine->qd[2]);
+ }
+ }
+
+ for (j = 0; j < NUM_LOADS; j++) {
+ engines->load_avg[j] =
+ update_load(engines->load_avg[j],
+ engines->load_exp[j],
+ qd);
+ }
+
+ printf("intel-gpu-top - load avg %5.2f, %5.2f, %5.2f; %4.0f/%4.0f MHz; %3.0f%% RC6; %6.0fmW; %8.0f irqs/s\n",
+ engines->load_avg[0],
+ engines->load_avg[1],
+ engines->load_avg[2],
+ freq[0], freq[1],
+ rc6, power, irq);
+ lines++;
+
+ printf("\n");
+ lines++;
+
+ for (i = 0; i < engines->num_engines && lines < con_h; i++) {
+ struct engine *engine = engine_ptr(engines, i);
+ unsigned int max_w = con_w - 1;
+ unsigned int len;
+ double val[2];
+ char buf[128];
+
+ val[0] = pmu_calc(&engine->wait.val, 1e9, t, 100);
+ val[1] = pmu_calc(&engine->sema.val, 1e9, t, 100);
+ len = snprintf(buf, sizeof(buf),
+ "%6.2f%% wait, %6.2f%% sema",
+ val[0], val[1]);
+
+ val[0] = pmu_calc(&engine->busy.val, 1e9, t, 100);
+ len += printf("%8s %6.2f%% (%5.2f/%5.2f/%5.2f) ",
+ engine->name,
+ val[0],
+ engine->qd[0],
+ engine->qd[1],
+ engine->qd[2]);
+ print_percentage_bar(val[0], max_w - len);
+
+ printf("%s\n", buf);
+
+ lines++;
+ }
+
+ printf("\n");
+ }
+
+ return 0;
+}
diff --git a/tools/meson.build b/tools/meson.build
index ebce4e305d00..36038f7a9d22 100644
--- a/tools/meson.build
+++ b/tools/meson.build
@@ -23,6 +23,7 @@ tools_progs = [
'intel_gpu_frequency',
'intel_firmware_decode',
'intel_gpu_time',
+ 'intel_gpu-top',
'intel_legacy_top',
'intel_gtt',
'intel_guc_logger',
--
2.14.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [RFC i-g-t 3/3] intel-gpu-top: Support for client stats
2018-02-14 18:52 [RFC i-g-t 0/3] New intel-gpu-top Tvrtko Ursulin
2018-02-14 18:52 ` [RFC i-g-t 1/3] intel-gpu-top: Rename to intel-legacy-top Tvrtko Ursulin
2018-02-14 18:52 ` [RFC i-g-t 2/3] intel-gpu-top: New version using PMU Tvrtko Ursulin
@ 2018-02-14 18:52 ` Tvrtko Ursulin
2018-02-14 19:30 ` ✓ Fi.CI.BAT: success for New intel-gpu-top Patchwork
3 siblings, 0 replies; 9+ messages in thread
From: Tvrtko Ursulin @ 2018-02-14 18:52 UTC (permalink / raw)
To: Intel-gfx
From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
tools/intel_gpu_top.c | 268 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 263 insertions(+), 5 deletions(-)
diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c
index 59a112240092..63f0c1941258 100644
--- a/tools/intel_gpu_top.c
+++ b/tools/intel_gpu_top.c
@@ -407,8 +407,222 @@ static void pmu_sample(struct engines *engines)
}
}
+enum client_status {
+ FREE = 0, /* mbz */
+ ALIVE,
+ PROBE
+};
+
+struct client {
+ enum client_status status;
+ unsigned int id;
+ unsigned int pid;
+ char name[128];
+ unsigned int samples;
+ unsigned long total;
+ struct engines *engines;
+ unsigned long *val;
+ uint64_t *last;
+};
+
+#define SYSFS_ENABLE "/sys/class/drm/card0/clients/enable_stats"
+#define SYSFS_CLIENTS "/sys/class/drm/card0/clients/"
+
+#define PERIOD_US (1000e3)
+
+static struct client *clients;
+static unsigned int num_clients;
+
+#define for_each_client(c, tmp) \
+ for (tmp = num_clients, c = clients; tmp > 0; tmp--, c++)
+
+static uint64_t read_client_busy(unsigned int id, const char *engine)
+{
+ char buf[256];
+ ssize_t ret;
+
+ ret = snprintf(buf, sizeof(buf), SYSFS_CLIENTS "/%u/busy/%s",
+ id, engine);
+ assert(ret > 0);
+
+ return filename_to_u64(buf, 10);
+}
+
+static struct client *find_client(enum client_status status, unsigned int id)
+{
+ struct client *c;
+ unsigned int tmp;
+
+ for_each_client(c, tmp) {
+ if ((status == FREE && c->status == FREE) ||
+ (status == c->status && c->id == id)) {
+ return c;
+ }
+ }
+
+ return NULL;
+}
+
+static void update_client(struct client *c, unsigned int pid, char *name)
+{
+ uint64_t val[c->engines->num_engines];
+ unsigned int i;
+
+ if (c->pid != pid)
+ c->pid = pid;
+
+ if (strncmp(c->name, name, sizeof(c->name)))
+ strncpy(c->name, name, sizeof(c->name));
+
+ for (i = 0; i < c->engines->num_engines; i++) {
+ struct engine *engine = engine_ptr(c->engines, i);
+
+ val[i] = read_client_busy(c->id, engine->name);
+ }
+
+ c->total = 0;
+
+ for (i = 0; i < c->engines->num_engines; i++) {
+ assert(val[i] >= c->last[i]);
+ c->val[i] = val[i] - c->last[i];
+ c->total += c->val[i];
+ c->last[i] = val[i];
+ }
+
+ c->samples++;
+ c->status = ALIVE;
+}
+
+static void
+add_client(unsigned int id, unsigned int pid, char *name,
+ struct engines *engines)
+{
+ struct client *c;
+
+ assert(!find_client(ALIVE, id));
+
+ c = find_client(FREE, 0);
+ if (!c) {
+ unsigned int idx = num_clients;
+
+ num_clients += (num_clients + 2) / 2;
+ clients = realloc(clients, num_clients * sizeof(*c));
+ assert(clients);
+ c = &clients[idx];
+ memset(c, 0, (num_clients - idx) * sizeof(*c));
+ }
+
+ c->id = id;
+ c->engines = engines;
+ c->val = calloc(engines->num_engines, sizeof(c->val));
+ c->last = calloc(engines->num_engines, sizeof(c->last));
+ assert(c->val && c->last);
+
+ update_client(c, pid, name);
+
+// c = find_client(c->status, c->id);
+}
+
+static void free_client(struct client *c)
+{
+ free(c->val);
+ free(c->last);
+ memset(c, 0, sizeof(*c));
+}
+
+static char *read_client_sysfs(unsigned int id, const char *field)
+{
+ char buf[256];
+ ssize_t ret;
+
+ ret = snprintf(buf, sizeof(buf), SYSFS_CLIENTS "/%u/%s", id, field);
+ assert(ret > 0);
+
+ ret = filename_to_buf(buf, buf, sizeof(buf));
+ assert(ret == 0);
+
+ return strdup(buf);
+}
+
+static void scan(struct engines *engines)
+{
+ struct dirent *dent;
+ struct client *c;
+ char *pid, *name;
+ unsigned int tmp;
+ unsigned int id;
+ DIR *d;
+
+ for_each_client(c, tmp) {
+ if (c->status == ALIVE)
+ c->status = PROBE;
+ }
+
+ d = opendir(SYSFS_CLIENTS);
+ assert(!NULL);
+
+ while ((dent = readdir(d)) != NULL) {
+ if (dent->d_type != DT_DIR)
+ continue;
+ if (!isdigit(dent->d_name[0]))
+ continue;
+
+ id = atoi(dent->d_name);
+
+ name = read_client_sysfs(id, "name");
+ assert(name);
+
+ pid = read_client_sysfs(id, "pid");
+ assert(pid);
+
+ c = find_client(PROBE, id);
+ if (c) {
+ update_client(c, atoi(pid), name);
+ continue;
+ }
+
+ add_client(id, atoi(pid), name, engines);
+
+ free(name);
+ free(pid);
+ }
+
+ closedir(d);
+
+ for_each_client(c, tmp) {
+ if (c->status == PROBE)
+ free_client(c);
+ }
+}
+
+static int cmp(const void *_a, const void *_b)
+{
+ const struct client *a = _a;
+ const struct client *b = _b;
+ long tot_a = a->total;
+ long tot_b = b->total;
+
+ if (a->status != ALIVE || a->samples < 2)
+ tot_a = -1;
+ if (b->status != ALIVE || b->samples < 2)
+ tot_b = -1;
+
+ if (tot_a == tot_b)
+ return a->pid - b->pid;
+ else
+ return -(tot_a - tot_b);
+}
+
static const char *bars[] = { " ", "▏", "▎", "▍", "▌", "▋", "▊", "▉", "█" };
+static void n_spaces(const unsigned int n)
+{
+ unsigned int i;
+
+ for (i = 0; i < n; i++)
+ putchar(' ');
+}
+
static void
print_percentage_bar(double percent, int max_len)
{
@@ -422,8 +636,7 @@ print_percentage_bar(double percent, int max_len)
if (i)
printf("%s", bars[i]);
- for (i = 0; i < (max_len - 2 - (bar_len + 7) / 8); i++)
- putchar(' ');
+ n_spaces(max_len - 2 - (bar_len + 7) / 8);
putchar('|');
}
@@ -500,16 +713,21 @@ int main(int argc, char **argv)
engines->load_exp[i] = exp(-period / load_period[i]);
pmu_sample(engines);
+ scan(engines);
for (;;) {
double t, freq[2], irq, rc6, power;
double qd = 0;
int lines = 0;
+ struct client *c;
+ unsigned int len, engine_w;
unsigned int j;
usleep(period_us);
pmu_sample(engines);
+ scan(engines);
+
t = (double)(engines->ts.cur - engines->ts.prev) / 1e9;
printf("\033[H\033[J");
@@ -561,8 +779,6 @@ int main(int argc, char **argv)
for (i = 0; i < engines->num_engines && lines < con_h; i++) {
struct engine *engine = engine_ptr(engines, i);
- unsigned int max_w = con_w - 1;
- unsigned int len;
double val[2];
char buf[128];
@@ -579,7 +795,7 @@ int main(int argc, char **argv)
engine->qd[0],
engine->qd[1],
engine->qd[2]);
- print_percentage_bar(val[0], max_w - len);
+ print_percentage_bar(val[0], con_w - 1 - len);
printf("%s\n", buf);
@@ -587,6 +803,48 @@ int main(int argc, char **argv)
}
printf("\n");
+
+ printf("\033[7m");
+ len = printf("%5s%16s", "PID", "NAME");
+ engine_w = (con_w - len) / engines->num_engines;
+ for (i = 0; i < engines->num_engines && lines < con_h; i++) {
+ struct engine *engine = engine_ptr(engines, i);
+ unsigned int pad = (engine_w - strlen(engine->name)) / 2;
+
+ n_spaces(pad);
+ printf("%s", engine->name);
+ n_spaces(engine_w - pad - strlen(engine->name));
+ len += pad + strlen(engine->name) +
+ (engine_w - pad - strlen(engine->name));
+ }
+ n_spaces(con_w - len);
+ printf("\033[0m\n");
+ lines++;
+
+ qsort(clients, num_clients, sizeof(*c), cmp);
+
+ for_each_client(c, i) {
+ if (lines > con_h)
+ break;
+
+ assert(c->status != PROBE);
+ if (c->status != ALIVE || c->samples < 2)
+ break;
+
+ printf("%5u%16s ", c->pid, c->name);
+
+ for (i = 0; i < engines->num_engines; i++) {
+ double pct;
+
+ pct = (double)c->val[i] / period_us / 1e3 * 100;
+
+ print_percentage_bar(pct, engine_w);
+ }
+
+ putchar('\n');
+ lines++;
+ }
+
}
return 0;
--
2.14.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 9+ messages in thread
* ✓ Fi.CI.BAT: success for New intel-gpu-top
2018-02-14 18:52 [RFC i-g-t 0/3] New intel-gpu-top Tvrtko Ursulin
` (2 preceding siblings ...)
2018-02-14 18:52 ` [RFC i-g-t 3/3] intel-gpu-top: Support for client stats Tvrtko Ursulin
@ 2018-02-14 19:30 ` Patchwork
3 siblings, 0 replies; 9+ messages in thread
From: Patchwork @ 2018-02-14 19:30 UTC (permalink / raw)
To: Tvrtko Ursulin; +Cc: intel-gfx
== Series Details ==
Series: New intel-gpu-top
URL : https://patchwork.freedesktop.org/series/38282/
State : success
== Summary ==
IGT patchset tested on top of latest successful build
1d227a47223d2ff5c6745c0d82e96e70d456d5de lib/kms: Clear unused fields for getproperty ioctl
with latest DRM-Tip kernel build CI_DRM_3774
5ad7866768dc drm-tip: 2018y-02m-14d-15h-14m-50s UTC integration manifest
No testlist changes.
fi-bdw-5557u total:288 pass:267 dwarn:0 dfail:0 fail:0 skip:21 time:421s
fi-bdw-gvtdvm total:288 pass:264 dwarn:0 dfail:0 fail:0 skip:24 time:426s
fi-blb-e6850 total:288 pass:223 dwarn:1 dfail:0 fail:0 skip:64 time:377s
fi-bsw-n3050 total:288 pass:242 dwarn:0 dfail:0 fail:0 skip:46 time:489s
fi-bwr-2160 total:288 pass:183 dwarn:0 dfail:0 fail:0 skip:105 time:290s
fi-bxt-dsi total:288 pass:258 dwarn:0 dfail:0 fail:0 skip:30 time:483s
fi-bxt-j4205 total:288 pass:259 dwarn:0 dfail:0 fail:0 skip:29 time:489s
fi-byt-j1900 total:288 pass:253 dwarn:0 dfail:0 fail:0 skip:35 time:473s
fi-byt-n2820 total:288 pass:249 dwarn:0 dfail:0 fail:0 skip:39 time:459s
fi-cfl-s2 total:288 pass:262 dwarn:0 dfail:0 fail:0 skip:26 time:567s
fi-cnl-y3 total:288 pass:262 dwarn:0 dfail:0 fail:0 skip:26 time:578s
fi-elk-e7500 total:288 pass:229 dwarn:0 dfail:0 fail:0 skip:59 time:426s
fi-gdg-551 total:288 pass:179 dwarn:0 dfail:0 fail:1 skip:108 time:284s
fi-glk-1 total:288 pass:260 dwarn:0 dfail:0 fail:0 skip:28 time:512s
fi-hsw-4770 total:288 pass:261 dwarn:0 dfail:0 fail:0 skip:27 time:391s
fi-ilk-650 total:288 pass:228 dwarn:0 dfail:0 fail:0 skip:60 time:413s
fi-ivb-3520m total:288 pass:259 dwarn:0 dfail:0 fail:0 skip:29 time:463s
fi-ivb-3770 total:288 pass:255 dwarn:0 dfail:0 fail:0 skip:33 time:420s
fi-kbl-7500u total:288 pass:263 dwarn:1 dfail:0 fail:0 skip:24 time:467s
fi-kbl-7560u total:288 pass:269 dwarn:0 dfail:0 fail:0 skip:19 time:498s
fi-kbl-r total:288 pass:261 dwarn:0 dfail:0 fail:0 skip:27 time:501s
fi-pnv-d510 total:288 pass:222 dwarn:1 dfail:0 fail:0 skip:65 time:591s
fi-skl-6260u total:288 pass:268 dwarn:0 dfail:0 fail:0 skip:20 time:424s
fi-skl-6600u total:288 pass:261 dwarn:0 dfail:0 fail:0 skip:27 time:510s
fi-skl-6700hq total:288 pass:262 dwarn:0 dfail:0 fail:0 skip:26 time:525s
fi-skl-6700k2 total:288 pass:264 dwarn:0 dfail:0 fail:0 skip:24 time:497s
fi-skl-6770hq total:288 pass:268 dwarn:0 dfail:0 fail:0 skip:20 time:475s
fi-skl-guc total:288 pass:260 dwarn:0 dfail:0 fail:0 skip:28 time:414s
fi-skl-gvtdvm total:288 pass:265 dwarn:0 dfail:0 fail:0 skip:23 time:433s
fi-snb-2520m total:288 pass:248 dwarn:0 dfail:0 fail:0 skip:40 time:541s
fi-snb-2600 total:288 pass:248 dwarn:0 dfail:0 fail:0 skip:40 time:398s
Blacklisted hosts:
fi-glk-dsi total:288 pass:258 dwarn:0 dfail:0 fail:0 skip:30 time:470s
fi-kbl-7567u total:288 pass:268 dwarn:0 dfail:0 fail:0 skip:20 time:457s
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_915/issues.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFC i-g-t 1/3] intel-gpu-top: Rename to intel-legacy-top
2018-02-14 18:52 ` [RFC i-g-t 1/3] intel-gpu-top: Rename to intel-legacy-top Tvrtko Ursulin
@ 2018-02-15 9:10 ` Petri Latvala
2018-02-15 9:17 ` Chris Wilson
2018-02-15 9:57 ` Tvrtko Ursulin
0 siblings, 2 replies; 9+ messages in thread
From: Petri Latvala @ 2018-02-15 9:10 UTC (permalink / raw)
To: Tvrtko Ursulin; +Cc: Intel-gfx
On Wed, Feb 14, 2018 at 06:52:05PM +0000, Tvrtko Ursulin wrote:
> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>
> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> ---
> tools/.gitignore | 2 +-
> tools/Makefile.sources | 2 +-
> tools/{intel_gpu_top.c => intel_legacy_top.c} | 0
> tools/meson.build | 2 +-
> 4 files changed, 3 insertions(+), 3 deletions(-)
> rename tools/{intel_gpu_top.c => intel_legacy_top.c} (100%)
If the old tool is to be kept, the name intel_legacy_top doesn't quite
capture what it does. A more important topic though is whether it
should be kept at all. What are the features in the old tool that your
rewrite doesn't have?
--
Petri Latvala
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFC i-g-t 1/3] intel-gpu-top: Rename to intel-legacy-top
2018-02-15 9:10 ` Petri Latvala
@ 2018-02-15 9:17 ` Chris Wilson
2018-02-15 9:57 ` Tvrtko Ursulin
1 sibling, 0 replies; 9+ messages in thread
From: Chris Wilson @ 2018-02-15 9:17 UTC (permalink / raw)
To: Petri Latvala, Tvrtko Ursulin; +Cc: Intel-gfx
Quoting Petri Latvala (2018-02-15 09:10:45)
> On Wed, Feb 14, 2018 at 06:52:05PM +0000, Tvrtko Ursulin wrote:
> > From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> >
> > Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> > ---
> > tools/.gitignore | 2 +-
> > tools/Makefile.sources | 2 +-
> > tools/{intel_gpu_top.c => intel_legacy_top.c} | 0
> > tools/meson.build | 2 +-
> > 4 files changed, 3 insertions(+), 3 deletions(-)
> > rename tools/{intel_gpu_top.c => intel_legacy_top.c} (100%)
>
>
> If the old tool is to be kept,
No. The old tool should be removed as it is a machine killer.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFC i-g-t 1/3] intel-gpu-top: Rename to intel-legacy-top
2018-02-15 9:10 ` Petri Latvala
2018-02-15 9:17 ` Chris Wilson
@ 2018-02-15 9:57 ` Tvrtko Ursulin
2018-02-15 10:05 ` Chris Wilson
1 sibling, 1 reply; 9+ messages in thread
From: Tvrtko Ursulin @ 2018-02-15 9:57 UTC (permalink / raw)
To: Tvrtko Ursulin, Intel-gfx
On 15/02/2018 09:10, Petri Latvala wrote:
> On Wed, Feb 14, 2018 at 06:52:05PM +0000, Tvrtko Ursulin wrote:
>> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>>
>> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>> ---
>> tools/.gitignore | 2 +-
>> tools/Makefile.sources | 2 +-
>> tools/{intel_gpu_top.c => intel_legacy_top.c} | 0
>> tools/meson.build | 2 +-
>> 4 files changed, 3 insertions(+), 3 deletions(-)
>> rename tools/{intel_gpu_top.c => intel_legacy_top.c} (100%)
>
>
> If the old tool is to be kept, the name intel_legacy_top doesn't quite
> capture what it does. A more important topic though is whether it
> should be kept at all. What are the features in the old tool that your
> rewrite doesn't have?
It's a bit different in target audience and capabilities I think.
The current one exposes what OA is, I assume at least, able to provide
today in a safe way. The new tool doesn't do any of that but just
provides basic, more end-user friendly, engine busyness and related stats.
It may be that when considering gpu-top work, intel-gpu-top rewrite
hasn't even got a place. Or it might have as a minimal, easy to use and
simple tool. TBD.
On 15/02/2018 09:17, Chris Wilson wrote:
> Quoting Petri Latvala (2018-02-15 09:10:45)
>>
>> If the old tool is to be kept,
>
> No. The old tool should be removed as it is a machine killer.
And it is not up to date with current hardware so no complaints from me.
Regards,
Tvrtko
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFC i-g-t 1/3] intel-gpu-top: Rename to intel-legacy-top
2018-02-15 9:57 ` Tvrtko Ursulin
@ 2018-02-15 10:05 ` Chris Wilson
0 siblings, 0 replies; 9+ messages in thread
From: Chris Wilson @ 2018-02-15 10:05 UTC (permalink / raw)
To: Tvrtko Ursulin, Tvrtko Ursulin, Intel-gfx
Quoting Tvrtko Ursulin (2018-02-15 09:57:45)
>
> On 15/02/2018 09:10, Petri Latvala wrote:
> > On Wed, Feb 14, 2018 at 06:52:05PM +0000, Tvrtko Ursulin wrote:
> >> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> >>
> >> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> >> ---
> >> tools/.gitignore | 2 +-
> >> tools/Makefile.sources | 2 +-
> >> tools/{intel_gpu_top.c => intel_legacy_top.c} | 0
> >> tools/meson.build | 2 +-
> >> 4 files changed, 3 insertions(+), 3 deletions(-)
> >> rename tools/{intel_gpu_top.c => intel_legacy_top.c} (100%)
> >
> >
> > If the old tool is to be kept, the name intel_legacy_top doesn't quite
> > capture what it does. A more important topic though is whether it
> > should be kept at all. What are the features in the old tool that your
> > rewrite doesn't have?
>
> It's a bit different in target audience and capabilities I think.
>
> The current one exposes what OA is, I assume at least, able to provide
> today in a safe way. The new tool doesn't do any of that but just
> provides basic, more end-user friendly, engine busyness and related stats.
>
> It may be that when considering gpu-top work, intel-gpu-top rewrite
> hasn't even got a place. Or it might have as a minimal, easy to use and
> simple tool. TBD.
I liken it to classic "top", even when we have graphical system
monitors, for a quick assay of what's running, top is unbeatable.
I think each tool has its use. There may be future refactoring to a
single tool with different interfaces, but for now it looks to be a nice
little demonstration vehicle with some practical value.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2018-02-15 10:05 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-02-14 18:52 [RFC i-g-t 0/3] New intel-gpu-top Tvrtko Ursulin
2018-02-14 18:52 ` [RFC i-g-t 1/3] intel-gpu-top: Rename to intel-legacy-top Tvrtko Ursulin
2018-02-15 9:10 ` Petri Latvala
2018-02-15 9:17 ` Chris Wilson
2018-02-15 9:57 ` Tvrtko Ursulin
2018-02-15 10:05 ` Chris Wilson
2018-02-14 18:52 ` [RFC i-g-t 2/3] intel-gpu-top: New version using PMU Tvrtko Ursulin
2018-02-14 18:52 ` [RFC i-g-t 3/3] intel-gpu-top: Support for client stats Tvrtko Ursulin
2018-02-14 19:30 ` ✓ Fi.CI.BAT: success for New intel-gpu-top Patchwork
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox