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

Commit 5ded8c13 authored by Suren Baghdasaryan's avatar Suren Baghdasaryan Committed by Gerrit Code Review
Browse files

Merge changes from topic "ion memory accounting"

* changes:
  Add ION usage into dumpsys report and account ION pools as kernel cache
  Improve cached kernel memory accounting using meminfo KReclaimable field
  Add JNI API to query sizes of ION heaps, pools and mapped part of the heaps
parents 073b0dad da5a9dd5
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -2503,4 +2503,27 @@ public final class Debug
     * @hide
     */
    public static native long getZramFreeKb();

    /**
     * Return memory size in kilobytes allocated for ION heaps.
     *
     * @hide
     */
    public static native long getIonHeapsSizeKb();

    /**
     * Return memory size in kilobytes allocated for ION pools.
     *
     * @hide
     */
    public static native long getIonPoolsSizeKb();

    /**
     * Return ION memory mapped by processes in kB.
     * Notes:
     *  * Warning: Might impact performance as it reads /proc/<pid>/maps files for each process.
     *
     * @hide
     */
    public static native long getIonMappedSizeKb();
}
+9 −1
Original line number Diff line number Diff line
@@ -91,7 +91,15 @@ public final class MemInfoReader {
     * that are mapped in to processes.
     */
    public long getCachedSizeKb() {
        return mInfos[Debug.MEMINFO_BUFFERS] + mInfos[Debug.MEMINFO_SLAB_RECLAIMABLE]
        long kReclaimable = mInfos[Debug.MEMINFO_KRECLAIMABLE];

        // Note: MEMINFO_KRECLAIMABLE includes MEMINFO_SLAB_RECLAIMABLE and ION pools.
        // Fall back to using MEMINFO_SLAB_RECLAIMABLE in case of older kernels that do
        // not include KReclaimable meminfo field.
        if (kReclaimable == 0) {
            kReclaimable = mInfos[Debug.MEMINFO_SLAB_RECLAIMABLE];
        }
        return mInfos[Debug.MEMINFO_BUFFERS] + kReclaimable
                + mInfos[Debug.MEMINFO_CACHED] - mInfos[Debug.MEMINFO_MAPPED];
    }

+1 −0
Original line number Diff line number Diff line
@@ -233,6 +233,7 @@ cc_library_shared {

    static_libs: [
        "libasync_safe",
        "libdmabufinfo",
        "libgif",
        "libseccomp_policy",
        "libgrallocusage",
+60 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@
#include <nativehelper/JNIHelp.h>
#include <nativehelper/ScopedUtfChars.h>
#include "jni.h"
#include <dmabufinfo/dmabufinfo.h>
#include <meminfo/procmeminfo.h>
#include <meminfo/sysmeminfo.h>
#include <memtrack/memtrack.h>
@@ -779,6 +780,59 @@ static jlong android_os_Debug_getFreeZramKb(JNIEnv* env, jobject clazz) {
    return zramFreeKb;
}

static jlong android_os_Debug_getIonHeapsSizeKb(JNIEnv* env, jobject clazz) {
    jlong heapsSizeKb = 0;
    uint64_t size;

    if (meminfo::ReadIonHeapsSizeKb(&size)) {
        heapsSizeKb = size;
    }

    return heapsSizeKb;
}

static jlong android_os_Debug_getIonPoolsSizeKb(JNIEnv* env, jobject clazz) {
    jlong poolsSizeKb = 0;
    uint64_t size;

    if (meminfo::ReadIonPoolsSizeKb(&size)) {
        poolsSizeKb = size;
    }

    return poolsSizeKb;
}

static jlong android_os_Debug_getIonMappedSizeKb(JNIEnv* env, jobject clazz) {
    jlong ionPss = 0;
    std::vector<dmabufinfo::DmaBuffer> dmabufs;

    std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir("/proc"), closedir);
    if (!dir) {
        LOG(ERROR) << "Failed to open /proc directory";
        return false;
    }

    struct dirent* dent;
    while ((dent = readdir(dir.get()))) {
        if (dent->d_type != DT_DIR) continue;

        int pid = atoi(dent->d_name);
        if (pid == 0) {
            continue;
        }

        if (!AppendDmaBufInfo(pid, &dmabufs, false)) {
            LOG(ERROR) << "Failed to read maps for pid " << pid;
        }
    }

    for (dmabufinfo::DmaBuffer buf : dmabufs) {
        ionPss += buf.size() / 1024;
    }

    return ionPss;
}

/*
 * JNI registration.
 */
@@ -822,6 +876,12 @@ static const JNINativeMethod gMethods[] = {
            (void*)android_os_Debug_getUnreachableMemory },
    { "getZramFreeKb", "()J",
            (void*)android_os_Debug_getFreeZramKb },
    { "getIonHeapsSizeKb", "()J",
            (void*)android_os_Debug_getIonHeapsSizeKb },
    { "getIonPoolsSizeKb", "()J",
            (void*)android_os_Debug_getIonPoolsSizeKb },
    { "getIonMappedSizeKb", "()J",
            (void*)android_os_Debug_getIonMappedSizeKb },
};

int register_android_os_Debug(JNIEnv *env)
+34 −6
Original line number Diff line number Diff line
@@ -12799,14 +12799,31 @@ public class ActivityManagerService extends IActivityManager.Stub
                    pw.println(totalPss - cachedPss);
                }
            }
            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
            long kernelUsed = memInfo.getKernelUsedSizeKb();
            final long ionHeap = Debug.getIonHeapsSizeKb();
            if (ionHeap > 0) {
                final long ionMapped = Debug.getIonMappedSizeKb();
                final long ionUnmapped = ionHeap - ionMapped;
                final long ionPool = Debug.getIonPoolsSizeKb();
                pw.print("      ION: ");
                        pw.print(stringifyKBSize(ionHeap + ionPool));
                        pw.print(" (");
                        pw.print(stringifyKBSize(ionMapped));
                        pw.print(" mapped + ");
                        pw.print(stringifyKBSize(ionUnmapped));
                        pw.print(" unmapped + ");
                        pw.print(stringifyKBSize(ionPool));
                        pw.println(" pools)");
                kernelUsed += ionUnmapped;
            }
            final long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
                    - kernelUsed - memInfo.getZramTotalSizeKb();
            if (!opts.isCompact) {
                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
                        + kernelUsed)); pw.print(" (");
                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
                pw.print(stringifyKBSize(kernelUsed)); pw.print(" kernel)\n");
                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
            } else {
                pw.print("lostram,"); pw.println(lostRAM);
@@ -13525,14 +13542,25 @@ public class ActivityManagerService extends IActivityManager.Stub
        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
                + memInfo.getFreeSizeKb()));
        memInfoBuilder.append("\n");
        long kernelUsed = memInfo.getKernelUsedSizeKb();
        final long ionHeap = Debug.getIonHeapsSizeKb();
        if (ionHeap > 0) {
            final long ionMapped = Debug.getIonMappedSizeKb();
            final long ionUnmapped = ionHeap - ionMapped;
            final long ionPool = Debug.getIonPoolsSizeKb();
            memInfoBuilder.append("       ION: ");
            memInfoBuilder.append(stringifyKBSize(ionHeap + ionPool));
            memInfoBuilder.append("\n");
            kernelUsed += ionUnmapped;
        }
        memInfoBuilder.append("  Used RAM: ");
        memInfoBuilder.append(stringifyKBSize(
                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
                                  totalPss - cachedPss + kernelUsed));
        memInfoBuilder.append("\n");
        memInfoBuilder.append("  Lost RAM: ");
        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
                - (totalPss - totalSwapPss) - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
                - kernelUsed - memInfo.getZramTotalSizeKb()));
        memInfoBuilder.append("\n");
        Slog.i(TAG, "Low on memory:");
        Slog.i(TAG, shortNativeBuilder.toString());