Skip to contentSkip to conversation

gputop memory usage

PATCH In review Tvrtko Ursulin 3 participants 11 messages Jul 5, 2023 – Jul 27, 2023 Library code

lore
Share & tools
lore
#0 lore raw

cover gputop memory usage

From: Tvrtko Ursulin <[email protected]>

Same general approach as with engine utilisation, adding parsing of the relevant fdinfo fields and plumbing to client discovery helpers to finally present some of the available data in gputop:

DRM minor 0
PID MEM RSS render copy video NAME

8098     124M     124M |███████||       ||       ||       | neverball
 888      76M      75M |▊      ||       ||       ||       | Xorg
 966      12M      12M |       ||       ||       ||       | xfwm4

There is probably scope to consolidate some of the igt_drm_fdinfo code and to improve on the presentation but this is a start.

For now, out of the available memory categories, only total and resident are displayed, and also all discovered memory regions are summed up and shown under a single heading.

Cc Rob Clark <[email protected]>

Tvrtko Ursulin (3):
lib/igt_drm_fdinfo: Parse memory usage lib/igt_drm_clients: Store memory info in the client
gputop: Add memory information

 lib/igt_drm_clients.c   |  34 +++++++++-
 lib/igt_drm_clients.h   |  11 ++++
 lib/igt_drm_fdinfo.c    | 142 ++++++++++++++++++++++++++++++++++++++--
 lib/igt_drm_fdinfo.h    |  24 ++++++-
 tests/i915/drm_fdinfo.c |   8 +--
 tools/gputop.c          |  34 +++++++++-
 tools/intel_gpu_top.c   |   2 +-
 7 files changed, 240 insertions(+), 15 deletions(-)
Signature · 1 line
2.39.2
#1 lore raw

PATCH 1/3 lib/igt_drm_fdinfo: Parse memory usage

From: Tvrtko Ursulin <[email protected]>

Add parsing and memory storage for the memory usage related fdinfo stats.

Uses the same approach as the engine utilization code by either auto- discovering different memory regions, or allowing for the caller to pass in a map with predefined index to name relationship.

---
 lib/igt_drm_clients.c   |   3 +-
 lib/igt_drm_fdinfo.c    | 142 ++++++++++++++++++++++++++++++++++++++--
 lib/igt_drm_fdinfo.h    |  24 ++++++-
 tests/i915/drm_fdinfo.c |   8 +--
 tools/intel_gpu_top.c   |   2 +-
 5 files changed, 165 insertions(+), 14 deletions(-)
lib/igt_drm_clients.c +2 -1
index f0294ba81c42..fdea42752a81 100644
@@ -491,7 +491,8 @@ igt_drm_clients_scan(struct igt_drm_clients *clients,
 
 			if (!__igt_parse_drm_fdinfo(dirfd(fdinfo_dir),
 						    fdinfo_dent->d_name, &info,
-						    name_map, map_entries))
+						    name_map, map_entries,
+						    NULL, 0))
 				continue;
 
 			if (filter_client && !filter_client(clients, &info))
lib/igt_drm_fdinfo.c +136 -6

174 lines not on this page · raw message

lib/igt_drm_fdinfo.h +22 -2
index 6284e05e868a..1999c4f2b857 100644
@@ -30,8 +30,17 @@
 #include <stdint.h>
 #include <stdbool.h>
 
+#define DRM_CLIENT_FDINFO_MAX_REGIONS 16
 #define DRM_CLIENT_FDINFO_MAX_ENGINES 16
 
+struct drm_client_meminfo {
+	uint64_t total;
+	uint64_t shared;
+	uint64_t resident;
+	uint64_t purgeable;
+	uint64_t active;
+};
+
 struct drm_client_fdinfo {
 	char driver[128];
 	char pdev[128];
@@ -42,6 +51,11 @@ struct drm_client_fdinfo {
 	unsigned int capacity[DRM_CLIENT_FDINFO_MAX_ENGINES];
 	char names[DRM_CLIENT_FDINFO_MAX_ENGINES][256];
 	uint64_t busy[DRM_CLIENT_FDINFO_MAX_ENGINES];
+
+	unsigned int num_regions;
+	unsigned int last_region_index;
+	char region_names[DRM_CLIENT_FDINFO_MAX_REGIONS][256];
+	struct drm_client_meminfo region_mem[DRM_CLIENT_FDINFO_MAX_REGIONS];
 };
 
 /**
@@ -51,13 +65,16 @@ struct drm_client_fdinfo {
  * @info: Structure to populate with read data. Must be zeroed.
  * @name_map: Optional array of strings representing engine names
  * @map_entries: Number of strings in the names array
+ * @region_map: Optional array of strings representing memory regions
+ * @region_entries: Number of strings in the region map
  *
  * Returns the number of valid drm fdinfo keys found or zero if not all
  * mandatory keys were present or no engines found.
  */
 unsigned int
 igt_parse_drm_fdinfo(int drm_fd, struct drm_client_fdinfo *info,
-		     const char **name_map, unsigned int map_entries);
+		     const char **name_map, unsigned int map_entries,
+		     const char **region_map, unsigned int region_entries);
 
 /**
  * __igt_parse_drm_fdinfo: Parses the drm fdinfo file
@@ -67,6 +84,8 @@ igt_parse_drm_fdinfo(int drm_fd, struct drm_client_fdinfo *info,
  * @info: Structure to populate with read data. Must be zeroed.
  * @name_map: Optional array of strings representing engine names
  * @map_entries: Number of strings in the names array
+ * @region_map: Optional array of strings representing memory regions
+ * @region_entries: Number of strings in the region map
  *
  * Returns the number of valid drm fdinfo keys found or zero if not all
  * mandatory keys were present or no engines found.
@@ -74,6 +93,7 @@ igt_parse_drm_fdinfo(int drm_fd, struct drm_client_fdinfo *info,
 unsigned int
 __igt_parse_drm_fdinfo(int dir, const char *fd,
 		       struct drm_client_fdinfo *info,
-		       const char **name_map, unsigned int map_entries);
+		       const char **name_map, unsigned int map_entries,
+		       const char **region_map, unsigned int region_entries);
 
 #endif /* IGT_DRM_FDINFO_H */
tests/i915/drm_fdinfo.c +4 -4
index c0e0ba1905f1..01526c0e19de 100644
@@ -104,7 +104,7 @@ static void basics(int i915, unsigned int num_classes)
 	unsigned int ret;
 
 	ret = igt_parse_drm_fdinfo(i915, &info, engine_map,
-				   ARRAY_SIZE(engine_map));
+				   ARRAY_SIZE(engine_map), NULL, 0);
 	igt_assert(ret);
 
 	igt_assert(!strcmp(info.driver, "i915"));
@@ -236,7 +236,7 @@ static uint64_t read_busy(int i915, unsigned int class)
 	struct drm_client_fdinfo info = { };
 
 	igt_assert(igt_parse_drm_fdinfo(i915, &info, engine_map,
-					ARRAY_SIZE(engine_map)));
+					ARRAY_SIZE(engine_map), NULL, 0));
 
 	return info.busy[class];
 }
@@ -326,7 +326,7 @@ static void read_busy_all(int i915, uint64_t *val)
 	struct drm_client_fdinfo info = { };
 
 	igt_assert(igt_parse_drm_fdinfo(i915, &info, engine_map,
-					ARRAY_SIZE(engine_map)));
+					ARRAY_SIZE(engine_map), NULL, 0));
 
 	memcpy(val, info.busy, sizeof(info.busy));
 }
@@ -797,7 +797,7 @@ igt_main
 		i915 = __drm_open_driver(DRIVER_INTEL);
 
 		igt_require_gem(i915);
-		igt_require(igt_parse_drm_fdinfo(i915, &info, NULL, 0));
+		igt_require(igt_parse_drm_fdinfo(i915, &info, NULL, 0, NULL, 0));
 
 		ctx = intel_ctx_create_all_physical(i915);
 
tools/intel_gpu_top.c +1 -1
index cef1d3c7fa9f..87e9681e53b4 100644
@@ -2307,7 +2307,7 @@ static bool has_drm_fdinfo(const struct igt_device_card *card)
 	if (fd < 0)
 		return false;
 
-	cnt = igt_parse_drm_fdinfo(fd, &info, NULL, 0);
+	cnt = igt_parse_drm_fdinfo(fd, &info, NULL, 0, NULL, 0);
 
 	close(fd);
 
Signature · 1 line
2.39.2
#2 lore raw

Re: [igt-dev] [Intel-gfx] [PATCH i-g-t 1/3] lib/igt_drm_fdinfo: Parse memory usage

Hi Tvrtko,

please check your patches with Linux kernel script checkpatch.pl Some of it's warnings seems strange, like:

WARNING: Co-developed-by and Signed-off-by: name/email do not match #12:

Quoted 77 lines · Tvrtko Ursulin

From: Tvrtko Ursulin <[email protected]>

Add parsing and memory storage for the memory usage related fdinfo stats.

Uses the same approach as the engine utilization code by either auto- discovering different memory regions, or allowing for the caller to pass in a map with predefined index to name relationship.

