From: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com> To: igt-dev@lists.freedesktop.org, Intel-gfx@lists.freedesktop.org Subject: [Intel-gfx] [PATCH i-g-t 6/8] lib/igt_drm_clients: Decouple hardcoded engine assumptions Date: Thu, 6 Apr 2023 15:15:36 +0100 [thread overview] Message-ID: <20230406141538.3414368-7-tvrtko.ursulin@linux.intel.com> (raw) In-Reply-To: <20230406141538.3414368-1-tvrtko.ursulin@linux.intel.com> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Intel_gpu_top gets it's main engine configuration data via PMU probe and uses that for per client view as well. Furthemore code so far assumed only clients belonging from a single DRM card would be tracked in a single clients list. Break this inter-dependency by moving the engine data to be per client and also have libdrmclient probe the engine configuration independently using the previously added libdrmfdinfo facilities. Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> --- lib/igt_drm_clients.c | 38 +++++++++++-- lib/igt_drm_clients.h | 14 ++--- tools/intel_gpu_top.c | 127 +++++++++++++++++++++++++++++++----------- 3 files changed, 134 insertions(+), 45 deletions(-) diff --git a/lib/igt_drm_clients.c b/lib/igt_drm_clients.c index e11c8b18188f..d507c07fec87 100644 --- a/lib/igt_drm_clients.c +++ b/lib/igt_drm_clients.c @@ -97,7 +97,7 @@ igt_drm_client_update(struct igt_drm_client *c, unsigned int pid, char *name, c->last_runtime = 0; c->total_runtime = 0; - for (i = 0; i < c->clients->num_classes; i++) { + for (i = 0; i <= c->engines->max_engine_id; i++) { assert(i < ARRAY_SIZE(info->busy)); if (info->busy[i] < c->last[i]) @@ -119,6 +119,7 @@ igt_drm_client_add(struct igt_drm_clients *clients, unsigned int pid, char *name, unsigned int drm_minor) { struct igt_drm_client *c; + unsigned int i; assert(!igt_drm_clients_find(clients, IGT_DRM_CLIENT_ALIVE, drm_minor, info->id)); @@ -144,8 +145,28 @@ igt_drm_client_add(struct igt_drm_clients *clients, c->id = info->id; c->drm_minor = drm_minor; c->clients = clients; - c->val = calloc(clients->num_classes, sizeof(c->val)); - c->last = calloc(clients->num_classes, sizeof(c->last)); + c->engines = malloc(sizeof(*c->engines)); + assert(c->engines); + memset(c->engines, 0, sizeof(*c->engines)); + c->engines->capacity = calloc(info->last_engine_index + 1, + sizeof(*c->engines->capacity)); + assert(c->engines->capacity); + c->engines->names = calloc(info->last_engine_index + 1, + sizeof(*c->engines->names)); + assert(c->engines->names); + + for (i = 0; i <= info->last_engine_index; i++) { + if (!info->capacity[i]) + continue; + + c->engines->capacity[i] = info->capacity[i]; + c->engines->names[i] = strdup(info->names[i]); + assert(c->engines->names[i]); + c->engines->num_engines++; + c->engines->max_engine_id = i; + } + c->val = calloc(c->engines->max_engine_id + 1, sizeof(c->val)); + c->last = calloc(c->engines->max_engine_id + 1, sizeof(c->last)); assert(c->val && c->last); igt_drm_client_update(c, pid, name, info); @@ -154,6 +175,15 @@ igt_drm_client_add(struct igt_drm_clients *clients, static void igt_drm_client_free(struct igt_drm_client *c, bool clear) { + unsigned int i; + + if (c->engines) { + for (i = 0; i <= c->engines->max_engine_id; i++) + free(c->engines->names[i]); + free(c->engines->capacity); + free(c->engines->names); + } + free(c->engines); free(c->val); free(c->last); @@ -323,7 +353,7 @@ static bool is_drm_fd(int fd_dir, const char *name, unsigned int *minor) * * If @name_map is not provided engine names will be auto-detected (this is * less performant) and indices will correspond with auto-detected names as - * listed int clients->engine_class[]. + * listed int clients->engines->names[]. */ struct igt_drm_clients * igt_drm_clients_scan(struct igt_drm_clients *clients, diff --git a/lib/igt_drm_clients.h b/lib/igt_drm_clients.h index ffa219c9c9fd..0a903b431eaa 100644 --- a/lib/igt_drm_clients.h +++ b/lib/igt_drm_clients.h @@ -31,10 +31,12 @@ enum igt_drm_client_status { IGT_DRM_CLIENT_PROBE }; -struct igt_drm_client_engine_class { - unsigned int engine_class; - const char *name; - unsigned int num_engines; +struct igt_drm_client_engines { + unsigned int num_engines; /* Number of discovered active engines. */ + unsigned int max_engine_id; /* Largest engine index discovered. + (Can differ from num_engines - 1 when using the engine map facility.) */ + unsigned int *capacity; /* Array of engine capacities as parsed from fdinfo. */ + char **names; /* Array of engine names, either auto-detected or from the passed in engine map. */ }; struct igt_drm_clients; @@ -43,6 +45,7 @@ struct igt_drm_client { struct igt_drm_clients *clients; /* Owning list. */ enum igt_drm_client_status status; + struct igt_drm_client_engines *engines; /* Engines used by this client, to map with busynees data. */ unsigned int id; /* DRM client id from fdinfo. */ unsigned int drm_minor; /* DRM minor of this client. */ unsigned int pid; /* PID which has this DRM fd open. */ @@ -59,9 +62,6 @@ struct igt_drm_clients { unsigned int num_clients; unsigned int active_clients; - unsigned int num_classes; - struct igt_drm_client_engine_class *engine_class; - void *private_data; struct igt_drm_client *client; /* Must be last. */ diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c index 4276632eea8d..c7af93e1e85e 100644 --- a/tools/intel_gpu_top.c +++ b/tools/intel_gpu_top.c @@ -67,6 +67,12 @@ struct pmu_counter { bool present; }; +struct engine_class { + unsigned int engine_class; + const char *name; + unsigned int num_engines; +}; + struct engine { const char *name; char *display_name; @@ -85,7 +91,7 @@ struct engine { struct engines { unsigned int num_engines; unsigned int num_classes; - struct igt_drm_client_engine_class *class; + struct engine_class *class; unsigned int num_counters; DIR *root; int fd; @@ -117,6 +123,11 @@ struct engines { }; +struct intel_clients { + const char *pci_slot; + struct igt_drm_client_engines classes; +}; + static struct termios termios_orig; __attribute__((format(scanf,3,4))) @@ -774,9 +785,8 @@ static struct igt_drm_clients *display_clients(struct igt_drm_clients *clients) ac = calloc(clients->num_clients, sizeof(*c)); assert(ac); - aggregated->num_classes = clients->num_classes; - aggregated->engine_class = clients->engine_class; aggregated->private_data = clients->private_data; + aggregated->client = ac; igt_for_each_drm_client(clients, c, tmp) { @@ -797,7 +807,8 @@ static struct igt_drm_clients *display_clients(struct igt_drm_clients *clients) ac->pid = c->pid; strcpy(ac->name, c->name); strcpy(ac->print_name, c->print_name); - ac->val = calloc(clients->num_classes, + ac->engines = c->engines; + ac->val = calloc(c->engines->max_engine_id + 1, sizeof(ac->val[0])); assert(ac->val); ac->samples = 1; @@ -812,7 +823,7 @@ static struct igt_drm_clients *display_clients(struct igt_drm_clients *clients) ac->total_runtime += c->total_runtime; ac->last_runtime += c->last_runtime; - for (i = 0; i < clients->num_classes; i++) + for (i = 0; i <= c->engines->max_engine_id; i++) ac->val[i] += c->val[i]; } @@ -833,7 +844,7 @@ static void free_display_clients(struct igt_drm_clients *clients) /* * Don't call igt_drm_clients_free or igt_drm_client_free since * "display" clients are not proper clients and have un-initialized - * fields which we don't want the library to try and free. + * or borrowed fields which we don't want the library to try and free. */ igt_for_each_drm_client(clients, c, tmp) free(c->val); @@ -1616,15 +1627,15 @@ print_engines_footer(struct engines *engines, double t, static int class_cmp(const void *_a, const void *_b) { - const struct igt_drm_client_engine_class *a = _a; - const struct igt_drm_client_engine_class *b = _b; + const struct engine_class *a = _a; + const struct engine_class *b = _b; return a->engine_class - b->engine_class; } static void init_engine_classes(struct engines *engines) { - struct igt_drm_client_engine_class *classes; + struct engine_class *classes; unsigned int i, num; int max = -1; @@ -1796,6 +1807,8 @@ static int print_clients_header(struct igt_drm_clients *clients, int lines, int con_w, int con_h, int *class_w) { + struct intel_clients *iclients = clients->private_data; + if (output_mode == INTERACTIVE) { const char *pidname = " PID NAME "; unsigned int num_active = 0; @@ -1810,25 +1823,25 @@ print_clients_header(struct igt_drm_clients *clients, int lines, if (lines++ >= con_h || len >= con_w) return lines; - if (clients->num_classes) { + if (iclients->classes.num_engines) { unsigned int i; int width; - for (i = 0; i < clients->num_classes; i++) { - if (clients->engine_class[i].num_engines) + for (i = 0; i <= iclients->classes.max_engine_id; i++) { + if (iclients->classes.capacity[i]) num_active++; } *class_w = width = (con_w - len) / num_active; - for (i = 0; i < clients->num_classes; i++) { - const char *name = clients->engine_class[i].name; + for (i = 0; i <= iclients->classes.max_engine_id; i++) { + const char *name = iclients->classes.names[i]; int name_len = strlen(name); int pad = (width - name_len) / 2; int spaces = width - pad - name_len; - if (!clients->engine_class[i].num_engines) - continue; /* Assert in the ideal world. */ + if (!iclients->classes.capacity[i]) + continue; if (pad < 0 || spaces < 0) continue; @@ -1843,7 +1856,7 @@ print_clients_header(struct igt_drm_clients *clients, int lines, n_spaces(con_w - len); printf("\033[0m\n"); } else { - if (clients->num_classes) + if (iclients->classes.num_engines) pops->open_struct("clients"); } @@ -1858,6 +1871,7 @@ print_client(struct igt_drm_client *c, struct engines *engines, double t, int li int con_w, int con_h, unsigned int period_us, int *class_w) { struct igt_drm_clients *clients = c->clients; + struct intel_clients *iclients = clients->private_data; unsigned int i; if (output_mode == INTERACTIVE) { @@ -1868,14 +1882,16 @@ print_client(struct igt_drm_client *c, struct engines *engines, double t, int li printf("%6u %17s ", c->pid, c->print_name); - for (i = 0; c->samples > 1 && i < clients->num_classes; i++) { + for (i = 0; + c->samples > 1 && i <= iclients->classes.max_engine_id; + i++) { double pct; - if (!clients->engine_class[i].num_engines) - continue; /* Assert in the ideal world. */ + if (!iclients->classes.capacity[i]) + continue; pct = (double)c->val[i] / period_us / 1e3 * 100 / - clients->engine_class[i].num_engines; + iclients->classes.capacity[i]; /* * Guard against possible time-drift between sampling @@ -1903,11 +1919,11 @@ print_client(struct igt_drm_client *c, struct engines *engines, double t, int li if (c->samples > 1) { pops->open_struct("engine-classes"); - for (i = 0; i < clients->num_classes; i++) { + for (i = 0; i <= iclients->classes.max_engine_id; i++) { double pct; snprintf(buf, sizeof(buf), "%s", - clients->engine_class[i].name); + iclients->classes.names[i]); pops->open_struct(buf); pct = (double)c->val[i] / period_us / 1e3 * 100; @@ -1936,7 +1952,9 @@ print_clients_footer(struct igt_drm_clients *clients, double t, if (lines++ < con_h) printf("\n"); } else { - if (clients->num_classes) + struct intel_clients *iclients = clients->private_data; + + if (iclients->classes.num_engines) pops->close_struct(); } @@ -2181,14 +2199,54 @@ static unsigned long elapsed_us(struct timespec *prev, unsigned int period_us) static bool client_match(const struct igt_drm_clients *clients, const struct drm_client_fdinfo *info) { + struct intel_clients *iclients = clients->private_data; + if (strcmp(info->driver, "i915")) return false; - if (strcmp(info->pdev, clients->private_data)) + if (strcmp(info->pdev, iclients->pci_slot)) return false; return true; } +static void +intel_init_clients(struct intel_clients *iclients, + const struct igt_device_card *card, struct engines *engines) +{ + unsigned int i; + + iclients->pci_slot = strdup(card->pci_slot_name[0] ? + card->pci_slot_name : IGPU_PCI); + assert(iclients->pci_slot); + + iclients->classes.num_engines = engines->num_classes; + iclients->classes.max_engine_id = engines->num_classes - 1; + + iclients->classes.capacity = calloc(engines->num_classes, + sizeof(*iclients->classes.capacity)); + assert(iclients->classes.capacity); + iclients->classes.names = calloc(engines->num_classes, + sizeof(*iclients->classes.names)); + assert(iclients->classes.names); + + for (i = 0; i < engines->num_classes; i++) { + if (!engines->class[i].num_engines) + continue; + + iclients->classes.num_engines++; + iclients->classes.max_engine_id = i; + iclients->classes.capacity[i] = engines->class[i].num_engines; + iclients->classes.names[i] = strdup(engines->class[i].name); + } +} + +static void intel_free_clients(struct intel_clients *iclients) +{ + free((void *)iclients->pci_slot); + free(iclients->classes.capacity); + free(iclients->classes.names); +} + int main(int argc, char **argv) { unsigned int period_us = DEFAULT_PERIOD_MS * 1000; @@ -2201,6 +2259,7 @@ int main(int argc, char **argv) "compute", }; bool physical_engines = false; + struct intel_clients iclients; int con_w = -1, con_h = -1; char *output_path = NULL; struct engines *engines; @@ -2324,6 +2383,8 @@ int main(int argc, char **argv) else pmu_device = strdup("i915"); + codename = igt_device_get_pretty_name(&card, false); + engines = discover_engines(pmu_device); if (!engines) { fprintf(stderr, @@ -2352,21 +2413,17 @@ int main(int argc, char **argv) ret = EXIT_SUCCESS; - if (has_drm_fdinfo(&card)) - clients = igt_drm_clients_init(strdup(card.pci_slot_name[0] ? - card.pci_slot_name : - IGPU_PCI)); init_engine_classes(engines); - if (clients) { - clients->num_classes = engines->num_classes; - clients->engine_class = engines->class; + + if (has_drm_fdinfo(&card)) { + intel_init_clients(&iclients, &card, engines); + clients = igt_drm_clients_init(&iclients); } pmu_sample(engines); igt_drm_clients_scan(clients, client_match, engine_map, ARRAY_SIZE(engine_map)); gettime(&ts); - codename = igt_device_get_pretty_name(&card, false); if (output_mode == JSON) printf("[\n"); @@ -2466,8 +2523,10 @@ int main(int argc, char **argv) if (output_mode == JSON) printf("]\n"); - if (clients) + if (clients) { igt_drm_clients_free(clients); + intel_free_clients(&iclients); + } free(codename); err_pmu: -- 2.37.2
WARNING: multiple messages have this Message-ID (diff)
From: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com> To: igt-dev@lists.freedesktop.org, Intel-gfx@lists.freedesktop.org Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Subject: [igt-dev] [PATCH i-g-t 6/8] lib/igt_drm_clients: Decouple hardcoded engine assumptions Date: Thu, 6 Apr 2023 15:15:36 +0100 [thread overview] Message-ID: <20230406141538.3414368-7-tvrtko.ursulin@linux.intel.com> (raw) In-Reply-To: <20230406141538.3414368-1-tvrtko.ursulin@linux.intel.com> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Intel_gpu_top gets it's main engine configuration data via PMU probe and uses that for per client view as well. Furthemore code so far assumed only clients belonging from a single DRM card would be tracked in a single clients list. Break this inter-dependency by moving the engine data to be per client and also have libdrmclient probe the engine configuration independently using the previously added libdrmfdinfo facilities. Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> --- lib/igt_drm_clients.c | 38 +++++++++++-- lib/igt_drm_clients.h | 14 ++--- tools/intel_gpu_top.c | 127 +++++++++++++++++++++++++++++++----------- 3 files changed, 134 insertions(+), 45 deletions(-) diff --git a/lib/igt_drm_clients.c b/lib/igt_drm_clients.c index e11c8b18188f..d507c07fec87 100644 --- a/lib/igt_drm_clients.c +++ b/lib/igt_drm_clients.c @@ -97,7 +97,7 @@ igt_drm_client_update(struct igt_drm_client *c, unsigned int pid, char *name, c->last_runtime = 0; c->total_runtime = 0; - for (i = 0; i < c->clients->num_classes; i++) { + for (i = 0; i <= c->engines->max_engine_id; i++) { assert(i < ARRAY_SIZE(info->busy)); if (info->busy[i] < c->last[i]) @@ -119,6 +119,7 @@ igt_drm_client_add(struct igt_drm_clients *clients, unsigned int pid, char *name, unsigned int drm_minor) { struct igt_drm_client *c; + unsigned int i; assert(!igt_drm_clients_find(clients, IGT_DRM_CLIENT_ALIVE, drm_minor, info->id)); @@ -144,8 +145,28 @@ igt_drm_client_add(struct igt_drm_clients *clients, c->id = info->id; c->drm_minor = drm_minor; c->clients = clients; - c->val = calloc(clients->num_classes, sizeof(c->val)); - c->last = calloc(clients->num_classes, sizeof(c->last)); + c->engines = malloc(sizeof(*c->engines)); + assert(c->engines); + memset(c->engines, 0, sizeof(*c->engines)); + c->engines->capacity = calloc(info->last_engine_index + 1, + sizeof(*c->engines->capacity)); + assert(c->engines->capacity); + c->engines->names = calloc(info->last_engine_index + 1, + sizeof(*c->engines->names)); + assert(c->engines->names); + + for (i = 0; i <= info->last_engine_index; i++) { + if (!info->capacity[i]) + continue; + + c->engines->capacity[i] = info->capacity[i]; + c->engines->names[i] = strdup(info->names[i]); + assert(c->engines->names[i]); + c->engines->num_engines++; + c->engines->max_engine_id = i; + } + c->val = calloc(c->engines->max_engine_id + 1, sizeof(c->val)); + c->last = calloc(c->engines->max_engine_id + 1, sizeof(c->last)); assert(c->val && c->last); igt_drm_client_update(c, pid, name, info); @@ -154,6 +175,15 @@ igt_drm_client_add(struct igt_drm_clients *clients, static void igt_drm_client_free(struct igt_drm_client *c, bool clear) { + unsigned int i; + + if (c->engines) { + for (i = 0; i <= c->engines->max_engine_id; i++) + free(c->engines->names[i]); + free(c->engines->capacity); + free(c->engines->names); + } + free(c->engines); free(c->val); free(c->last); @@ -323,7 +353,7 @@ static bool is_drm_fd(int fd_dir, const char *name, unsigned int *minor) * * If @name_map is not provided engine names will be auto-detected (this is * less performant) and indices will correspond with auto-detected names as - * listed int clients->engine_class[]. + * listed int clients->engines->names[]. */ struct igt_drm_clients * igt_drm_clients_scan(struct igt_drm_clients *clients, diff --git a/lib/igt_drm_clients.h b/lib/igt_drm_clients.h index ffa219c9c9fd..0a903b431eaa 100644 --- a/lib/igt_drm_clients.h +++ b/lib/igt_drm_clients.h @@ -31,10 +31,12 @@ enum igt_drm_client_status { IGT_DRM_CLIENT_PROBE }; -struct igt_drm_client_engine_class { - unsigned int engine_class; - const char *name; - unsigned int num_engines; +struct igt_drm_client_engines { + unsigned int num_engines; /* Number of discovered active engines. */ + unsigned int max_engine_id; /* Largest engine index discovered. + (Can differ from num_engines - 1 when using the engine map facility.) */ + unsigned int *capacity; /* Array of engine capacities as parsed from fdinfo. */ + char **names; /* Array of engine names, either auto-detected or from the passed in engine map. */ }; struct igt_drm_clients; @@ -43,6 +45,7 @@ struct igt_drm_client { struct igt_drm_clients *clients; /* Owning list. */ enum igt_drm_client_status status; + struct igt_drm_client_engines *engines; /* Engines used by this client, to map with busynees data. */ unsigned int id; /* DRM client id from fdinfo. */ unsigned int drm_minor; /* DRM minor of this client. */ unsigned int pid; /* PID which has this DRM fd open. */ @@ -59,9 +62,6 @@ struct igt_drm_clients { unsigned int num_clients; unsigned int active_clients; - unsigned int num_classes; - struct igt_drm_client_engine_class *engine_class; - void *private_data; struct igt_drm_client *client; /* Must be last. */ diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c index 4276632eea8d..c7af93e1e85e 100644 --- a/tools/intel_gpu_top.c +++ b/tools/intel_gpu_top.c @@ -67,6 +67,12 @@ struct pmu_counter { bool present; }; +struct engine_class { + unsigned int engine_class; + const char *name; + unsigned int num_engines; +}; + struct engine { const char *name; char *display_name; @@ -85,7 +91,7 @@ struct engine { struct engines { unsigned int num_engines; unsigned int num_classes; - struct igt_drm_client_engine_class *class; + struct engine_class *class; unsigned int num_counters; DIR *root; int fd; @@ -117,6 +123,11 @@ struct engines { }; +struct intel_clients { + const char *pci_slot; + struct igt_drm_client_engines classes; +}; + static struct termios termios_orig; __attribute__((format(scanf,3,4))) @@ -774,9 +785,8 @@ static struct igt_drm_clients *display_clients(struct igt_drm_clients *clients) ac = calloc(clients->num_clients, sizeof(*c)); assert(ac); - aggregated->num_classes = clients->num_classes; - aggregated->engine_class = clients->engine_class; aggregated->private_data = clients->private_data; + aggregated->client = ac; igt_for_each_drm_client(clients, c, tmp) { @@ -797,7 +807,8 @@ static struct igt_drm_clients *display_clients(struct igt_drm_clients *clients) ac->pid = c->pid; strcpy(ac->name, c->name); strcpy(ac->print_name, c->print_name); - ac->val = calloc(clients->num_classes, + ac->engines = c->engines; + ac->val = calloc(c->engines->max_engine_id + 1, sizeof(ac->val[0])); assert(ac->val); ac->samples = 1; @@ -812,7 +823,7 @@ static struct igt_drm_clients *display_clients(struct igt_drm_clients *clients) ac->total_runtime += c->total_runtime; ac->last_runtime += c->last_runtime; - for (i = 0; i < clients->num_classes; i++) + for (i = 0; i <= c->engines->max_engine_id; i++) ac->val[i] += c->val[i]; } @@ -833,7 +844,7 @@ static void free_display_clients(struct igt_drm_clients *clients) /* * Don't call igt_drm_clients_free or igt_drm_client_free since * "display" clients are not proper clients and have un-initialized - * fields which we don't want the library to try and free. + * or borrowed fields which we don't want the library to try and free. */ igt_for_each_drm_client(clients, c, tmp) free(c->val); @@ -1616,15 +1627,15 @@ print_engines_footer(struct engines *engines, double t, static int class_cmp(const void *_a, const void *_b) { - const struct igt_drm_client_engine_class *a = _a; - const struct igt_drm_client_engine_class *b = _b; + const struct engine_class *a = _a; + const struct engine_class *b = _b; return a->engine_class - b->engine_class; } static void init_engine_classes(struct engines *engines) { - struct igt_drm_client_engine_class *classes; + struct engine_class *classes; unsigned int i, num; int max = -1; @@ -1796,6 +1807,8 @@ static int print_clients_header(struct igt_drm_clients *clients, int lines, int con_w, int con_h, int *class_w) { + struct intel_clients *iclients = clients->private_data; + if (output_mode == INTERACTIVE) { const char *pidname = " PID NAME "; unsigned int num_active = 0; @@ -1810,25 +1823,25 @@ print_clients_header(struct igt_drm_clients *clients, int lines, if (lines++ >= con_h || len >= con_w) return lines; - if (clients->num_classes) { + if (iclients->classes.num_engines) { unsigned int i; int width; - for (i = 0; i < clients->num_classes; i++) { - if (clients->engine_class[i].num_engines) + for (i = 0; i <= iclients->classes.max_engine_id; i++) { + if (iclients->classes.capacity[i]) num_active++; } *class_w = width = (con_w - len) / num_active; - for (i = 0; i < clients->num_classes; i++) { - const char *name = clients->engine_class[i].name; + for (i = 0; i <= iclients->classes.max_engine_id; i++) { + const char *name = iclients->classes.names[i]; int name_len = strlen(name); int pad = (width - name_len) / 2; int spaces = width - pad - name_len; - if (!clients->engine_class[i].num_engines) - continue; /* Assert in the ideal world. */ + if (!iclients->classes.capacity[i]) + continue; if (pad < 0 || spaces < 0) continue; @@ -1843,7 +1856,7 @@ print_clients_header(struct igt_drm_clients *clients, int lines, n_spaces(con_w - len); printf("\033[0m\n"); } else { - if (clients->num_classes) + if (iclients->classes.num_engines) pops->open_struct("clients"); } @@ -1858,6 +1871,7 @@ print_client(struct igt_drm_client *c, struct engines *engines, double t, int li int con_w, int con_h, unsigned int period_us, int *class_w) { struct igt_drm_clients *clients = c->clients; + struct intel_clients *iclients = clients->private_data; unsigned int i; if (output_mode == INTERACTIVE) { @@ -1868,14 +1882,16 @@ print_client(struct igt_drm_client *c, struct engines *engines, double t, int li printf("%6u %17s ", c->pid, c->print_name); - for (i = 0; c->samples > 1 && i < clients->num_classes; i++) { + for (i = 0; + c->samples > 1 && i <= iclients->classes.max_engine_id; + i++) { double pct; - if (!clients->engine_class[i].num_engines) - continue; /* Assert in the ideal world. */ + if (!iclients->classes.capacity[i]) + continue; pct = (double)c->val[i] / period_us / 1e3 * 100 / - clients->engine_class[i].num_engines; + iclients->classes.capacity[i]; /* * Guard against possible time-drift between sampling @@ -1903,11 +1919,11 @@ print_client(struct igt_drm_client *c, struct engines *engines, double t, int li if (c->samples > 1) { pops->open_struct("engine-classes"); - for (i = 0; i < clients->num_classes; i++) { + for (i = 0; i <= iclients->classes.max_engine_id; i++) { double pct; snprintf(buf, sizeof(buf), "%s", - clients->engine_class[i].name); + iclients->classes.names[i]); pops->open_struct(buf); pct = (double)c->val[i] / period_us / 1e3 * 100; @@ -1936,7 +1952,9 @@ print_clients_footer(struct igt_drm_clients *clients, double t, if (lines++ < con_h) printf("\n"); } else { - if (clients->num_classes) + struct intel_clients *iclients = clients->private_data; + + if (iclients->classes.num_engines) pops->close_struct(); } @@ -2181,14 +2199,54 @@ static unsigned long elapsed_us(struct timespec *prev, unsigned int period_us) static bool client_match(const struct igt_drm_clients *clients, const struct drm_client_fdinfo *info) { + struct intel_clients *iclients = clients->private_data; + if (strcmp(info->driver, "i915")) return false; - if (strcmp(info->pdev, clients->private_data)) + if (strcmp(info->pdev, iclients->pci_slot)) return false; return true; } +static void +intel_init_clients(struct intel_clients *iclients, + const struct igt_device_card *card, struct engines *engines) +{ + unsigned int i; + + iclients->pci_slot = strdup(card->pci_slot_name[0] ? + card->pci_slot_name : IGPU_PCI); + assert(iclients->pci_slot); + + iclients->classes.num_engines = engines->num_classes; + iclients->classes.max_engine_id = engines->num_classes - 1; + + iclients->classes.capacity = calloc(engines->num_classes, + sizeof(*iclients->classes.capacity)); + assert(iclients->classes.capacity); + iclients->classes.names = calloc(engines->num_classes, + sizeof(*iclients->classes.names)); + assert(iclients->classes.names); + + for (i = 0; i < engines->num_classes; i++) { + if (!engines->class[i].num_engines) + continue; + + iclients->classes.num_engines++; + iclients->classes.max_engine_id = i; + iclients->classes.capacity[i] = engines->class[i].num_engines; + iclients->classes.names[i] = strdup(engines->class[i].name); + } +} + +static void intel_free_clients(struct intel_clients *iclients) +{ + free((void *)iclients->pci_slot); + free(iclients->classes.capacity); + free(iclients->classes.names); +} + int main(int argc, char **argv) { unsigned int period_us = DEFAULT_PERIOD_MS * 1000; @@ -2201,6 +2259,7 @@ int main(int argc, char **argv) "compute", }; bool physical_engines = false; + struct intel_clients iclients; int con_w = -1, con_h = -1; char *output_path = NULL; struct engines *engines; @@ -2324,6 +2383,8 @@ int main(int argc, char **argv) else pmu_device = strdup("i915"); + codename = igt_device_get_pretty_name(&card, false); + engines = discover_engines(pmu_device); if (!engines) { fprintf(stderr, @@ -2352,21 +2413,17 @@ int main(int argc, char **argv) ret = EXIT_SUCCESS; - if (has_drm_fdinfo(&card)) - clients = igt_drm_clients_init(strdup(card.pci_slot_name[0] ? - card.pci_slot_name : - IGPU_PCI)); init_engine_classes(engines); - if (clients) { - clients->num_classes = engines->num_classes; - clients->engine_class = engines->class; + + if (has_drm_fdinfo(&card)) { + intel_init_clients(&iclients, &card, engines); + clients = igt_drm_clients_init(&iclients); } pmu_sample(engines); igt_drm_clients_scan(clients, client_match, engine_map, ARRAY_SIZE(engine_map)); gettime(&ts); - codename = igt_device_get_pretty_name(&card, false); if (output_mode == JSON) printf("[\n"); @@ -2466,8 +2523,10 @@ int main(int argc, char **argv) if (output_mode == JSON) printf("]\n"); - if (clients) + if (clients) { igt_drm_clients_free(clients); + intel_free_clients(&iclients); + } free(codename); err_pmu: -- 2.37.2
next prev parent reply other threads:[~2023-04-06 14:16 UTC|newest] Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top 2023-04-06 14:15 [Intel-gfx] [PATCH i-g-t v4 0/8] Vendor agnostic gputop Tvrtko Ursulin 2023-04-06 14:15 ` [igt-dev] " Tvrtko Ursulin 2023-04-06 14:15 ` [Intel-gfx] [PATCH i-g-t 1/8] lib: Extract igt_drm_clients from intel_gpu_top Tvrtko Ursulin 2023-04-06 14:15 ` [igt-dev] " Tvrtko Ursulin 2023-04-06 14:15 ` [Intel-gfx] [PATCH i-g-t 2/8] lib: Allow specifying custom engine map Tvrtko Ursulin 2023-04-06 14:15 ` [igt-dev] " Tvrtko Ursulin 2023-04-06 14:15 ` [Intel-gfx] [PATCH i-g-t 3/8] lib/igt_drm_clients: Record client drm minor Tvrtko Ursulin 2023-04-06 14:15 ` [igt-dev] " Tvrtko Ursulin 2023-04-06 14:15 ` [Intel-gfx] [PATCH i-g-t 4/8] lib/igt_drm_clients: Support multiple DRM cards Tvrtko Ursulin 2023-04-06 14:15 ` [igt-dev] " Tvrtko Ursulin 2023-04-06 14:15 ` [Intel-gfx] [PATCH i-g-t 5/8] lib/igt_drm_fdinfo: Track largest engine index Tvrtko Ursulin 2023-04-06 14:15 ` [igt-dev] " Tvrtko Ursulin 2023-04-06 14:15 ` Tvrtko Ursulin [this message] 2023-04-06 14:15 ` [igt-dev] [PATCH i-g-t 6/8] lib/igt_drm_clients: Decouple hardcoded engine assumptions Tvrtko Ursulin 2023-04-06 14:15 ` [Intel-gfx] [PATCH i-g-t 7/8] lib/igt_drm_clients: Enforce client status sort order in the library Tvrtko Ursulin 2023-04-06 14:15 ` [igt-dev] " Tvrtko Ursulin 2023-04-06 14:15 ` [Intel-gfx] [PATCH i-g-t 8/8] gputop: Basic vendor agnostic GPU top tool Tvrtko Ursulin 2023-04-06 14:15 ` [igt-dev] " Tvrtko Ursulin 2023-04-06 14:44 ` [igt-dev] ✗ Fi.CI.BUILD: failure for Vendor agnostic gputop (rev6) Patchwork 2023-04-06 15:05 ` Tvrtko Ursulin -- strict thread matches above, loose matches on Subject: below -- 2023-04-17 10:57 [Intel-gfx] [PATCH i-g-t v5 0/8] Vendor agnostic gputop Tvrtko Ursulin 2023-04-17 10:57 ` [Intel-gfx] [PATCH i-g-t 6/8] lib/igt_drm_clients: Decouple hardcoded engine assumptions Tvrtko Ursulin 2023-01-31 11:32 [Intel-gfx] [PATCH i-g-t v3 0/8] Vendor agnostic gputop Tvrtko Ursulin 2023-01-31 11:32 ` [Intel-gfx] [PATCH i-g-t 6/8] lib/igt_drm_clients: Decouple hardcoded engine assumptions Tvrtko Ursulin
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20230406141538.3414368-7-tvrtko.ursulin@linux.intel.com \ --to=tvrtko.ursulin@linux.intel.com \ --cc=Intel-gfx@lists.freedesktop.org \ --cc=igt-dev@lists.freedesktop.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.