Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5b4ef81f authored by Adam Lesinski's avatar Adam Lesinski
Browse files

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
parent a9f97a0a
Loading
Loading
Loading
Loading
+9 −7
Original line number Diff line number Diff line
@@ -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 "????";
            }
        }
+1 −0
Original line number Diff line number Diff line
@@ -178,6 +178,7 @@ LOCAL_C_INCLUDES += \
	libcore/include

LOCAL_SHARED_LIBRARIES := \
	libmemtrack \
	libandroidfw \
	libexpat \
	libnativehelper \
+81 −60
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <utils/String8.h>
#include "utils/misc.h"
#include "cutils/debugger.h"
#include <memtrack/memtrack.h>

#include <cutils/log.h>
#include <fcntl.h>
@@ -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;
    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;

        //ALOGI("Read: %s", line);

        // 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.

        // 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_gl_pss(p);
    if (pss < 0) {
        ALOGE("failed to get gl pss: %d", pss);
        return pss;
    }
    graphics_mem->gl = pss / 1024;

        // Look to see if useraddr is 00000000.
        while (i < 17) {
            if (line[i] != '0') {
                break;
            }
            i++;
    pss = memtrack_proc_other_pss(p);
    if (pss < 0) {
        ALOGE("failed to get other pss: %d", pss);
        return pss;
    }
        if (i < 17) {
            //ALOGI("useraddr not 0!");
            continue;
    graphics_mem->other = pss / 1024;

    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.