libmemtrack: avoid counting surfaceflinger buffers twice
The system wide Graphics memory usage is inaccurate because some ION
buffers which are shared between processes are counted twice, once for
the buffer's consumer (surfaceflinger), and again for the producer.
These ION buffers appear in surfaceflinger's kgsl memory dump with
usage=egl_image, and in the producer's dump with usage=egl_surface.
Improve the accuracy of Graphics memory tracking by ignoring all ION
buffers with usage=egl_image in the surfaceflinger process, under the
assumption that the buffers will be accounted for when examining the
producer's process.
Change-Id: I764c610f226d41e2897d6e0c2247793b0e321ed0
Signed-off-by: Fred Fettinger <fred.fettinger@motorola.com>
diff --git a/libmemtrack/kgsl.c b/libmemtrack/kgsl.c
index b644d73..208b22f 100644
--- a/libmemtrack/kgsl.c
+++ b/libmemtrack/kgsl.c
@@ -49,6 +49,7 @@
FILE *fp;
char line[1024];
char tmp[128];
+ bool is_surfaceflinger = false;
size_t accounted_size = 0;
size_t unaccounted_size = 0;
unsigned long smaps_addr = 0;
@@ -60,6 +61,16 @@
return 0;
}
+ snprintf(tmp, sizeof(tmp), "/proc/%d/cmdline", pid);
+ fp = fopen(tmp, "r");
+ if (fp != NULL) {
+ if (fgets(line, sizeof(line), fp)) {
+ if (strcmp(line, "/system/bin/surfaceflinger") == 0)
+ is_surfaceflinger = true;
+ }
+ fclose(fp);
+ }
+
memcpy(records, record_templates,
sizeof(struct memtrack_record) * allocated_records);
@@ -77,6 +88,7 @@
unsigned long size;
char line_type[7];
char flags[7];
+ char line_usage[19];
int ret;
if (fgets(line, sizeof(line), fp) == NULL) {
@@ -87,9 +99,9 @@
* gpuaddr useraddr size id flags type usage sglen
* 545ba000 545ba000 4096 1 ----pY gpumem arraybuffer 1
*/
- ret = sscanf(line, "%*x %*x %lu %*d %6s %6s %*s %*d\n",
- &size, flags, line_type);
- if (ret != 3) {
+ ret = sscanf(line, "%*x %*lx %lu %*d %6s %6s %18s %*d\n",
+ &size, flags, line_type, line_usage);
+ if (ret != 4) {
continue;
}
@@ -101,7 +113,9 @@
unaccounted_size += size;
} else if (type == MEMTRACK_TYPE_GRAPHICS && strcmp(line_type, "ion") == 0) {
- unaccounted_size += size;
+ if (!is_surfaceflinger || strcmp(line_usage, "egl_image") != 0) {
+ unaccounted_size += size;
+ }
}
}