[igt-dev] [PATCH i-g-t 8/9] tools/intel_gpu_top: Add per client memory info
Kamil Konieczny
kamil.konieczny at linux.intel.com
Fri Nov 3 19:01:44 UTC 2023
Hi Tvrtko,
On 2023-10-12 at 09:15:46 +0100, Tvrtko Ursulin wrote:
> From: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
>
> 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 <tvrtko.ursulin at intel.com>
Reviewed-by: Kamil Konieczny <kamil.konieczny at linux.intel.com>
> ---
> 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 b2e81d5f9ffb..2c09895c79dd 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, ...)
> {
> @@ -882,6 +895,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;
> }
>
> @@ -896,6 +912,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;
> @@ -920,8 +944,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) {
> + pops->open_struct("memory");
> +
> + for (i = 0; i < ARRAY_SIZE(json_memory_region_names);
> + i++) {
> + if (i > c->regions->max_region_id)
> + break;
> +
> + pops->open_struct(json_memory_region_names[i]);
> +
> + snprintf(buf, sizeof(buf), "%" PRIu64,
> + c->memory[i].total);
> + __json_add_member("total", buf);
> +
> + snprintf(buf, sizeof(buf), "%" PRIu64,
> + c->memory[i].shared);
> + __json_add_member("shared", buf);
> +
> + snprintf(buf, sizeof(buf), "%" PRIu64,
> + c->memory[i].resident);
> + __json_add_member("resident", buf);
> +
> + snprintf(buf, sizeof(buf), "%" PRIu64,
> + c->memory[i].purgeable);
> + __json_add_member("purgeable", buf);
> +
> + snprintf(buf, sizeof(buf), "%" PRIu64,
> + c->memory[i].active);
> + __json_add_member("active", buf);
> +
> + pops->close_struct();
> + }
> +
> + pops->close_struct();
> + }
> +
> if (c->samples > 1) {
> pops->open_struct("engine-classes");
>
> @@ -2460,10 +2551,29 @@ static void intel_scan_clients(struct intel_clients *iclients)
> "video-enhance",
> "compute",
> };
> + struct igt_drm_client *c;
> + unsigned int i;
>
> igt_drm_clients_scan(iclients->clients, client_match,
> engine_map, ARRAY_SIZE(engine_map),
> - NULL, 0);
> + memory_region_map, ARRAY_SIZE(memory_region_map));
> +
> + iclients->regions = NULL;
> +
> + if (!iclients->clients)
> + return;
> +
> + /*
> + * Borrow memory region data from first client so we can use it
> + * when displaying stuff. All regions are the same due our client_match.
> + */
> + igt_for_each_drm_client(iclients->clients, c, i) {
> + if (c->status == IGT_DRM_CLIENT_ALIVE) {
> + if (c->regions->num_regions)
> + iclients->regions = c->regions;
> + break;
> + }
> + }
> }
>
> int main(int argc, char **argv)
> --
> 2.39.2
>
More information about the igt-dev
mailing list