---
 lib/igt_drm_clients.c   |   3 +-
 lib/igt_drm_fdinfo.c    | 142 ++++++++++++++++++++++++++++++++++++++--
 lib/igt_drm_fdinfo.h    |  24 ++++++-
 tests/i915/drm_fdinfo.c |   8 +--
 tools/intel_gpu_top.c   |   2 +-
 5 files changed, 165 insertions(+), 14 deletions(-)
lib/igt_drm_clients.c +2 -1
index f0294ba81c42..fdea42752a81 100644
@@ -491,7 +491,8 @@ igt_drm_clients_scan(struct igt_drm_clients *clients,
 
 			if (!__igt_parse_drm_fdinfo(dirfd(fdinfo_dir),
 						    fdinfo_dent->d_name, &info,
-						    name_map, map_entries))
+						    name_map, map_entries,
+						    NULL, 0))
 				continue;
 
 			if (filter_client && !filter_client(clients, &info))
lib/igt_drm_fdinfo.c +37 -0
index b5f8a8679a71..d08632dfb690 100644
@@ -124,13 +124,81 @@ static const char *find_kv(const char *buf, const char *key, size_t keylen)
 	return *p ? p : NULL;
 }
 
+static int parse_region(char *line, struct drm_client_fdinfo *info,
+			size_t prefix_len,
+			const char **region_map, unsigned int region_entries,
+			uint64_t *val)
+{
+	char *name, *p, *unit = NULL;
+	ssize_t name_len;
+	int found = -1;
+	unsigned int i;
+
+	p = index(line, ':');
+	if (!p || p == line)
+		return -1;
+
+	name_len = p - line - prefix_len;
+	if (name_len < 1)
+		return -1;
+
+	name = line + prefix_len;
+
+	if (region_map) {
+		for (i = 0; i < region_entries; i++) {
+			if (!strncmp(name, region_map[i], name_len)) {
+				found = i;
+				break;
+			}
+		}
+	} else {
+		for (i = 0; i < info->num_regions; i++) {
+			if (!strncmp(name, info->region_names[i], name_len)) {
+				found = i;
+				break;
+			}
+		}
+
+		if (found < 0) {
+			assert((info->num_regions + 1) < ARRAY_SIZE(info->region_names));

lib/igt_drm_fdinfo.c static const char *find_kv(const char *buf, const char *key, size_t keylen) · line 173

Quoted 10 lines
lib/igt_drm_fdinfo.c +10 -0
+			assert((strlen(name) + 1) < sizeof(info->region_names[0]));
+			strncpy(info->region_names[info->num_regions], name, name_len);
+			found = info->num_regions;
+		}
+	}
+
+	if (found < 0)
+		goto out;
+
+	while (*++p && isspace(*p));

---------------------------------- ^
According to checkpatch:

	while (*++p && isspace(*p))
		;

lib/igt_drm_fdinfo.c static const char *find_kv(const char *buf, const char *key, size_t keylen) · line 183

Quoted 10 lines
lib/igt_drm_fdinfo.c +10 -0
+	*val = strtoull(p, NULL, 10);
+
+	p = index(p, ' ');
+	if (!p)
+		goto out;
+
+	unit = ++p;
+	if (!strcmp(unit, "KiB")) {
+		*val *= 1024;
+	} else if (!strcmp(unit, "MiB")) {

------- ^^^^^^
No need for separate 'else':

	if (!strcmp(unit, "MiB")) {

lib/igt_drm_fdinfo.c static const char *find_kv(const char *buf, const char *key, size_t keylen) · line 185

Quoted 2 lines
lib/igt_drm_fdinfo.c +2 -0
+		*val *= 1024 * 1024;
+	} else if (!strcmp(unit, "GiB")) {

------- ^^^^^^
Same here.

Regards,
Kamil

Quoted 240 lines
lib/igt_drm_fdinfo.c +77 -6
+		*val *= 1024 * 1024 * 1024;
+	}
+
+out:
+	return found;
+}
+
 unsigned int
 __igt_parse_drm_fdinfo(int dir, const char *fd, struct drm_client_fdinfo *info,
-		       const char **name_map, unsigned int map_entries)
+		       const char **name_map, unsigned int map_entries,
+		       const char **region_map, unsigned int region_entries)
 {
+	bool regions_found[DRM_CLIENT_FDINFO_MAX_REGIONS] = { };
+	unsigned int good = 0, num_capacity = 0;
 	char buf[4096], *_buf = buf;
 	char *l, *ctx = NULL;
-	unsigned int good = 0, num_capacity = 0;
 	size_t count;
 
 	count = read_fdinfo(buf, sizeof(buf), dir, fd);
@@ -173,18 +241,79 @@ __igt_parse_drm_fdinfo(int dir, const char *fd, struct drm_client_fdinfo *info,
 				info->capacity[idx] = val;
 				num_capacity++;
 			}
+		} else if (!strncmp(l, "drm-total-", 10)) {
+			idx = parse_region(l, info, strlen("drm-total-"),
+					   region_map, region_entries, &val);
+			if (idx >= 0) {
+				info->region_mem[idx].total = val;
+				if (!regions_found[idx]) {
+					info->num_regions++;
+					regions_found[idx] = true;
+					if (idx > info->last_region_index)
+						info->last_region_index = idx;
+				}
+			}
+		} else if (!strncmp(l, "drm-shared-", 11)) {
+			idx = parse_region(l, info, strlen("drm-shared-"),
+					   region_map, region_entries, &val);
+			if (idx >= 0) {
+				info->region_mem[idx].shared = val;
+				if (!regions_found[idx]) {
+					info->num_regions++;
+					regions_found[idx] = true;
+					if (idx > info->last_region_index)
+						info->last_region_index = idx;
+				}
+			}
+		} else if (!strncmp(l, "drm-resident-", 13)) {
+			idx = parse_region(l, info, strlen("drm-resident-"),
+					   region_map, region_entries, &val);
+			if (idx >= 0) {
+				info->region_mem[idx].resident = val;
+				if (!regions_found[idx]) {
+					info->num_regions++;
+					regions_found[idx] = true;
+					if (idx > info->last_region_index)
+						info->last_region_index = idx;
+				}
+			}
+		} else if (!strncmp(l, "drm-purgeable-", 14)) {
+			idx = parse_region(l, info, strlen("drm-purgeable-"),
+					   region_map, region_entries, &val);
+			if (idx >= 0) {
+				info->region_mem[idx].purgeable = val;
+				if (!regions_found[idx]) {
+					info->num_regions++;
+					regions_found[idx] = true;
+					if (idx > info->last_region_index)
+						info->last_region_index = idx;
+				}
+			}
+		} else if (!strncmp(l, "drm-active-", 11)) {
+			idx = parse_region(l, info, strlen("drm-active-"),
+					   region_map, region_entries, &val);
+			if (idx >= 0) {
+				info->region_mem[idx].active = val;
+				if (!regions_found[idx]) {
+					info->num_regions++;
+					regions_found[idx] = true;
+					if (idx > info->last_region_index)
+						info->last_region_index = idx;
+				}
+			}
 		}
 	}
 
-	if (good < 2 || !info->num_engines)
+	if (good < 2 || (!info->num_engines && !info->num_regions))
 		return 0; /* fdinfo format not as expected */
 
-	return good + info->num_engines + num_capacity;
+	return good + info->num_engines + num_capacity + info->num_regions;
 }
 
 unsigned int
 igt_parse_drm_fdinfo(int drm_fd, struct drm_client_fdinfo *info,
-		     const char **name_map, unsigned int map_entries)
+		     const char **name_map, unsigned int map_entries,
+		     const char **region_map, unsigned int region_entries)
 {
 	unsigned int res;
 	char fd[64];
@@ -198,7 +327,8 @@ igt_parse_drm_fdinfo(int drm_fd, struct drm_client_fdinfo *info,
 	if (dir < 0)
 		return false;
 
-	res = __igt_parse_drm_fdinfo(dir, fd, info, name_map, map_entries);
+	res = __igt_parse_drm_fdinfo(dir, fd, info, name_map, map_entries,
+				     region_map, region_entries);
 
 	close(dir);
 
lib/igt_drm_fdinfo.h +22 -2
index 6284e05e868a..1999c4f2b857 100644
@@ -30,8 +30,17 @@
 #include <stdint.h>
 #include <stdbool.h>
 
+#define DRM_CLIENT_FDINFO_MAX_REGIONS 16
 #define DRM_CLIENT_FDINFO_MAX_ENGINES 16
 
+struct drm_client_meminfo {
+	uint64_t total;
+	uint64_t shared;
+	uint64_t resident;
+	uint64_t purgeable;
+	uint64_t active;
+};
+
 struct drm_client_fdinfo {
 	char driver[128];
 	char pdev[128];
@@ -42,6 +51,11 @@ struct drm_client_fdinfo {
 	unsigned int capacity[DRM_CLIENT_FDINFO_MAX_ENGINES];
 	char names[DRM_CLIENT_FDINFO_MAX_ENGINES][256];
 	uint64_t busy[DRM_CLIENT_FDINFO_MAX_ENGINES];
+
+	unsigned int num_regions;
+	unsigned int last_region_index;
+	char region_names[DRM_CLIENT_FDINFO_MAX_REGIONS][256];
+	struct drm_client_meminfo region_mem[DRM_CLIENT_FDINFO_MAX_REGIONS];
 };
 
 /**
@@ -51,13 +65,16 @@ struct drm_client_fdinfo {
  * @info: Structure to populate with read data. Must be zeroed.
  * @name_map: Optional array of strings representing engine names
  * @map_entries: Number of strings in the names array
+ * @region_map: Optional array of strings representing memory regions
+ * @region_entries: Number of strings in the region map
  *
  * Returns the number of valid drm fdinfo keys found or zero if not all
  * mandatory keys were present or no engines found.
  */
 unsigned int
 igt_parse_drm_fdinfo(int drm_fd, struct drm_client_fdinfo *info,
-		     const char **name_map, unsigned int map_entries);
+		     const char **name_map, unsigned int map_entries,
+		     const char **region_map, unsigned int region_entries);
 
 /**
  * __igt_parse_drm_fdinfo: Parses the drm fdinfo file
@@ -67,6 +84,8 @@ igt_parse_drm_fdinfo(int drm_fd, struct drm_client_fdinfo *info,
  * @info: Structure to populate with read data. Must be zeroed.
  * @name_map: Optional array of strings representing engine names
  * @map_entries: Number of strings in the names array
+ * @region_map: Optional array of strings representing memory regions
+ * @region_entries: Number of strings in the region map
  *
  * Returns the number of valid drm fdinfo keys found or zero if not all
  * mandatory keys were present or no engines found.
@@ -74,6 +93,7 @@ igt_parse_drm_fdinfo(int drm_fd, struct drm_client_fdinfo *info,
 unsigned int
 __igt_parse_drm_fdinfo(int dir, const char *fd,
 		       struct drm_client_fdinfo *info,
-		       const char **name_map, unsigned int map_entries);
+		       const char **name_map, unsigned int map_entries,
+		       const char **region_map, unsigned int region_entries);
 
 #endif /* IGT_DRM_FDINFO_H */
tests/i915/drm_fdinfo.c +4 -4
index c0e0ba1905f1..01526c0e19de 100644
@@ -104,7 +104,7 @@ static void basics(int i915, unsigned int num_classes)
 	unsigned int ret;
 
 	ret = igt_parse_drm_fdinfo(i915, &info, engine_map,
-				   ARRAY_SIZE(engine_map));
+				   ARRAY_SIZE(engine_map), NULL, 0);
 	igt_assert(ret);
 
 	igt_assert(!strcmp(info.driver, "i915"));
@@ -236,7 +236,7 @@ static uint64_t read_busy(int i915, unsigned int class)
 	struct drm_client_fdinfo info = { };
 
 	igt_assert(igt_parse_drm_fdinfo(i915, &info, engine_map,
-					ARRAY_SIZE(engine_map)));
+					ARRAY_SIZE(engine_map), NULL, 0));
 
 	return info.busy[class];
 }
@@ -326,7 +326,7 @@ static void read_busy_all(int i915, uint64_t *val)
 	struct drm_client_fdinfo info = { };
 
 	igt_assert(igt_parse_drm_fdinfo(i915, &info, engine_map,
-					ARRAY_SIZE(engine_map)));
+					ARRAY_SIZE(engine_map), NULL, 0));
 
 	memcpy(val, info.busy, sizeof(info.busy));
 }
@@ -797,7 +797,7 @@ igt_main
 		i915 = __drm_open_driver(DRIVER_INTEL);
 
 		igt_require_gem(i915);
-		igt_require(igt_parse_drm_fdinfo(i915, &info, NULL, 0));
+		igt_require(igt_parse_drm_fdinfo(i915, &info, NULL, 0, NULL, 0));
 
 		ctx = intel_ctx_create_all_physical(i915);
 
tools/intel_gpu_top.c +1 -1
index cef1d3c7fa9f..87e9681e53b4 100644
@@ -2307,7 +2307,7 @@ static bool has_drm_fdinfo(const struct igt_device_card *card)
 	if (fd < 0)
 		return false;
 
-	cnt = igt_parse_drm_fdinfo(fd, &info, NULL, 0);
+	cnt = igt_parse_drm_fdinfo(fd, &info, NULL, 0, NULL, 0);
 
 	close(fd);
 
Signature · 1 line
2.39.2
#3 lore raw

Re: [igt-dev] [Intel-gfx] [PATCH i-g-t 1/3] lib/igt_drm_fdinfo: Parse memory usage

Quoted 9 lines · Kamil Konieczny

Hi Tvrtko,

please check your patches with Linux kernel script checkpatch.pl Some of it's warnings seems strange, like:

WARNING: Co-developed-by and Signed-off-by: name/email do not match #12:

Done.

Quoted 90 lines · Tvrtko Ursulin
Quoted 77 lines

From: Tvrtko Ursulin <[email protected]>

Add parsing and memory storage for the memory usage related fdinfo stats.

Uses the same approach as the engine utilization code by either auto- discovering different memory regions, or allowing for the caller to pass in a map with predefined index to name relationship.

---
  lib/igt_drm_clients.c   |   3 +-
  lib/igt_drm_fdinfo.c    | 142 ++++++++++++++++++++++++++++++++++++++--
  lib/igt_drm_fdinfo.h    |  24 ++++++-
  tests/i915/drm_fdinfo.c |   8 +--
  tools/intel_gpu_top.c   |   2 +-
  5 files changed, 165 insertions(+), 14 deletions(-)
lib/igt_drm_clients.c +2 -1
index f0294ba81c42..fdea42752a81 100644
@@ -491,7 +491,8 @@ igt_drm_clients_scan(struct igt_drm_clients *clients,
 
  			if (!__igt_parse_drm_fdinfo(dirfd(fdinfo_dir),
  						    fdinfo_dent->d_name, &info,
-						    name_map, map_entries))
+						    name_map, map_entries,
+						    NULL, 0))
  				continue;
 
  			if (filter_client && !filter_client(clients, &info))
lib/igt_drm_fdinfo.c +37 -0
index b5f8a8679a71..d08632dfb690 100644
@@ -124,13 +124,81 @@ static const char *find_kv(const char *buf, const char *key, size_t keylen)
  	return *p ? p : NULL;
  }
 
+static int parse_region(char *line, struct drm_client_fdinfo *info,
+			size_t prefix_len,
+			const char **region_map, unsigned int region_entries,
+			uint64_t *val)
+{
+	char *name, *p, *unit = NULL;
+	ssize_t name_len;
+	int found = -1;
+	unsigned int i;
+
+	p = index(line, ':');
+	if (!p || p == line)
+		return -1;
+
+	name_len = p - line - prefix_len;
+	if (name_len < 1)
+		return -1;
+
+	name = line + prefix_len;
+
+	if (region_map) {
+		for (i = 0; i < region_entries; i++) {
+			if (!strncmp(name, region_map[i], name_len)) {
+				found = i;
+				break;
+			}
+		}
+	} else {
+		for (i = 0; i < info->num_regions; i++) {
+			if (!strncmp(name, info->region_names[i], name_len)) {
+				found = i;
+				break;
+			}
+		}
+
+		if (found < 0) {
+			assert((info->num_regions + 1) < ARRAY_SIZE(info->region_names));

lib/igt_drm_fdinfo.c static const char *find_kv(const char *buf, const char *key, size_t keylen) · line 173

Quoted 10 lines
lib/igt_drm_fdinfo.c +10 -0
+			assert((strlen(name) + 1) < sizeof(info->region_names[0]));
+			strncpy(info->region_names[info->num_regions], name, name_len);
+			found = info->num_regions;
+		}
+	}
+
+	if (found < 0)
+		goto out;
+
+	while (*++p && isspace(*p));

---------------------------------- ^
According to checkpatch:

Quoted 2 lines
	while (*++p && isspace(*p))
		;

Done.

Quoted 13 lines

lib/igt_drm_fdinfo.c static const char *find_kv(const char *buf, const char *key, size_t keylen) · line 183

Quoted 11 lines
lib/igt_drm_fdinfo.c +10 -0
+	*val = strtoull(p, NULL, 10);
+
+	p = index(p, ' ');
+	if (!p)
+		goto out;
+
+	unit = ++p;
+	if (!strcmp(unit, "KiB")) {
+		*val *= 1024;
+	} else if (!strcmp(unit, "MiB")) {

------- ^^^^^^
No need for separate 'else':

Quoted 6 lines
	if (!strcmp(unit, "MiB")) {

lib/igt_drm_fdinfo.c static const char *find_kv(const char *buf, const char *key, size_t keylen) · line 185

Quoted 2 lines
lib/igt_drm_fdinfo.c +2 -0
+		*val *= 1024 * 1024;
+	} else if (!strcmp(unit, "GiB")) {

------- ^^^^^^
Same here.

We don't want to run strcmp multiple times for no reason so I opted to leave as is.

Regards,

Tvrtko

Quoted 244 lines

Regards,
Kamil

Quoted 240 lines
lib/igt_drm_fdinfo.c +77 -6
+		*val *= 1024 * 1024 * 1024;
+	}
+
+out:
+	return found;
+}
+
  unsigned int
  __igt_parse_drm_fdinfo(int dir, const char *fd, struct drm_client_fdinfo *info,
-		       const char **name_map, unsigned int map_entries)
+		       const char **name_map, unsigned int map_entries,
+		       const char **region_map, unsigned int region_entries)
  {
+	bool regions_found[DRM_CLIENT_FDINFO_MAX_REGIONS] = { };
+	unsigned int good = 0, num_capacity = 0;
  	char buf[4096], *_buf = buf;
  	char *l, *ctx = NULL;
-	unsigned int good = 0, num_capacity = 0;
  	size_t count;
 
  	count = read_fdinfo(buf, sizeof(buf), dir, fd);
@@ -173,18 +241,79 @@ __igt_parse_drm_fdinfo(int dir, const char *fd, struct drm_client_fdinfo *info,
  				info->capacity[idx] = val;
  				num_capacity++;
  			}
+		} else if (!strncmp(l, "drm-total-", 10)) {
+			idx = parse_region(l, info, strlen("drm-total-"),
+					   region_map, region_entries, &val);
+			if (idx >= 0) {
+				info->region_mem[idx].total = val;
+				if (!regions_found[idx]) {
+					info->num_regions++;
+					regions_found[idx] = true;
+					if (idx > info->last_region_index)
+						info->last_region_index = idx;
+				}
+			}
+		} else if (!strncmp(l, "drm-shared-", 11)) {
+			idx = parse_region(l, info, strlen("drm-shared-"),
+					   region_map, region_entries, &val);
+			if (idx >= 0) {
+				info->region_mem[idx].shared = val;
+				if (!regions_found[idx]) {
+					info->num_regions++;
+					regions_found[idx] = true;
+					if (idx > info->last_region_index)
+						info->last_region_index = idx;
+				}
+			}
+		} else if (!strncmp(l, "drm-resident-", 13)) {
+			idx = parse_region(l, info, strlen("drm-resident-"),
+					   region_map, region_entries, &val);
+			if (idx >= 0) {
+				info->region_mem[idx].resident = val;
+				if (!regions_found[idx]) {
+					info->num_regions++;
+					regions_found[idx] = true;
+					if (idx > info->last_region_index)
+						info->last_region_index = idx;
+				}
+			}
+		} else if (!strncmp(l, "drm-purgeable-", 14)) {
+			idx = parse_region(l, info, strlen("drm-purgeable-"),
+					   region_map, region_entries, &val);
+			if (idx >= 0) {
+				info->region_mem[idx].purgeable = val;
+				if (!regions_found[idx]) {
+					info->num_regions++;
+					regions_found[idx] = true;
+					if (idx > info->last_region_index)
+						info->last_region_index = idx;
+				}
+			}
+		} else if (!strncmp(l, "drm-active-", 11)) {
+			idx = parse_region(l, info, strlen("drm-active-"),
+					   region_map, region_entries, &val);
+			if (idx >= 0) {
+				info->region_mem[idx].active = val;
+				if (!regions_found[idx]) {
+					info->num_regions++;
+					regions_found[idx] = true;
+					if (idx > info->last_region_index)
+						info->last_region_index = idx;
+				}
+			}
  		}
  	}
 
-	if (good < 2 || !info->num_engines)
+	if (good < 2 || (!info->num_engines && !info->num_regions))
  		return 0; /* fdinfo format not as expected */
 
-	return good + info->num_engines + num_capacity;
+	return good + info->num_engines + num_capacity + info->num_regions;
  }
 
  unsigned int
  igt_parse_drm_fdinfo(int drm_fd, struct drm_client_fdinfo *info,
-		     const char **name_map, unsigned int map_entries)
+		     const char **name_map, unsigned int map_entries,
+		     const char **region_map, unsigned int region_entries)
  {
  	unsigned int res;
  	char fd[64];
@@ -198,7 +327,8 @@ igt_parse_drm_fdinfo(int drm_fd, struct drm_client_fdinfo *info,
  	if (dir < 0)
  		return false;
 
-	res = __igt_parse_drm_fdinfo(dir, fd, info, name_map, map_entries);
+	res = __igt_parse_drm_fdinfo(dir, fd, info, name_map, map_entries,
+				     region_map, region_entries);
 
  	close(dir);
 
lib/igt_drm_fdinfo.h +22 -2
index 6284e05e868a..1999c4f2b857 100644
@@ -30,8 +30,17 @@
  #include <stdint.h>
  #include <stdbool.h>
 
+#define DRM_CLIENT_FDINFO_MAX_REGIONS 16
  #define DRM_CLIENT_FDINFO_MAX_ENGINES 16
 
+struct drm_client_meminfo {
+	uint64_t total;
+	uint64_t shared;
+	uint64_t resident;
+	uint64_t purgeable;
+	uint64_t active;
+};
+
  struct drm_client_fdinfo {
  	char driver[128];
  	char pdev[128];
@@ -42,6 +51,11 @@ struct drm_client_fdinfo {
  	unsigned int capacity[DRM_CLIENT_FDINFO_MAX_ENGINES];
  	char names[DRM_CLIENT_FDINFO_MAX_ENGINES][256];
  	uint64_t busy[DRM_CLIENT_FDINFO_MAX_ENGINES];
+
+	unsigned int num_regions;
+	unsigned int last_region_index;
+	char region_names[DRM_CLIENT_FDINFO_MAX_REGIONS][256];
+	struct drm_client_meminfo region_mem[DRM_CLIENT_FDINFO_MAX_REGIONS];
  };
 
  /**
@@ -51,13 +65,16 @@ struct drm_client_fdinfo {
   * @info: Structure to populate with read data. Must be zeroed.
   * @name_map: Optional array of strings representing engine names
   * @map_entries: Number of strings in the names array
+ * @region_map: Optional array of strings representing memory regions
+ * @region_entries: Number of strings in the region map
   *
   * Returns the number of valid drm fdinfo keys found or zero if not all
   * mandatory keys were present or no engines found.
   */
  unsigned int
  igt_parse_drm_fdinfo(int drm_fd, struct drm_client_fdinfo *info,
-		     const char **name_map, unsigned int map_entries);
+		     const char **name_map, unsigned int map_entries,
+		     const char **region_map, unsigned int region_entries);
 
  /**
   * __igt_parse_drm_fdinfo: Parses the drm fdinfo file
@@ -67,6 +84,8 @@ igt_parse_drm_fdinfo(int drm_fd, struct drm_client_fdinfo *info,
   * @info: Structure to populate with read data. Must be zeroed.
   * @name_map: Optional array of strings representing engine names
   * @map_entries: Number of strings in the names array
+ * @region_map: Optional array of strings representing memory regions
+ * @region_entries: Number of strings in the region map
   *
   * Returns the number of valid drm fdinfo keys found or zero if not all
   * mandatory keys were present or no engines found.
@@ -74,6 +93,7 @@ igt_parse_drm_fdinfo(int drm_fd, struct drm_client_fdinfo *info,
  unsigned int
  __igt_parse_drm_fdinfo(int dir, const char *fd,
  		       struct drm_client_fdinfo *info,
-		       const char **name_map, unsigned int map_entries);
+		       const char **name_map, unsigned int map_entries,
+		       const char **region_map, unsigned int region_entries);
 
  #endif /* IGT_DRM_FDINFO_H */
tests/i915/drm_fdinfo.c +4 -4
index c0e0ba1905f1..01526c0e19de 100644
@@ -104,7 +104,7 @@ static void basics(int i915, unsigned int num_classes)
  	unsigned int ret;
 
  	ret = igt_parse_drm_fdinfo(i915, &info, engine_map,
-				   ARRAY_SIZE(engine_map));
+				   ARRAY_SIZE(engine_map), NULL, 0);
  	igt_assert(ret);
 
  	igt_assert(!strcmp(info.driver, "i915"));
@@ -236,7 +236,7 @@ static uint64_t read_busy(int i915, unsigned int class)
  	struct drm_client_fdinfo info = { };
 
  	igt_assert(igt_parse_drm_fdinfo(i915, &info, engine_map,
-					ARRAY_SIZE(engine_map)));
+					ARRAY_SIZE(engine_map), NULL, 0));
 
  	return info.busy[class];
  }
@@ -326,7 +326,7 @@ static void read_busy_all(int i915, uint64_t *val)
  	struct drm_client_fdinfo info = { };
 
  	igt_assert(igt_parse_drm_fdinfo(i915, &info, engine_map,
-					ARRAY_SIZE(engine_map)));
+					ARRAY_SIZE(engine_map), NULL, 0));
 
  	memcpy(val, info.busy, sizeof(info.busy));
  }
@@ -797,7 +797,7 @@ igt_main
  		i915 = __drm_open_driver(DRIVER_INTEL);
 
  		igt_require_gem(i915);
-		igt_require(igt_parse_drm_fdinfo(i915, &info, NULL, 0));
+		igt_require(igt_parse_drm_fdinfo(i915, &info, NULL, 0, NULL, 0));
 
  		ctx = intel_ctx_create_all_physical(i915);
 
tools/intel_gpu_top.c +1 -1
index cef1d3c7fa9f..87e9681e53b4 100644
@@ -2307,7 +2307,7 @@ static bool has_drm_fdinfo(const struct igt_device_card *card)
  	if (fd < 0)
  		return false;
 
-	cnt = igt_parse_drm_fdinfo(fd, &info, NULL, 0);
+	cnt = igt_parse_drm_fdinfo(fd, &info, NULL, 0, NULL, 0);
 
  	close(fd);
 
Signature · 1 line
2.39.2
#4 lore raw

PATCH 2/3 lib/igt_drm_clients: Store memory info in the client

In reply to Tvrtko Ursulin

From: Tvrtko Ursulin <[email protected]>

Define the storage structure and copy over memory data as parsed by the fdinfo helpers.

---
 lib/igt_drm_clients.c | 31 +++++++++++++++++++++++++++++++
 lib/igt_drm_clients.h | 11 +++++++++++
 2 files changed, 42 insertions(+)
lib/igt_drm_clients.c +31 -0
index fdea42752a81..0db5b64effea 100644
@@ -103,6 +103,8 @@ igt_drm_client_update(struct igt_drm_client *c, unsigned int pid, char *name,
 			c->clients->max_name_len = len;
 	}
 
+	/* Engines */
+
 	c->last_runtime = 0;
 	c->total_runtime = 0;
 
@@ -118,6 +120,13 @@ igt_drm_client_update(struct igt_drm_client *c, unsigned int pid, char *name,
 		c->last[i] = info->busy[i];
 	}
 
+	/* Memory regions */
+	for (i = 0; i <= c->regions->max_region_id; i++) {
+		assert(i < ARRAY_SIZE(info->region_mem));
+
+		c->memory[i] = info->region_mem[i];
+	}
+
 	c->samples++;
 	c->status = IGT_DRM_CLIENT_ALIVE;
 }
@@ -154,6 +163,8 @@ igt_drm_client_add(struct igt_drm_clients *clients,
 	c->id = info->id;
 	c->drm_minor = drm_minor;
 	c->clients = clients;
+
+	/* Engines */
 	c->engines = malloc(sizeof(*c->engines));
 	assert(c->engines);
 	memset(c->engines, 0, sizeof(*c->engines));
@@ -178,6 +189,26 @@ igt_drm_client_add(struct igt_drm_clients *clients,
 	c->last = calloc(c->engines->max_engine_id + 1, sizeof(c->last));
 	assert(c->val && c->last);
 
+	/* Memory regions */
+	c->regions = malloc(sizeof(*c->regions));
+	assert(c->regions);
+	memset(c->regions, 0, sizeof(*c->regions));
+	c->regions->names = calloc(info->last_region_index + 1,
+				   sizeof(*c->regions->names));
+	assert(c->regions->names);
+
+	for (i = 0; i <= info->last_region_index; i++) {
+		if (!info->region_names[i])
+			continue;
+
+		c->regions->names[i] = strdup(info->region_names[i]);
+		assert(c->regions->names[i]);
+		c->regions->num_regions++;
+		c->regions->max_region_id = i;
+	}
+	c->memory = calloc(c->regions->max_region_id + 1, sizeof(*c->memory));
+	assert(c->memory);
+
 	igt_drm_client_update(c, pid, name, info);
 }
 
lib/igt_drm_clients.h +11 -0
index ed795c193986..07bd236d43bf 100644
@@ -8,6 +8,8 @@
 
 #include <stdint.h>
 
+#include "lib/igt_drm_fdinfo.h"
+
 /**
  * SECTION:igt_drm_clients
  * @short_description: Parsing driver exposed fdinfo to track DRM clients
@@ -39,12 +41,20 @@ struct igt_drm_client_engines {
 	char **names; /* Array of engine names, either auto-detected or from the passed in engine map. */
 };
 
