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 11/12] tools/intel_gpu_top: Add per client memory info
Date: Fri, 29 Sep 2023 13:25:16 +0100 [thread overview]
Message-ID: <20230929122517.349348-12-tvrtko.ursulin@linux.intel.com> (raw)
In-Reply-To: <20230929122517.349348-1-tvrtko.ursulin@linux.intel.com>
From: Tvrtko Ursulin <tvrtko.ursulin@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@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 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) {
+ 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");
@@ -2456,10 +2547,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
next prev parent reply other threads:[~2023-09-29 12:26 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-29 12:25 [Intel-gfx] [PATCH i-g-t 00/12] fdinfo tests, intel_gpu_top memory support, etc Tvrtko Ursulin
2023-09-29 12:25 ` [Intel-gfx] [PATCH i-g-t 01/12] tests/i915/drm_fdinfo: Check engine info is supported Tvrtko Ursulin
2023-09-29 12:25 ` [Intel-gfx] [PATCH i-g-t 02/12] tests/i915/drm_fdinfo: Stress test context close versus fdinfo reads Tvrtko Ursulin
2023-09-29 12:25 ` [Intel-gfx] [PATCH i-g-t 03/12] tests/i915/drm_fdinfo: Add some memory info tests Tvrtko Ursulin
2023-09-29 12:25 ` [Intel-gfx] [PATCH i-g-t 04/12] tools/intel_gpu_top: Fix clients header width when no clients Tvrtko Ursulin
2023-09-29 12:25 ` [Intel-gfx] [PATCH i-g-t 05/12] tools/intel_gpu_top: Fix client layout on first sample period Tvrtko Ursulin
2023-09-29 12:25 ` [Intel-gfx] [PATCH i-g-t 06/12] tools/intel_gpu_top: Optimise interactive display a bit Tvrtko Ursulin
2023-09-29 12:25 ` [Intel-gfx] [PATCH i-g-t 07/12] lib/igt_drm_fdinfo: Copy over region map name on match Tvrtko Ursulin
2023-09-29 12:25 ` [Intel-gfx] [PATCH i-g-t 08/12] lib/igt_drm_clients: Fix client id type confusion Tvrtko Ursulin
2023-09-29 12:25 ` [Intel-gfx] [PATCH i-g-t 09/12] lib/igt_drm_clients: Allow passing in the memory region map Tvrtko Ursulin
2023-09-29 12:25 ` [Intel-gfx] [PATCH i-g-t 10/12] tools/intel_gpu_top: Fully wrap clients operations Tvrtko Ursulin
2023-09-29 12:25 ` Tvrtko Ursulin [this message]
2023-09-29 12:25 ` [Intel-gfx] [PATCH i-g-t 12/12] tools/intel_gpu_top: Add ability to show memory region breakdown Tvrtko Ursulin
-- strict thread matches above, loose matches on Subject: below --
2023-09-22 13:44 [Intel-gfx] [PATCH i-g-t 00/12] fdinfo tests, intel_gpu_top memory support, etc Tvrtko Ursulin
2023-09-22 13:44 ` [Intel-gfx] [PATCH i-g-t 11/12] tools/intel_gpu_top: Add per client memory info 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=20230929122517.349348-12-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: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox