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

Commit fce46978 authored by Ioannis Ilkos's avatar Ioannis Ilkos Committed by Android (Google) Code Review
Browse files

Merge "Read per-process GPU memory when pulling ProcessMemorySnapshot"

parents 12667f03 cc793ab6
Loading
Loading
Loading
Loading
+18 −4
Original line number Diff line number Diff line
@@ -18,9 +18,9 @@ package com.android.internal.os;

import android.annotation.Nullable;

/** Wrapper around libdmabufinfo. */
public final class DmabufInfoReader {
    private DmabufInfoReader() {}
/** JNI wrapper around libmeminfo for kernel memory allocation stats (dmabufs, gpu driver). */
public final class KernelAllocationStats {
    private KernelAllocationStats() {}

    /** Process dma-buf stats. */
    public static final class ProcessDmabuf {
@@ -47,5 +47,19 @@ public final class DmabufInfoReader {
     * stats could not be read.
     */
    @Nullable
    public static native ProcessDmabuf getProcessStats(int pid);
    public static native ProcessDmabuf getDmabufAllocations(int pid);

    /** Pid to gpu memory size. */
    public static final class ProcessGpuMem {
        public final int pid;
        public final int gpuMemoryKb;

        ProcessGpuMem(int pid, int gpuMemoryKb) {
            this.pid = pid;
            this.gpuMemoryKb = gpuMemoryKb;
        }
    }

    /** Return list of pid to gpu memory size. */
    public static native ProcessGpuMem[] getGpuAllocations();
}
+1 −1
Original line number Diff line number Diff line
@@ -210,8 +210,8 @@ cc_library_shared {
                "com_android_internal_content_om_OverlayConfig.cpp",
                "com_android_internal_net_NetworkUtilsInternal.cpp",
                "com_android_internal_os_ClassLoaderFactory.cpp",
                "com_android_internal_os_DmabufInfoReader.cpp",
                "com_android_internal_os_FuseAppLoop.cpp",
                "com_android_internal_os_KernelAllocationStats.cpp",
                "com_android_internal_os_KernelCpuBpfTracking.cpp",
                "com_android_internal_os_KernelCpuTotalBpfMapReader.cpp",
                "com_android_internal_os_KernelCpuUidBpfMapReader.cpp",
+2 −2
Original line number Diff line number Diff line
@@ -197,8 +197,8 @@ extern int register_com_android_internal_content_NativeLibraryHelper(JNIEnv *env
extern int register_com_android_internal_content_om_OverlayConfig(JNIEnv *env);
extern int register_com_android_internal_net_NetworkUtilsInternal(JNIEnv* env);
extern int register_com_android_internal_os_ClassLoaderFactory(JNIEnv* env);
extern int register_com_android_internal_os_DmabufInfoReader(JNIEnv* env);
extern int register_com_android_internal_os_FuseAppLoop(JNIEnv* env);
extern int register_com_android_internal_os_KernelAllocationStats(JNIEnv* env);
extern int register_com_android_internal_os_KernelCpuBpfTracking(JNIEnv* env);
extern int register_com_android_internal_os_KernelCpuTotalBpfMapReader(JNIEnv* env);
extern int register_com_android_internal_os_KernelCpuUidBpfMapReader(JNIEnv *env);
@@ -1655,8 +1655,8 @@ static const RegJNIRec gRegJNI[] = {
        REG_JNI(register_android_security_Scrypt),
        REG_JNI(register_com_android_internal_content_F2fsUtils),
        REG_JNI(register_com_android_internal_content_NativeLibraryHelper),
        REG_JNI(register_com_android_internal_os_DmabufInfoReader),
        REG_JNI(register_com_android_internal_os_FuseAppLoop),
        REG_JNI(register_com_android_internal_os_KernelAllocationStats),
        REG_JNI(register_com_android_internal_os_KernelCpuBpfTracking),
        REG_JNI(register_com_android_internal_os_KernelCpuTotalBpfMapReader),
        REG_JNI(register_com_android_internal_os_KernelCpuUidBpfMapReader),
+97 −0
Original line number Diff line number Diff line
@@ -13,13 +13,22 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <dmabufinfo/dmabufinfo.h>
#include <jni.h>
#include <meminfo/sysmeminfo.h>

#include "core_jni_helpers.h"

namespace {
static jclass gProcessDmabufClazz;
static jmethodID gProcessDmabufCtor;
static jclass gProcessGpuMemClazz;
static jmethodID gProcessGpuMemCtor;
} // namespace

namespace android {

static jobject DmabufInfoReader_getProcessStats(JNIEnv *env, jobject, jint pid) {
static jobject KernelAllocationStats_getDmabufAllocations(JNIEnv *env, jobject, jint pid) {
    std::vector<dmabufinfo::DmaBuffer> buffers;
    if (!dmabufinfo::ReadDmaBufMapRefs(pid, &buffers)) {
        return nullptr;
@@ -41,20 +50,48 @@ static jobject DmabufInfoReader_getProcessStats(JNIEnv *env, jobject, jint pid)
        }
        retainedSize /= 1024;
    }
    return env->NewObject(gProcessDmabufClazz, gProcessDmabufCtor, retainedSize, retainedCount,
                          mappedSize, mappedCount);
}

    jclass clazz = FindClassOrDie(env, "com/android/internal/os/DmabufInfoReader$ProcessDmabuf");
    jmethodID constructID = GetMethodIDOrDie(env, clazz, "<init>", "(IIII)V");
    return env->NewObject(clazz, constructID, retainedSize, retainedCount, mappedSize, mappedCount);
static jobject KernelAllocationStats_getGpuAllocations(JNIEnv *env) {
    std::unordered_map<uint32_t, uint64_t> out;
    meminfo::ReadPerProcessGpuMem(&out);
    jobjectArray result = env->NewObjectArray(out.size(), gProcessGpuMemClazz, nullptr);
    if (result == NULL) {
        jniThrowRuntimeException(env, "Cannot create result array");
        return nullptr;
    }
    int idx = 0;
    for (const auto &entry : out) {
        jobject pidStats =
                env->NewObject(gProcessGpuMemClazz, gProcessGpuMemCtor, entry.first, entry.second);
        env->SetObjectArrayElement(result, idx, pidStats);
        env->DeleteLocalRef(pidStats);
        ++idx;
    }
    return result;
}

static const JNINativeMethod methods[] = {
        {"getProcessStats", "(I)Lcom/android/internal/os/DmabufInfoReader$ProcessDmabuf;",
         (void *)DmabufInfoReader_getProcessStats},
        {"getDmabufAllocations", "(I)Lcom/android/internal/os/KernelAllocationStats$ProcessDmabuf;",
         (void *)KernelAllocationStats_getDmabufAllocations},
        {"getGpuAllocations", "()[Lcom/android/internal/os/KernelAllocationStats$ProcessGpuMem;",
         (void *)KernelAllocationStats_getGpuAllocations},
};

int register_com_android_internal_os_DmabufInfoReader(JNIEnv *env) {
    return RegisterMethodsOrDie(env, "com/android/internal/os/DmabufInfoReader", methods,
int register_com_android_internal_os_KernelAllocationStats(JNIEnv *env) {
    int res = RegisterMethodsOrDie(env, "com/android/internal/os/KernelAllocationStats", methods,
                                   NELEM(methods));
    jclass clazz =
            FindClassOrDie(env, "com/android/internal/os/KernelAllocationStats$ProcessDmabuf");
    gProcessDmabufClazz = MakeGlobalRefOrDie(env, clazz);
    gProcessDmabufCtor = GetMethodIDOrDie(env, gProcessDmabufClazz, "<init>", "(IIII)V");

    clazz = FindClassOrDie(env, "com/android/internal/os/KernelAllocationStats$ProcessGpuMem");
    gProcessGpuMemClazz = MakeGlobalRefOrDie(env, clazz);
    gProcessGpuMemCtor = GetMethodIDOrDie(env, gProcessGpuMemClazz, "<init>", "(II)V");
    return res;
}

} // namespace android
+16 −9
Original line number Diff line number Diff line
@@ -172,6 +172,7 @@ import android.util.Log;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.util.StatsEvent;
import android.util.proto.ProtoOutputStream;
import android.view.Display;
@@ -183,7 +184,7 @@ import com.android.internal.os.BackgroundThread;
import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatteryStatsHelper;
import com.android.internal.os.BinderCallsStats.ExportedCallStat;
import com.android.internal.os.DmabufInfoReader;
import com.android.internal.os.KernelAllocationStats;
import com.android.internal.os.KernelCpuBpfTracking;
import com.android.internal.os.KernelCpuThreadReader;
import com.android.internal.os.KernelCpuThreadReaderDiff;
@@ -425,7 +426,6 @@ public class StatsPullAtomService extends SystemService {
    private final Object mSystemUptimeLock = new Object();
    private final Object mProcessMemoryStateLock = new Object();
    private final Object mProcessMemoryHighWaterMarkLock = new Object();
    private final Object mProcessMemorySnapshotLock = new Object();
    private final Object mSystemIonHeapSizeLock = new Object();
    private final Object mIonHeapSizeLock = new Object();
    private final Object mProcessSystemIonHeapSizeLock = new Object();
@@ -563,9 +563,7 @@ public class StatsPullAtomService extends SystemService {
                            return pullProcessMemoryHighWaterMarkLocked(atomTag, data);
                        }
                    case FrameworkStatsLog.PROCESS_MEMORY_SNAPSHOT:
                        synchronized (mProcessMemorySnapshotLock) {
                            return pullProcessMemorySnapshotLocked(atomTag, data);
                        }
                        return pullProcessMemorySnapshot(atomTag, data);
                    case FrameworkStatsLog.SYSTEM_ION_HEAP_SIZE:
                        synchronized (mSystemIonHeapSizeLock) {
                            return pullSystemIonHeapSizeLocked(atomTag, data);
@@ -2218,10 +2216,16 @@ public class StatsPullAtomService extends SystemService {
        );
    }

    int pullProcessMemorySnapshotLocked(int atomTag, List<StatsEvent> pulledData) {
    int pullProcessMemorySnapshot(int atomTag, List<StatsEvent> pulledData) {
        List<ProcessMemoryState> managedProcessList =
                LocalServices.getService(ActivityManagerInternal.class)
                        .getMemoryStateForProcesses();
        KernelAllocationStats.ProcessGpuMem[] gpuAllocations =
                KernelAllocationStats.getGpuAllocations();
        SparseIntArray gpuMemPerPid = new SparseIntArray(gpuAllocations.length);
        for (KernelAllocationStats.ProcessGpuMem processGpuMem : gpuAllocations) {
            gpuMemPerPid.put(processGpuMem.pid, processGpuMem.gpuMemoryKb);
        }
        for (ProcessMemoryState managedProcess : managedProcessList) {
            final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(managedProcess.pid);
            if (snapshot == null) {
@@ -2230,7 +2234,8 @@ public class StatsPullAtomService extends SystemService {
            pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, managedProcess.uid,
                    managedProcess.processName, managedProcess.pid, managedProcess.oomScore,
                    snapshot.rssInKilobytes, snapshot.anonRssInKilobytes, snapshot.swapInKilobytes,
                    snapshot.anonRssInKilobytes + snapshot.swapInKilobytes));
                    snapshot.anonRssInKilobytes + snapshot.swapInKilobytes,
                    gpuMemPerPid.get(managedProcess.pid)));
        }
        // Complement the data with native system processes. Given these measurements can be taken
        // in response to LMKs happening, we want to first collect the managed app stats (to
@@ -2248,7 +2253,8 @@ public class StatsPullAtomService extends SystemService {
                    processCmdlines.valueAt(i), pid,
                    -1001 /*Placeholder for native processes, OOM_SCORE_ADJ_MIN - 1.*/,
                    snapshot.rssInKilobytes, snapshot.anonRssInKilobytes, snapshot.swapInKilobytes,
                    snapshot.anonRssInKilobytes + snapshot.swapInKilobytes));
                    snapshot.anonRssInKilobytes + snapshot.swapInKilobytes,
                    gpuMemPerPid.get(pid)));
        }
        return StatsManager.PULL_SUCCESS;
    }
@@ -2328,7 +2334,8 @@ public class StatsPullAtomService extends SystemService {
            if (process.uid == Process.SYSTEM_UID) {
                continue;
            }
            DmabufInfoReader.ProcessDmabuf proc = DmabufInfoReader.getProcessStats(process.pid);
            KernelAllocationStats.ProcessDmabuf proc =
                    KernelAllocationStats.getDmabufAllocations(process.pid);
            if (proc == null || (proc.retainedBuffersCount <= 0 && proc.mappedBuffersCount <= 0)) {
                continue;
            }
Loading