+struct igt_drm_client_regions {
+	unsigned int num_regions; /* Number of discovered memory_regions. */
+	unsigned int max_region_id; /* Largest memory region index discovered.
+				       (Can differ from num_regions - 1 when using the region map facility.) */
+	char **names; /* Array of region names, either auto-detected or from the passed in region map. */
+};
+
 struct igt_drm_clients;
 
 struct igt_drm_client {
 	struct igt_drm_clients *clients; /* Owning list. */
 
 	enum igt_drm_client_status status;
+	struct igt_drm_client_regions *regions; /* Memory regions present in this client, to map with memory usage. */
 	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. */
@@ -57,6 +67,7 @@ struct igt_drm_client {
 	unsigned long last_runtime; /* Aggregate busyness on all engines since previous scan. */
 	unsigned long *val; /* Array of engine busyness data, relative to previous scan. */
 	uint64_t *last; /* Array of engine busyness data as parsed from fdinfo. */
+	struct drm_client_meminfo *memory; /* Array of region memory utilisation as parsed from fdinfo. */
 };
 
 struct igt_drm_clients {
Signature · 1 line
2.39.2
#5 lore raw

Re: [igt-dev] [Intel-gfx] [PATCH i-g-t 2/3] lib/igt_drm_clients: Store memory info in the client

Hi Tvrtko,

Quoted 52 lines · Tvrtko Ursulin

From: Tvrtko Ursulin <[email protected]>

Define the storage structure and copy over memory data as parsed by the fdinfo helpers.

---
 lib/igt_drm_clients.c | 31 +++++++++++++++++++++++++++++++
 lib/igt_drm_clients.h | 11 +++++++++++
 2 files changed, 42 insertions(+)
lib/igt_drm_clients.c +11 -0
index fdea42752a81..0db5b64effea 100644
@@ -103,6 +103,8 @@ igt_drm_client_update(struct igt_drm_client *c, unsigned int pid, char *name,
 			c->clients->max_name_len = len;
 	}
 
+	/* Engines */
+
 	c->last_runtime = 0;
 	c->total_runtime = 0;
 
@@ -118,6 +120,13 @@ igt_drm_client_update(struct igt_drm_client *c, unsigned int pid, char *name,
 		c->last[i] = info->busy[i];
 	}
 
+	/* Memory regions */
+	for (i = 0; i <= c->regions->max_region_id; i++) {
+		assert(i < ARRAY_SIZE(info->region_mem));
+
+		c->memory[i] = info->region_mem[i];
+	}
+
 	c->samples++;
 	c->status = IGT_DRM_CLIENT_ALIVE;
 }
@@ -154,6 +163,8 @@ igt_drm_client_add(struct igt_drm_clients *clients,
 	c->id = info->id;
 	c->drm_minor = drm_minor;
 	c->clients = clients;
+
+	/* Engines */
 	c->engines = malloc(sizeof(*c->engines));
 	assert(c->engines);
 	memset(c->engines, 0, sizeof(*c->engines));
@@ -178,6 +189,26 @@ igt_drm_client_add(struct igt_drm_clients *clients,
 	c->last = calloc(c->engines->max_engine_id + 1, sizeof(c->last));
 	assert(c->val && c->last);
 

lib/igt_drm_clients.c igt_drm_client_add(struct igt_drm_clients *clients, · line 201

Quoted 10 lines
lib/igt_drm_clients.c +10 -0
+	/* Memory regions */
+	c->regions = malloc(sizeof(*c->regions));
+	assert(c->regions);
+	memset(c->regions, 0, sizeof(*c->regions));
+	c->regions->names = calloc(info->last_region_index + 1,
+				   sizeof(*c->regions->names));
+	assert(c->regions->names);
+
+	for (i = 0; i <= info->last_region_index; i++) {
+		if (!info->region_names[i])

This do not compile:
../lib/igt_drm_clients.c:201:21: error: the comparison will always evaluate as ‘true’ for the address of ‘region_names’ will never be NULL [-Werror=address]
201 | if (!info->region_names[i])
| ^
In file included from ../lib/igt_drm_clients.h:11,

                 from ../lib/igt_drm_clients.c:20:
../lib/igt_drm_fdinfo.h:57:14: note: ‘region_names’ declared here
   57 |         char region_names[DRM_CLIENT_FDINFO_MAX_REGIONS][256];
      |              ^~~~~~~~~~~~

did you mean:

		if (!info->region_names[i][0])

Regards,
Kamil

Quoted 58 lines
lib/igt_drm_clients.c +10 -0
+			continue;
+
+		c->regions->names[i] = strdup(info->region_names[i]);
+		assert(c->regions->names[i]);
+		c->regions->num_regions++;
+		c->regions->max_region_id = i;
+	}
+	c->memory = calloc(c->regions->max_region_id + 1, sizeof(*c->memory));
+	assert(c->memory);
+
 	igt_drm_client_update(c, pid, name, info);
 }
 
lib/igt_drm_clients.h +11 -0
index ed795c193986..07bd236d43bf 100644
@@ -8,6 +8,8 @@
 
 #include <stdint.h>
 
+#include "lib/igt_drm_fdinfo.h"
+
 /**
  * SECTION:igt_drm_clients
  * @short_description: Parsing driver exposed fdinfo to track DRM clients
@@ -39,12 +41,20 @@ struct igt_drm_client_engines {
 	char **names; /* Array of engine names, either auto-detected or from the passed in engine map. */
 };
 
+struct igt_drm_client_regions {
+	unsigned int num_regions; /* Number of discovered memory_regions. */
+	unsigned int max_region_id; /* Largest memory region index discovered.
+				       (Can differ from num_regions - 1 when using the region map facility.) */
+	char **names; /* Array of region names, either auto-detected or from the passed in region map. */
+};
+
 struct igt_drm_clients;
 
 struct igt_drm_client {
 	struct igt_drm_clients *clients; /* Owning list. */
 
 	enum igt_drm_client_status status;
+	struct igt_drm_client_regions *regions; /* Memory regions present in this client, to map with memory usage. */
 	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. */
@@ -57,6 +67,7 @@ struct igt_drm_client {
 	unsigned long last_runtime; /* Aggregate busyness on all engines since previous scan. */
 	unsigned long *val; /* Array of engine busyness data, relative to previous scan. */
 	uint64_t *last; /* Array of engine busyness data as parsed from fdinfo. */
+	struct drm_client_meminfo *memory; /* Array of region memory utilisation as parsed from fdinfo. */
 };
 
 struct igt_drm_clients {
Signature · 1 line
2.39.2
#6 lore raw

Re: [igt-dev] [Intel-gfx] [PATCH i-g-t 2/3] lib/igt_drm_clients: Store memory info in the client

Quoted 71 lines · Kamil Konieczny

Hi Tvrtko,

Quoted 52 lines · Tvrtko Ursulin

From: Tvrtko Ursulin <[email protected]>

Define the storage structure and copy over memory data as parsed by the fdinfo helpers.

---
  lib/igt_drm_clients.c | 31 +++++++++++++++++++++++++++++++
  lib/igt_drm_clients.h | 11 +++++++++++
  2 files changed, 42 insertions(+)
lib/igt_drm_clients.c +11 -0
index fdea42752a81..0db5b64effea 100644
@@ -103,6 +103,8 @@ igt_drm_client_update(struct igt_drm_client *c, unsigned int pid, char *name,
  			c->clients->max_name_len = len;
  	}
 
+	/* Engines */
+
  	c->last_runtime = 0;
  	c->total_runtime = 0;
 
@@ -118,6 +120,13 @@ igt_drm_client_update(struct igt_drm_client *c, unsigned int pid, char *name,
  		c->last[i] = info->busy[i];
  	}
 
+	/* Memory regions */
+	for (i = 0; i <= c->regions->max_region_id; i++) {
+		assert(i < ARRAY_SIZE(info->region_mem));
+
+		c->memory[i] = info->region_mem[i];
+	}
+
  	c->samples++;
  	c->status = IGT_DRM_CLIENT_ALIVE;
  }
@@ -154,6 +163,8 @@ igt_drm_client_add(struct igt_drm_clients *clients,
  	c->id = info->id;
  	c->drm_minor = drm_minor;
  	c->clients = clients;
+
+	/* Engines */
  	c->engines = malloc(sizeof(*c->engines));
  	assert(c->engines);
  	memset(c->engines, 0, sizeof(*c->engines));
@@ -178,6 +189,26 @@ igt_drm_client_add(struct igt_drm_clients *clients,
  	c->last = calloc(c->engines->max_engine_id + 1, sizeof(c->last));
  	assert(c->val && c->last);
 

lib/igt_drm_clients.c igt_drm_client_add(struct igt_drm_clients *clients, · line 201

Quoted 10 lines
lib/igt_drm_clients.c +10 -0
+	/* Memory regions */
+	c->regions = malloc(sizeof(*c->regions));
+	assert(c->regions);
+	memset(c->regions, 0, sizeof(*c->regions));
+	c->regions->names = calloc(info->last_region_index + 1,
+				   sizeof(*c->regions->names));
+	assert(c->regions->names);
+
+	for (i = 0; i <= info->last_region_index; i++) {
+		if (!info->region_names[i])

This do not compile:
../lib/igt_drm_clients.c:201:21: error: the comparison will always evaluate as ‘true’ for the address of ‘region_names’ will never be NULL [-Werror=address]
201 | if (!info->region_names[i])
| ^
In file included from ../lib/igt_drm_clients.h:11,

Quoted 8 lines
                  from ../lib/igt_drm_clients.c:20:
../lib/igt_drm_fdinfo.h:57:14: note: ‘region_names’ declared here
    57 |         char region_names[DRM_CLIENT_FDINFO_MAX_REGIONS][256];
       |              ^~~~~~~~~~~~

did you mean:

		if (!info->region_names[i][0])

Yes. But it's odd.. I can see the error today. But back then I built the thing, ran it, collected the screenshot for the cover letter. Oh well a mystery. Fixed now, thanks!

Regards,

Tvrtko

Quoted 62 lines

Regards,
Kamil

Quoted 58 lines
lib/igt_drm_clients.c +10 -0
+			continue;
+
+		c->regions->names[i] = strdup(info->region_names[i]);
+		assert(c->regions->names[i]);
+		c->regions->num_regions++;
+		c->regions->max_region_id = i;
+	}
+	c->memory = calloc(c->regions->max_region_id + 1, sizeof(*c->memory));
+	assert(c->memory);
+
  	igt_drm_client_update(c, pid, name, info);
  }
 
lib/igt_drm_clients.h +11 -0
index ed795c193986..07bd236d43bf 100644
@@ -8,6 +8,8 @@
 
  #include <stdint.h>
 
+#include "lib/igt_drm_fdinfo.h"
+
  /**
   * SECTION:igt_drm_clients
   * @short_description: Parsing driver exposed fdinfo to track DRM clients
@@ -39,12 +41,20 @@ struct igt_drm_client_engines {
  	char **names; /* Array of engine names, either auto-detected or from the passed in engine map. */
  };
 
+struct igt_drm_client_regions {
+	unsigned int num_regions; /* Number of discovered memory_regions. */
+	unsigned int max_region_id; /* Largest memory region index discovered.
+				       (Can differ from num_regions - 1 when using the region map facility.) */
+	char **names; /* Array of region names, either auto-detected or from the passed in region map. */
+};
+
  struct igt_drm_clients;
 
  struct igt_drm_client {
  	struct igt_drm_clients *clients; /* Owning list. */
 
  	enum igt_drm_client_status status;
+	struct igt_drm_client_regions *regions; /* Memory regions present in this client, to map with memory usage. */
  	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. */
@@ -57,6 +67,7 @@ struct igt_drm_client {
  	unsigned long last_runtime; /* Aggregate busyness on all engines since previous scan. */
  	unsigned long *val; /* Array of engine busyness data, relative to previous scan. */
  	uint64_t *last; /* Array of engine busyness data as parsed from fdinfo. */
+	struct drm_client_meminfo *memory; /* Array of region memory utilisation as parsed from fdinfo. */
  };
 
  struct igt_drm_clients {
Signature · 1 line
2.39.2
#7 lore raw

PATCH 3/3 gputop: Add memory information

In reply to Tvrtko Ursulin

From: Tvrtko Ursulin <[email protected]>

Show total and resident memory usage for clients which support it.

For simplicity all memory regions are summed up and shown under a single heading.

---
 tools/gputop.c | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)
tools/gputop.c +33 -1
index 681f0a6bb748..b5b360cbb063 100644
@@ -28,6 +28,7 @@
 
 #include "igt_drm_clients.h"
 #include "igt_drm_fdinfo.h"
+#include "drmtest.h"
 
 static const char *bars[] = { " ", "▏", "▎", "▍", "▌", "▋", "▊", "▉", "█" };
 
@@ -80,7 +81,11 @@ print_client_header(struct igt_drm_client *c, int lines, int con_w, int con_h,
 		return lines;
 
 	putchar('\n');
-	len = printf("%*s ", c->clients->max_pid_len, "PID");
+	if (c->regions->num_regions)
+		len = printf("%*s      MEM      RSS ",
+			     c->clients->max_pid_len, "PID");
+	else
+		len = printf("%*s ", c->clients->max_pid_len, "PID");
 
 	if (c->engines->num_engines) {
 		unsigned int i;
@@ -121,12 +126,28 @@ newheader(const struct igt_drm_client *c, const struct igt_drm_client *pc)
 	return !pc || c->drm_minor != pc->drm_minor;
 }
 
+static int
+print_size(uint64_t sz)
+{
+	char units[] = {'B', 'K', 'M', 'G'};
+	unsigned u;
+
+	for (u = 0; u < ARRAY_SIZE(units) - 1; u++) {
+		if (sz < 1024)
+			break;
+		sz /= 1024;
+	}
+
+	return printf("%7"PRIu64"%c ", sz, units[u]);
+}
+
 static int
 print_client(struct igt_drm_client *c, struct igt_drm_client **prevc,
 	     double t, int lines, int con_w, int con_h,
 	     unsigned int period_us, int *engine_w)
 {
 	unsigned int i;
+	uint64_t sz;
 	int len;
 
 	/* Filter out idle clients. */
@@ -143,6 +164,17 @@ print_client(struct igt_drm_client *c, struct igt_drm_client **prevc,
 	*prevc = c;
 
 	len = printf("%*s ", c->clients->max_pid_len, c->pid_str);
+
+	if (c->regions->num_regions) {
+		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);
+	}
+
 	lines++;
 
 	for (i = 0; c->samples > 1 && i <= c->engines->max_engine_id; i++) {
Signature · 1 line
2.39.2
#8 lore raw

Re: [igt-dev] [Intel-gfx] [PATCH i-g-t 3/3] gputop: Add memory information

Hi Tvrtko,

Quoted 39 lines · Tvrtko Ursulin

From: Tvrtko Ursulin <[email protected]>

Show total and resident memory usage for clients which support it.

For simplicity all memory regions are summed up and shown under a single heading.

---
 tools/gputop.c | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)
tools/gputop.c +6 -1
index 681f0a6bb748..b5b360cbb063 100644
@@ -28,6 +28,7 @@
 
 #include "igt_drm_clients.h"
 #include "igt_drm_fdinfo.h"
+#include "drmtest.h"
 
 static const char *bars[] = { " ", "▏", "▎", "▍", "▌", "▋", "▊", "▉", "█" };
 
@@ -80,7 +81,11 @@ print_client_header(struct igt_drm_client *c, int lines, int con_w, int con_h,
 		return lines;
 
 	putchar('\n');
-	len = printf("%*s ", c->clients->max_pid_len, "PID");
+	if (c->regions->num_regions)
+		len = printf("%*s      MEM      RSS ",
+			     c->clients->max_pid_len, "PID");
+	else
+		len = printf("%*s ", c->clients->max_pid_len, "PID");
 
 	if (c->engines->num_engines) {
 		unsigned int i;

tools/gputop.c newheader(const struct igt_drm_client *c, const struct igt_drm_client *pc) · line 133

Quoted 8 lines
tools/gputop.c +5 -0
@@ -121,12 +126,28 @@ newheader(const struct igt_drm_client *c, const struct igt_drm_client *pc)
 	return !pc || c->drm_minor != pc->drm_minor;
 }
 
+static int
+print_size(uint64_t sz)
+{
+	char units[] = {'B', 'K', 'M', 'G'};
+	unsigned u;

------- ^
Better:

	unsigned int u;

With that add my r-b tag,

Regards,
Kamil

Quoted 41 lines
tools/gputop.c +22 -0
+
+	for (u = 0; u < ARRAY_SIZE(units) - 1; u++) {
+		if (sz < 1024)
+			break;
+		sz /= 1024;
+	}
+
+	return printf("%7"PRIu64"%c ", sz, units[u]);
+}
+
 static int
 print_client(struct igt_drm_client *c, struct igt_drm_client **prevc,
 	     double t, int lines, int con_w, int con_h,
 	     unsigned int period_us, int *engine_w)
 {
 	unsigned int i;
+	uint64_t sz;
 	int len;
 
 	/* Filter out idle clients. */
@@ -143,6 +164,17 @@ print_client(struct igt_drm_client *c, struct igt_drm_client **prevc,
 	*prevc = c;
 
 	len = printf("%*s ", c->clients->max_pid_len, c->pid_str);
+
+	if (c->regions->num_regions) {
+		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);
+	}
+
 	lines++;
 
 	for (i = 0; c->samples > 1 && i <= c->engines->max_engine_id; i++) {
Signature · 1 line
2.39.2
#9 lore raw

Re: [igt-dev] [Intel-gfx] [PATCH i-g-t 3/3] gputop: Add memory information

Quoted 52 lines · Kamil Konieczny

Hi Tvrtko,

Quoted 39 lines · Tvrtko Ursulin

From: Tvrtko Ursulin <[email protected]>

Show total and resident memory usage for clients which support it.

For simplicity all memory regions are summed up and shown under a single heading.

---
  tools/gputop.c | 34 +++++++++++++++++++++++++++++++++-
  1 file changed, 33 insertions(+), 1 deletion(-)
tools/gputop.c +6 -1
index 681f0a6bb748..b5b360cbb063 100644
@@ -28,6 +28,7 @@
 
  #include "igt_drm_clients.h"
  #include "igt_drm_fdinfo.h"
+#include "drmtest.h"
 
  static const char *bars[] = { " ", "▏", "▎", "▍", "▌", "▋", "▊", "▉", "█" };
 
@@ -80,7 +81,11 @@ print_client_header(struct igt_drm_client *c, int lines, int con_w, int con_h,
  		return lines;
 
  	putchar('\n');
-	len = printf("%*s ", c->clients->max_pid_len, "PID");
+	if (c->regions->num_regions)
+		len = printf("%*s      MEM      RSS ",
+			     c->clients->max_pid_len, "PID");
+	else
+		len = printf("%*s ", c->clients->max_pid_len, "PID");
 
  	if (c->engines->num_engines) {
  		unsigned int i;

tools/gputop.c newheader(const struct igt_drm_client *c, const struct igt_drm_client *pc) · line 133

Quoted 8 lines
tools/gputop.c +5 -0
@@ -121,12 +126,28 @@ newheader(const struct igt_drm_client *c, const struct igt_drm_client *pc)
  	return !pc || c->drm_minor != pc->drm_minor;
  }
 
+static int
+print_size(uint64_t sz)
+{
+	char units[] = {'B', 'K', 'M', 'G'};
+	unsigned u;

------- ^
Better:

Quoted 3 lines
	unsigned int u;

With that add my r-b tag,

Okay, thanks, re-send will be coming shortly, just some final smoke tests to do.

Regards,

Tvrtko

Quoted 45 lines

Regards,
Kamil

Quoted 41 lines
tools/gputop.c +22 -0
+
+	for (u = 0; u < ARRAY_SIZE(units) - 1; u++) {
+		if (sz < 1024)
+			break;
+		sz /= 1024;
+	}
+
+	return printf("%7"PRIu64"%c ", sz, units[u]);
+}
+
  static int
  print_client(struct igt_drm_client *c, struct igt_drm_client **prevc,
  	     double t, int lines, int con_w, int con_h,
  	     unsigned int period_us, int *engine_w)
  {
  	unsigned int i;
+	uint64_t sz;
  	int len;
 
  	/* Filter out idle clients. */
@@ -143,6 +164,17 @@ print_client(struct igt_drm_client *c, struct igt_drm_client **prevc,
  	*prevc = c;
 
  	len = printf("%*s ", c->clients->max_pid_len, c->pid_str);
+
+	if (c->regions->num_regions) {
+		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);
+	}
+
  	lines++;
 
  	for (i = 0; c->samples > 1 && i <= c->engines->max_engine_id; i++) {
Signature · 1 line
2.39.2
#10 lore raw

[igt-dev] ✗ Fi.CI.BAT: failure for gputop memory usage

In reply to Tvrtko Ursulin
== Series Details ==

== Series Details ==

Series: gputop memory usage
URL : https://patchwork.freedesktop.org/series/120239/
State : failure

== Summary ==

CI Bug Log - changes from IGT_7371 -> IGTPW_9343
====================================================

Summary
-------

**FAILURE**

Serious unknown changes coming with IGTPW_9343 absolutely need to be verified manually.

If you think the reported changes have nothing to do with the changes introduced in IGTPW_9343, please notify your bug team to allow them to document this new failure mode, which will reduce false positives in CI.

External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/index.html

Participating hosts (40 -> 40)
------------------------------

Additional (1): bat-atsm-1
Missing (1): fi-snb-2520m

Possible new issues
-------------------

Here are the unknown changes that may have been introduced in IGTPW_9343:

### IGT changes ###

#### Possible regressions ####

* igt@i915_module_load@load:
- bat-dg2-9: [PASS][1] -> [DMESG-WARN][2]
[1]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_7371/bat-dg2-9/igt@[email protected]
[2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/bat-dg2-9/igt@[email protected]

Known issues
------------

Here are the changes found in IGTPW_9343 that come from known issues:

### IGT changes ###

#### Issues hit ####

* igt@gem_mmap@basic:
- bat-atsm-1: NOTRUN -> [SKIP][3] ([i915#4083])
[3]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/bat-atsm-1/igt@[email protected]

* igt@gem_render_tiled_blits@basic:
- bat-atsm-1: NOTRUN -> [SKIP][4] ([i915#4079]) +1 similar issue
[4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/bat-atsm-1/igt@[email protected]

* igt@gem_tiled_fence_blits@basic:
- bat-atsm-1: NOTRUN -> [SKIP][5] ([i915#4077]) +2 similar issues
[5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/bat-atsm-1/igt@[email protected]

* igt@i915_pm_rps@basic-api:
- bat-atsm-1: NOTRUN -> [SKIP][6] ([i915#6621])
[6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/bat-atsm-1/igt@[email protected]

* igt@i915_selftest@live@execlists:
- fi-bsw-nick: [PASS][7] -> [ABORT][8] ([i915#7911] / [i915#7913])
[7]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_7371/fi-bsw-nick/igt@i915_selftest@[email protected]
[8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/fi-bsw-nick/igt@i915_selftest@[email protected]

* igt@i915_selftest@live@gt_heartbeat:
- fi-apl-guc: [PASS][9] -> [DMESG-FAIL][10] ([i915#5334])
[9]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_7371/fi-apl-guc/igt@i915_selftest@live@gt_heartbeat.html
[10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/fi-apl-guc/igt@i915_selftest@live@gt_heartbeat.html

* igt@i915_selftest@live@gt_pm:
- bat-rpls-2: [PASS][11] -> [DMESG-FAIL][12] ([i915#4258] / [i915#7913])
[11]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_7371/bat-rpls-2/igt@i915_selftest@live@gt_pm.html
[12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/bat-rpls-2/igt@i915_selftest@live@gt_pm.html

* igt@i915_selftest@live@mman:
- bat-rpls-1: [PASS][13] -> [TIMEOUT][14] ([i915#6794] / [i915#7392])
[13]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_7371/bat-rpls-1/igt@i915_selftest@[email protected]
[14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/bat-rpls-1/igt@i915_selftest@[email protected]

* igt@i915_selftest@live@requests:
- bat-mtlp-8: [PASS][15] -> [ABORT][16] ([i915#7982])
[15]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_7371/bat-mtlp-8/igt@i915_selftest@[email protected]
[16]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/bat-mtlp-8/igt@i915_selftest@[email protected]

* igt@i915_selftest@live@reset:
- bat-rpls-2: [PASS][17] -> [ABORT][18] ([i915#4983] / [i915#7461] / [i915#7913] / [i915#7981] / [i915#8347])
[17]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_7371/bat-rpls-2/igt@i915_selftest@[email protected]
[18]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/bat-rpls-2/igt@i915_selftest@[email protected]

* igt@i915_selftest@live@slpc:
- bat-mtlp-6: [PASS][19] -> [DMESG-WARN][20] ([i915#6367])
[19]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_7371/bat-mtlp-6/igt@i915_selftest@[email protected]
[20]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/bat-mtlp-6/igt@i915_selftest@[email protected]

* igt@i915_suspend@basic-s2idle-without-i915:
- bat-rpls-1: [PASS][21] -> [WARN][22] ([i915#8747])
[21]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_7371/bat-rpls-1/igt@[email protected]
[22]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/bat-rpls-1/igt@[email protected]

* igt@i915_suspend@basic-s3-without-i915:
- bat-atsm-1: NOTRUN -> [SKIP][23] ([i915#6645])
[23]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/bat-atsm-1/igt@[email protected]

* igt@kms_addfb_basic@size-max:
- bat-atsm-1: NOTRUN -> [SKIP][24] ([i915#6077]) +36 similar issues
[24]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/bat-atsm-1/igt@[email protected]

* igt@kms_chamelium_hpd@common-hpd-after-suspend:
- fi-glk-j4005: NOTRUN -> [SKIP][25] ([fdo#109271])
[25]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/fi-glk-j4005/igt@[email protected]
- fi-bsw-n3050: NOTRUN -> [SKIP][26] ([fdo#109271])
[26]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/fi-bsw-n3050/igt@[email protected]

* igt@kms_cursor_legacy@basic-flip-after-cursor-atomic:
- bat-atsm-1: NOTRUN -> [SKIP][27] ([i915#6078]) +19 similar issues
[27]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/bat-atsm-1/igt@[email protected]

* igt@kms_flip@basic-flip-vs-wf_vblank:
- bat-atsm-1: NOTRUN -> [SKIP][28] ([i915#6166]) +3 similar issues
[28]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/bat-atsm-1/igt@kms_flip@basic-flip-vs-wf_vblank.html

* igt@kms_force_connector_basic@force-load-detect:
- bat-atsm-1: NOTRUN -> [SKIP][29] ([i915#6093]) +3 similar issues
[29]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/bat-atsm-1/igt@[email protected]

* igt@kms_pipe_crc_basic@read-crc-frame-sequence:
- bat-atsm-1: NOTRUN -> [SKIP][30] ([i915#1836]) +6 similar issues
[30]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/bat-atsm-1/igt@[email protected]

* igt@kms_pipe_crc_basic@read-crc-frame-sequence@pipe-d-edp-1:
- bat-rplp-1: [PASS][31] -> [ABORT][32] ([i915#8442] / [i915#8668])
[31]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_7371/bat-rplp-1/igt@kms_pipe_crc_basic@[email protected]
[32]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/bat-rplp-1/igt@kms_pipe_crc_basic@[email protected]

* igt@kms_prop_blob@basic:
- bat-atsm-1: NOTRUN -> [SKIP][33] ([i915#7357])
[33]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/bat-atsm-1/igt@[email protected]

* igt@kms_psr@sprite_plane_onoff:
- bat-atsm-1: NOTRUN -> [SKIP][34] ([i915#1072]) +3 similar issues
[34]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/bat-atsm-1/igt@kms_psr@sprite_plane_onoff.html

* igt@kms_setmode@basic-clone-single-crtc:
- bat-atsm-1: NOTRUN -> [SKIP][35] ([i915#6094])
[35]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/bat-atsm-1/igt@[email protected]

* igt@prime_vgem@basic-fence-flip:
- bat-atsm-1: NOTRUN -> [SKIP][36] ([fdo#109295] / [i915#6078])
[36]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/bat-atsm-1/igt@[email protected]

* igt@prime_vgem@basic-gtt:
- bat-atsm-1: NOTRUN -> [SKIP][37] ([fdo#109295] / [i915#4077]) +1 similar issue
[37]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/bat-atsm-1/igt@[email protected]

* igt@prime_vgem@basic-write:
- bat-atsm-1: NOTRUN -> [SKIP][38] ([fdo#109295]) +2 similar issues
[38]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/bat-atsm-1/igt@[email protected]

#### Possible fixes ####

* igt@dmabuf@all-tests@dma_fence:
- fi-glk-j4005: [DMESG-FAIL][39] ([i915#8189]) -> [PASS][40]
[39]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_7371/fi-glk-j4005/igt@dmabuf@all-tests@dma_fence.html
[40]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/fi-glk-j4005/igt@dmabuf@all-tests@dma_fence.html

* igt@dmabuf@all-tests@sanitycheck:
- fi-glk-j4005: [ABORT][41] ([i915#8143] / [i915#8144] / [i915#8218]) -> [PASS][42]
[41]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_7371/fi-glk-j4005/igt@dmabuf@[email protected]
[42]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/fi-glk-j4005/igt@dmabuf@[email protected]

* igt@i915_selftest@live@execlists:
- fi-bsw-n3050: [ABORT][43] ([i915#7913]) -> [PASS][44]
[43]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_7371/fi-bsw-n3050/igt@i915_selftest@[email protected]
[44]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/fi-bsw-n3050/igt@i915_selftest@[email protected]

* igt@i915_selftest@live@gt_mocs:
- bat-mtlp-8: [DMESG-FAIL][45] ([i915#7059]) -> [PASS][46]
[45]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_7371/bat-mtlp-8/igt@i915_selftest@live@gt_mocs.html
[46]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/bat-mtlp-8/igt@i915_selftest@live@gt_mocs.html

{name}: This element is suppressed. This means it is ignored when computing
the status of the difference (SUCCESS, WARNING, or FAILURE).

[fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
[fdo#109295]: https://bugs.freedesktop.org/show_bug.cgi?id=109295
[i915#1072]: https://gitlab.freedesktop.org/drm/intel/issues/1072
[i915#1836]: https://gitlab.freedesktop.org/drm/intel/issues/1836
[i915#4077]: https://gitlab.freedesktop.org/drm/intel/issues/4077
[i915#4079]: https://gitlab.freedesktop.org/drm/intel/issues/4079
[i915#4083]: https://gitlab.freedesktop.org/drm/intel/issues/4083
[i915#4258]: https://gitlab.freedesktop.org/drm/intel/issues/4258
[i915#4983]: https://gitlab.freedesktop.org/drm/intel/issues/4983
[i915#5334]: https://gitlab.freedesktop.org/drm/intel/issues/5334
[i915#6077]: https://gitlab.freedesktop.org/drm/intel/issues/6077
[i915#6078]: https://gitlab.freedesktop.org/drm/intel/issues/6078
[i915#6093]: https://gitlab.freedesktop.org/drm/intel/issues/6093
[i915#6094]: https://gitlab.freedesktop.org/drm/intel/issues/6094
[i915#6166]: https://gitlab.freedesktop.org/drm/intel/issues/6166
[i915#6367]: https://gitlab.freedesktop.org/drm/intel/issues/6367
[i915#6621]: https://gitlab.freedesktop.org/drm/intel/issues/6621
[i915#6645]: https://gitlab.freedesktop.org/drm/intel/issues/6645
[i915#6794]: https://gitlab.freedesktop.org/drm/intel/issues/6794
[i915#7059]: https://gitlab.freedesktop.org/drm/intel/issues/7059
[i915#7357]: https://gitlab.freedesktop.org/drm/intel/issues/7357
[i915#7392]: https://gitlab.freedesktop.org/drm/intel/issues/7392
[i915#7461]: https://gitlab.freedesktop.org/drm/intel/issues/7461
[i915#7911]: https://gitlab.freedesktop.org/drm/intel/issues/7911
[i915#7913]: https://gitlab.freedesktop.org/drm/intel/issues/7913
[i915#7981]: https://gitlab.freedesktop.org/drm/intel/issues/7981
[i915#7982]: https://gitlab.freedesktop.org/drm/intel/issues/7982
[i915#8143]: https://gitlab.freedesktop.org/drm/intel/issues/8143
[i915#8144]: https://gitlab.freedesktop.org/drm/intel/issues/8144
[i915#8189]: https://gitlab.freedesktop.org/drm/intel/issues/8189
[i915#8218]: https://gitlab.freedesktop.org/drm/intel/issues/8218
[i915#8347]: https://gitlab.freedesktop.org/drm/intel/issues/8347
[i915#8442]: https://gitlab.freedesktop.org/drm/intel/issues/8442
[i915#8668]: https://gitlab.freedesktop.org/drm/intel/issues/8668
[i915#8747]: https://gitlab.freedesktop.org/drm/intel/issues/8747

Build changes
-------------

* CI: CI-20190529 -> None
* IGT: IGT_7371 -> IGTPW_9343

CI-20190529: 20190529
CI_DRM_13346: c5442b2363bf5ad916805d105ff03ce5805070e5 @ git://anongit.freedesktop.org/gfx-ci/linux
IGTPW_9343: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/index.html
IGT_7371: f8d05fd574fad1526cbf5e20672910df87b8839b @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9343/index.html