Message ID | 20231012081547.852052-10-tvrtko.ursulin@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Client memory fdinfo test and intel_gpu_top support | expand |
Hi Tvrtko, On 2023-10-12 at 09:15:47 +0100, Tvrtko Ursulin wrote: > From: Tvrtko Ursulin <tvrtko.ursulin@intel.com> > > Similar as we can toggle between aggregated engines and clients, add the > capability to toggle between aggregated and per memory region stats. > > It starts in aggregated mode by default and interactive command 'm' and > command line switch '-m' can be used to toggle that. > > Both only affect the interactive view, while JSON output always contains > separate memory regions. > > Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Reviewed-by: Kamil Konieczny <kamil.konieczny@linux.intel.com> > --- > man/intel_gpu_top.rst | 4 ++++ > tools/intel_gpu_top.c | 55 ++++++++++++++++++++++++++++++++++--------- > 2 files changed, 48 insertions(+), 11 deletions(-) > > diff --git a/man/intel_gpu_top.rst b/man/intel_gpu_top.rst > index 9499f87f1b4d..44a54a5f219d 100644 > --- a/man/intel_gpu_top.rst > +++ b/man/intel_gpu_top.rst > @@ -55,6 +55,9 @@ OPTIONS > -p > Default to showing physical engines instead of aggregated classes. > > +-m > + Default to showing all memory regions separately. > + > RUNTIME CONTROL > =============== > > @@ -68,6 +71,7 @@ Supported keys: > | 's' Toggle between sort modes (runtime, total runtime, pid, client id). > | 'i' Toggle display of clients which used no GPU time. > | 'H' Toggle between per PID aggregation and individual clients. > +| 'm' Toggle between aggregated memory regions and full breakdown. > > DEVICE SELECTION > ================ > diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c > index 2c09895c79dd..046ead15a122 100644 > --- a/tools/intel_gpu_top.c > +++ b/tools/intel_gpu_top.c > @@ -138,6 +138,7 @@ struct intel_clients { > > static struct termios termios_orig; > static bool class_view; > +static bool aggregate_regions; > > /* Maps i915 fdinfo names to indices */ > static const char *memory_region_map[] = { > @@ -1050,6 +1051,7 @@ usage(const char *appname) > "\t[-L] List all cards.\n" > "\t[-d <device>] Device filter, please check manual page for more details.\n" > "\t[-p] Default to showing physical engines instead of classes.\n" > + "\t[-m] Default to showing all memory regions.\n" > "\n", > appname, DEFAULT_PERIOD_MS); > igt_device_print_filter_types(); > @@ -2032,6 +2034,7 @@ print_clients_header(struct igt_drm_clients *clients, int lines, > > if (output_mode == INTERACTIVE) { > int len, num_active = 0; > + unsigned int i; > > if (lines++ >= con_h) > return lines; > @@ -2042,11 +2045,17 @@ 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->regions) { > + if (aggregate_regions) { > + len += printf(" MEM RSS "); > + } else { > + len += printf(" RAM RSS "); > + if (iclients->regions->num_regions > 1) > + len += printf(" VRAM VRSS "); > + } > + } > > if (iclients->classes.num_engines) { > - unsigned int i; > int width; > > for (i = 0; i <= iclients->classes.max_engine_id; i++) { > @@ -2120,15 +2129,26 @@ 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; > + if (aggregate_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].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 (sz = 0, i = 0; > + i <= c->regions->max_region_id; i++) > + sz += c->memory[i].resident; > + len += print_size(sz); > + } else { > + len += print_size(c->memory[0].total); > + len += print_size(c->memory[0].resident); > + if (c->regions->num_regions > 1) { > + len += print_size(c->memory[1].total); > + len += print_size(c->memory[1].resident); > + } > + } > } > > for (i = 0; i <= iclients->classes.max_engine_id; i++) { > @@ -2405,6 +2425,13 @@ static void process_normal_stdin(void) > else > header_msg = "Showing individual clients."; > break; > + case 'm': > + aggregate_regions ^= true; > + if (aggregate_regions) > + header_msg = "Aggregating memory regions."; > + else > + header_msg = "Showing memory regions."; > + break; > }; > } > } > @@ -2453,6 +2480,7 @@ static void show_help_screen(void) > " 's' Toggle between sort modes (runtime, total runtime, pid, client id).\n" > " 'i' Toggle display of clients which used no GPU time.\n" > " 'H' Toggle between per PID aggregation and individual clients.\n" > +" 'm' Toggle between aggregated memory regions and full breakdown.\n" > "\n" > " 'h' or 'q' Exit interactive help.\n" > "\n"); > @@ -2580,6 +2608,7 @@ int main(int argc, char **argv) > { > unsigned int period_us = DEFAULT_PERIOD_MS * 1000; > bool physical_engines = false; > + bool separate_regions = false; > struct intel_clients iclients; > int con_w = -1, con_h = -1; > char *output_path = NULL; > @@ -2592,7 +2621,7 @@ int main(int argc, char **argv) > struct timespec ts; > > /* Parse options */ > - while ((ch = getopt(argc, argv, "o:s:d:pcJLlh")) != -1) { > + while ((ch = getopt(argc, argv, "o:s:d:mpcJLlh")) != -1) { > switch (ch) { > case 'o': > output_path = optarg; > @@ -2606,6 +2635,9 @@ int main(int argc, char **argv) > case 'p': > physical_engines = true; > break; > + case 'm': > + separate_regions = true; > + break; > case 'c': > output_mode = CSV; > break; > @@ -2649,6 +2681,7 @@ int main(int argc, char **argv) > fprintf(stderr, "Failed to install signal handler!\n"); > > class_view = !physical_engines; > + aggregate_regions = !separate_regions; > > switch (output_mode) { > case INTERACTIVE: > -- > 2.39.2 >
diff --git a/man/intel_gpu_top.rst b/man/intel_gpu_top.rst index 9499f87f1b4d..44a54a5f219d 100644 --- a/man/intel_gpu_top.rst +++ b/man/intel_gpu_top.rst @@ -55,6 +55,9 @@ OPTIONS -p Default to showing physical engines instead of aggregated classes. +-m + Default to showing all memory regions separately. + RUNTIME CONTROL =============== @@ -68,6 +71,7 @@ Supported keys: | 's' Toggle between sort modes (runtime, total runtime, pid, client id). | 'i' Toggle display of clients which used no GPU time. | 'H' Toggle between per PID aggregation and individual clients. +| 'm' Toggle between aggregated memory regions and full breakdown. DEVICE SELECTION ================ diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c index 2c09895c79dd..046ead15a122 100644 --- a/tools/intel_gpu_top.c +++ b/tools/intel_gpu_top.c @@ -138,6 +138,7 @@ struct intel_clients { static struct termios termios_orig; static bool class_view; +static bool aggregate_regions; /* Maps i915 fdinfo names to indices */ static const char *memory_region_map[] = { @@ -1050,6 +1051,7 @@ usage(const char *appname) "\t[-L] List all cards.\n" "\t[-d <device>] Device filter, please check manual page for more details.\n" "\t[-p] Default to showing physical engines instead of classes.\n" + "\t[-m] Default to showing all memory regions.\n" "\n", appname, DEFAULT_PERIOD_MS); igt_device_print_filter_types(); @@ -2032,6 +2034,7 @@ print_clients_header(struct igt_drm_clients *clients, int lines, if (output_mode == INTERACTIVE) { int len, num_active = 0; + unsigned int i; if (lines++ >= con_h) return lines; @@ -2042,11 +2045,17 @@ 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->regions) { + if (aggregate_regions) { + len += printf(" MEM RSS "); + } else { + len += printf(" RAM RSS "); + if (iclients->regions->num_regions > 1) + len += printf(" VRAM VRSS "); + } + } if (iclients->classes.num_engines) { - unsigned int i; int width; for (i = 0; i <= iclients->classes.max_engine_id; i++) { @@ -2120,15 +2129,26 @@ 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; + if (aggregate_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].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 (sz = 0, i = 0; + i <= c->regions->max_region_id; i++) + sz += c->memory[i].resident; + len += print_size(sz); + } else { + len += print_size(c->memory[0].total); + len += print_size(c->memory[0].resident); + if (c->regions->num_regions > 1) { + len += print_size(c->memory[1].total); + len += print_size(c->memory[1].resident); + } + } } for (i = 0; i <= iclients->classes.max_engine_id; i++) { @@ -2405,6 +2425,13 @@ static void process_normal_stdin(void) else header_msg = "Showing individual clients."; break; + case 'm': + aggregate_regions ^= true; + if (aggregate_regions) + header_msg = "Aggregating memory regions."; + else + header_msg = "Showing memory regions."; + break; }; } } @@ -2453,6 +2480,7 @@ static void show_help_screen(void) " 's' Toggle between sort modes (runtime, total runtime, pid, client id).\n" " 'i' Toggle display of clients which used no GPU time.\n" " 'H' Toggle between per PID aggregation and individual clients.\n" +" 'm' Toggle between aggregated memory regions and full breakdown.\n" "\n" " 'h' or 'q' Exit interactive help.\n" "\n"); @@ -2580,6 +2608,7 @@ int main(int argc, char **argv) { unsigned int period_us = DEFAULT_PERIOD_MS * 1000; bool physical_engines = false; + bool separate_regions = false; struct intel_clients iclients; int con_w = -1, con_h = -1; char *output_path = NULL; @@ -2592,7 +2621,7 @@ int main(int argc, char **argv) struct timespec ts; /* Parse options */ - while ((ch = getopt(argc, argv, "o:s:d:pcJLlh")) != -1) { + while ((ch = getopt(argc, argv, "o:s:d:mpcJLlh")) != -1) { switch (ch) { case 'o': output_path = optarg; @@ -2606,6 +2635,9 @@ int main(int argc, char **argv) case 'p': physical_engines = true; break; + case 'm': + separate_regions = true; + break; case 'c': output_mode = CSV; break; @@ -2649,6 +2681,7 @@ int main(int argc, char **argv) fprintf(stderr, "Failed to install signal handler!\n"); class_view = !physical_engines; + aggregate_regions = !separate_regions; switch (output_mode) { case INTERACTIVE: