From 5b4ef81f2b79dd5d597b1681de4d0311d46693aa Mon Sep 17 00:00:00 2001 From: Adam Lesinski Date: Mon, 23 Sep 2013 10:06:09 -0700 Subject: Add Graphics alloc tracking via memtrack Any OpenGL memory reported by /proc/pid/smaps will not be included in the GPU GL memory count and will be considered Unknown. This is an artifact of how some memory reporting is done in libmemtrack and some is done in this module. bug:10294768 Change-Id: Id8fb63b2e86520f4dbc8410573a509e66b96b13b --- core/java/android/os/Debug.java | 16 +++-- core/jni/Android.mk | 1 + core/jni/android_os_Debug.cpp | 141 +++++++++++++++++++++++----------------- 3 files changed, 91 insertions(+), 67 deletions(-) (limited to 'core') diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java index 0c718f4..3adfe0a 100644 --- a/core/java/android/os/Debug.java +++ b/core/java/android/os/Debug.java @@ -158,7 +158,7 @@ public final class Debug public int otherSharedClean; /** @hide */ - public static final int NUM_OTHER_STATS = 14; + public static final int NUM_OTHER_STATS = 16; /** @hide */ public static final int NUM_DVK_STATS = 5; @@ -285,12 +285,14 @@ public final class Debug case 10: return "code mmap"; case 11: return "image mmap"; case 12: return "Other mmap"; - case 13: return "GPU"; - case 14: return ".Heap"; - case 15: return ".LOS"; - case 16: return ".LinearAlloc"; - case 17: return ".GC"; - case 18: return ".JITCache"; + case 13: return "Graphics"; + case 14: return "GL"; + case 15: return "Other memtrack"; + case 16: return ".Heap"; + case 17: return ".LOS"; + case 18: return ".LinearAlloc"; + case 19: return ".GC"; + case 20: return ".JITCache"; default: return "????"; } } diff --git a/core/jni/Android.mk b/core/jni/Android.mk index f78d807..e09fcff 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -178,6 +178,7 @@ LOCAL_C_INCLUDES += \ libcore/include LOCAL_SHARED_LIBRARIES := \ + libmemtrack \ libandroidfw \ libexpat \ libnativehelper \ diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp index 60540f4..ff14a7e 100644 --- a/core/jni/android_os_Debug.cpp +++ b/core/jni/android_os_Debug.cpp @@ -20,6 +20,7 @@ #include #include "utils/misc.h" #include "cutils/debugger.h" +#include #include #include @@ -57,7 +58,9 @@ enum { HEAP_OAT, HEAP_ART, HEAP_UNKNOWN_MAP, - HEAP_GPU, + HEAP_GRAPHICS, + HEAP_GL, + HEAP_OTHER_MEMTRACK, HEAP_DALVIK_NORMAL, HEAP_DALVIK_LARGE, @@ -66,7 +69,7 @@ enum { HEAP_DALVIK_CODE_CACHE, _NUM_HEAP, - _NUM_EXCLUSIVE_HEAP = HEAP_GPU+1, + _NUM_EXCLUSIVE_HEAP = HEAP_OTHER_MEMTRACK+1, _NUM_CORE_HEAP = HEAP_NATIVE+1 }; @@ -98,6 +101,8 @@ static stat_field_names stat_field_names[_NUM_CORE_HEAP] = { jfieldID otherStats_field; +static bool memtrackLoaded; + struct stats_t { int pss; int swappablePss; @@ -139,70 +144,68 @@ static jlong android_os_Debug_getNativeHeapFreeSize(JNIEnv *env, jobject clazz) #endif } -// XXX Qualcom-specific! -static jlong read_gpu_mem(int pid) +// Container used to retrieve graphics memory pss +struct graphics_memory_pss { - char line[1024]; - jlong uss = 0; - unsigned temp; - - char tmp[128]; - FILE *fp; + int graphics; + int gl; + int other; +}; - sprintf(tmp, "/d/kgsl/proc/%d/mem", pid); - fp = fopen(tmp, "r"); - if (fp == 0) { - //ALOGI("Unable to open: %s", tmp); - return 0; +/* + * Uses libmemtrack to retrieve graphics memory that the process is using. + * Any graphics memory reported in /proc/pid/smaps is not included here. + */ +static int read_memtrack_memory(struct memtrack_proc* p, int pid, struct graphics_memory_pss* graphics_mem) +{ + int err = memtrack_proc_get(p, pid); + if (err != 0) { + ALOGE("failed to get memory consumption info: %d", err); + return err; } - while (true) { - if (fgets(line, 1024, fp) == NULL) { - break; - } - - //ALOGI("Read: %s", line); + ssize_t pss = memtrack_proc_graphics_pss(p); + if (pss < 0) { + ALOGE("failed to get graphics pss: %d", pss); + return pss; + } + graphics_mem->graphics = pss / 1024; - // Format is: - // gpuaddr useraddr size id flags type usage sglen - // 54676000 54676000 4096 1 ----p gpumem arraybuffer 1 - // - // If useraddr is 0, this is gpu mem not otherwise accounted - // against the process. + pss = memtrack_proc_gl_pss(p); + if (pss < 0) { + ALOGE("failed to get gl pss: %d", pss); + return pss; + } + graphics_mem->gl = pss / 1024; - // Make sure line is long enough. - int i = 0; - while (i < 9) { - if (line[i] == 0) { - break; - } - i++; - } - if (i < 9) { - //ALOGI("Early line term!"); - continue; - } + pss = memtrack_proc_other_pss(p); + if (pss < 0) { + ALOGE("failed to get other pss: %d", pss); + return pss; + } + graphics_mem->other = pss / 1024; - // Look to see if useraddr is 00000000. - while (i < 17) { - if (line[i] != '0') { - break; - } - i++; - } - if (i < 17) { - //ALOGI("useraddr not 0!"); - continue; - } + return 0; +} - uss += atoi(line + i); - //ALOGI("Uss now: %ld", uss); +/* + * Retrieves the graphics memory that is unaccounted for in /proc/pid/smaps. + */ +static int read_memtrack_memory(int pid, struct graphics_memory_pss* graphics_mem) +{ + if (!memtrackLoaded) { + return -1; } - fclose(fp); + struct memtrack_proc* p = memtrack_proc_new(); + if (p == NULL) { + ALOGE("failed to create memtrack_proc"); + return -1; + } - // Convert from bytes to KB. - return uss / 1024; + int err = read_memtrack_memory(p, pid, graphics_mem); + memtrack_proc_destroy(p); + return err; } static void read_mapinfo(FILE *fp, stats_t* stats) @@ -405,12 +408,19 @@ static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, stats_t stats[_NUM_HEAP]; memset(&stats, 0, sizeof(stats)); - load_maps(pid, stats); - jlong gpu = read_gpu_mem(pid); - stats[HEAP_GPU].pss += gpu; - stats[HEAP_GPU].privateDirty += gpu; + struct graphics_memory_pss graphics_mem; + if (read_memtrack_memory(pid, &graphics_mem) == 0) { + stats[HEAP_GRAPHICS].pss = graphics_mem.graphics; + stats[HEAP_GRAPHICS].privateDirty = graphics_mem.graphics; + stats[HEAP_GL].pss = graphics_mem.gl; + stats[HEAP_GL].privateDirty = graphics_mem.gl; + stats[HEAP_OTHER_MEMTRACK].pss = graphics_mem.other; + stats[HEAP_OTHER_MEMTRACK].privateDirty = graphics_mem.other; + } else { + ALOGE("Failed to read gpu memory"); + } for (int i=_NUM_CORE_HEAP; i<_NUM_EXCLUSIVE_HEAP; i++) { stats[HEAP_UNKNOWN].pss += stats[i].pss; @@ -466,7 +476,10 @@ static jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid, jl char tmp[128]; FILE *fp; - pss = uss = read_gpu_mem(pid); + struct graphics_memory_pss graphics_mem; + if (read_memtrack_memory(pid, &graphics_mem) == 0) { + pss = uss = graphics_mem.graphics + graphics_mem.gl + graphics_mem.other; + } sprintf(tmp, "/proc/%d/smaps", pid); fp = fopen(tmp, "r"); @@ -891,6 +904,14 @@ static JNINativeMethod gMethods[] = { int register_android_os_Debug(JNIEnv *env) { + int err = memtrack_init(); + if (err != 0) { + memtrackLoaded = false; + ALOGE("failed to load memtrack module: %d", err); + } else { + memtrackLoaded = true; + } + jclass clazz = env->FindClass("android/os/Debug$MemoryInfo"); // Sanity check the number of other statistics expected in Java matches here. -- cgit v1.1