[Intel-gfx] [PATCH i-g-t 11/12] tools/intel_gpu_top: Add per client memory info
From: Tvrtko Ursulin JSON output has the full breakdown but for now the interactive mode only shows total and resident aggregated for all memory regions. Signed-off-by: Tvrtko Ursulin --- tools/intel_gpu_top.c | 114 +- 1 file changed, 112 insertions(+), 2 deletions(-) diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c index 4b9ef306ca8e..958df42e8c20 100644 --- a/tools/intel_gpu_top.c +++ b/tools/intel_gpu_top.c @@ -133,11 +133,24 @@ struct intel_clients { const char *pci_slot; struct igt_drm_client_engines classes; struct igt_drm_clients *clients; + struct igt_drm_client_regions *regions; /* Borrowed from first client */ }; static struct termios termios_orig; static bool class_view; +/* Maps i915 fdinfo names to indices */ +static const char *memory_region_map[] = { + "system0", + "local0", +}; + +/* For JSON, 1:1 with indices above. */ +static const char *json_memory_region_names[] = { + "system", + "local", +}; + __attribute__((format(scanf,3,4))) static int igt_sysfs_scanf(int dir, const char *attr, const char *fmt, ...) { @@ -880,6 +893,9 @@ static struct igt_drm_clients *display_clients(struct igt_drm_clients *clients) ac->val = calloc(c->engines->max_engine_id + 1, sizeof(ac->val[0])); assert(ac->val); + ac->regions = c->regions; + ac->memory = calloc(c->regions->max_region_id + 1, + sizeof(ac->memory[0])); ac->samples = 1; } @@ -894,6 +910,14 @@ static struct igt_drm_clients *display_clients(struct igt_drm_clients *clients) for (i = 0; i <= c->engines->max_engine_id; i++) ac->val[i] += c->val[i]; + + for (i = 0; i <= c->regions->max_region_id; i++) { + ac->memory[i].total += c->memory[i].total; + ac->memory[i].shared += c->memory[i].shared; + ac->memory[i].resident += c->memory[i].resident; + ac->memory[i].purgeable += c->memory[i].purgeable; + ac->memory[i].active += c->memory[i].active; + } } aggregated->num_clients = num; @@ -918,8 +942,10 @@ static void free_display_clients(struct igt_drm_clients *clients) * "display" clients are not proper clients and have un-initialized * or borrowed fields which we don't want the library to try and free. */ - igt_for_each_drm_client(clients, c, tmp) + igt_for_each_drm_client(clients, c, tmp) { free(c->val); + free(c->memory); + } free(clients->client); free(clients); @@ -2012,6 +2038,9 @@ print_clients_header(struct igt_drm_clients *clients, int lines, if (lines++ >= con_h || len >= con_w) return lines; + if (iclients->regions) + len += printf(" MEM RSS "); + if (iclients->classes.num_engines) { unsigned int i; int width; @@ -2055,6 +2084,20 @@ print_clients_header(struct igt_drm_clients *clients, int lines, static bool numeric_clients; static bool filter_idle; +static int print_size(uint64_t sz) +{ + char units[] = { ' ', 'K', 'M', 'G' }; + unsigned int u; + + for (u = 0; u < ARRAY_SIZE(units) - 1; u++) { + if (sz & 1023 || sz < 1024) + break; + sz /= 1024; + } + + return printf("%7"PRIu64"%c ", sz, units[u]); +} + static int print_client(struct igt_drm_client *c, struct engines *engines, double t, int lines, int con_w, int con_h, unsigned int period_us, int *class_w) @@ -2072,6 +2115,18 @@ print_client(struct igt_drm_client *c, struct engines *engines, double t, int li len = printf("%*s ", clients->max_pid_len, c->pid_str); + if (iclients->regions) { + uint64_t sz; + + for (sz = 0, i = 0; i <= c->regions->max_region_id; i++) + sz += c->memory[i].total; + len += print_size(sz); + + for (sz = 0, i = 0; i <= c->regions->max_region_id; i++) + sz += c->memory[i].resident; + len += print_size(sz); + } + for (i = 0; i <= iclients->classes.max_engine_id; i++) { double pct, max; @@ -2111,6 +2166,42 @@ print_client(struct igt_drm_client *c, struct engines *engines, double t, int li snprintf(buf, sizeof(buf), "%u", c->pid); __json_add_member("pid", buf); + if (iclients->regions) { +
[Intel-gfx] [PATCH i-g-t 11/12] tools/intel_gpu_top: Add per client memory info
From: Tvrtko Ursulin JSON output has the full breakdown but for now the interactive mode only shows total and resident aggregated for all memory regions. Signed-off-by: Tvrtko Ursulin --- tools/intel_gpu_top.c | 114 +- 1 file changed, 112 insertions(+), 2 deletions(-) diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c index 27503ac03ebd..c239a0d4f350 100644 --- a/tools/intel_gpu_top.c +++ b/tools/intel_gpu_top.c @@ -133,11 +133,24 @@ struct intel_clients { const char *pci_slot; struct igt_drm_client_engines classes; struct igt_drm_clients *clients; + struct igt_drm_client_regions *regions; /* Borrowed from first client */ }; static struct termios termios_orig; static bool class_view; +/* Maps i915 fdinfo names to indices */ +static const char *memory_region_map[] = { + "system0", + "local0", +}; + +/* For JSON, 1:1 with indices above. */ +static const char *json_memory_region_names[] = { + "system", + "local", +}; + __attribute__((format(scanf,3,4))) static int igt_sysfs_scanf(int dir, const char *attr, const char *fmt, ...) { @@ -884,6 +897,9 @@ static struct igt_drm_clients *display_clients(struct igt_drm_clients *clients) ac->val = calloc(c->engines->max_engine_id + 1, sizeof(ac->val[0])); assert(ac->val); + ac->regions = c->regions; + ac->memory = calloc(c->regions->max_region_id + 1, + sizeof(ac->memory[0])); ac->samples = 1; } @@ -898,6 +914,14 @@ static struct igt_drm_clients *display_clients(struct igt_drm_clients *clients) for (i = 0; i <= c->engines->max_engine_id; i++) ac->val[i] += c->val[i]; + + for (i = 0; i <= c->regions->max_region_id; i++) { + ac->memory[i].total += c->memory[i].total; + ac->memory[i].shared += c->memory[i].shared; + ac->memory[i].resident += c->memory[i].resident; + ac->memory[i].purgeable += c->memory[i].purgeable; + ac->memory[i].active += c->memory[i].active; + } } aggregated->num_clients = num; @@ -922,8 +946,10 @@ static void free_display_clients(struct igt_drm_clients *clients) * "display" clients are not proper clients and have un-initialized * or borrowed fields which we don't want the library to try and free. */ - igt_for_each_drm_client(clients, c, tmp) + igt_for_each_drm_client(clients, c, tmp) { free(c->val); + free(c->memory); + } free(clients->client); free(clients); @@ -2016,6 +2042,9 @@ print_clients_header(struct igt_drm_clients *clients, int lines, if (lines++ >= con_h || len >= con_w) return lines; + if (iclients->regions) + len += printf(" MEM RSS "); + if (iclients->classes.num_engines) { unsigned int i; int width; @@ -2059,6 +2088,20 @@ print_clients_header(struct igt_drm_clients *clients, int lines, static bool numeric_clients; static bool filter_idle; +static int print_size(uint64_t sz) +{ + char units[] = { ' ', 'K', 'M', 'G' }; + unsigned int u; + + for (u = 0; u < ARRAY_SIZE(units) - 1; u++) { + if (sz & 1023 || sz < 1024) + break; + sz /= 1024; + } + + return printf("%7"PRIu64"%c ", sz, units[u]); +} + static int print_client(struct igt_drm_client *c, struct engines *engines, double t, int lines, int con_w, int con_h, unsigned int period_us, int *class_w) @@ -2076,6 +2119,18 @@ print_client(struct igt_drm_client *c, struct engines *engines, double t, int li len = printf("%*s ", clients->max_pid_len, c->pid_str); + if (iclients->regions) { + uint64_t sz; + + for (sz = 0, i = 0; i <= c->regions->max_region_id; i++) + sz += c->memory[i].total; + len += print_size(sz); + + for (sz = 0, i = 0; i <= c->regions->max_region_id; i++) + sz += c->memory[i].resident; + len += print_size(sz); + } + for (i = 0; i <= iclients->classes.max_engine_id; i++) { double pct, max; @@ -2115,6 +2170,42 @@ print_client(struct igt_drm_client *c, struct engines *engines, double t, int li snprintf(buf, sizeof(buf), "%u", c->pid); __json_add_member("pid", buf); + if (iclients->regions) { +