diff options
| author | 2021-12-06 21:13:03 +0000 | |
|---|---|---|
| committer | 2021-12-06 21:13:03 +0000 | |
| commit | fce46978ff9ac97c05caed4437b5ea489f401b18 (patch) | |
| tree | 027091d3f6bc3c2a4dade062994a80ee0b1e1151 | |
| parent | 12667f03f1d9ae7ed201f408954029a00cdf68ed (diff) | |
| parent | cc793ab6084411404dc290e2a897f0fed2d429bd (diff) | |
Merge "Read per-process GPU memory when pulling ProcessMemorySnapshot"
| -rw-r--r-- | core/java/com/android/internal/os/KernelAllocationStats.java (renamed from core/java/com/android/internal/os/DmabufInfoReader.java) | 22 | ||||
| -rw-r--r-- | core/jni/Android.bp | 2 | ||||
| -rw-r--r-- | core/jni/AndroidRuntime.cpp | 4 | ||||
| -rw-r--r-- | core/jni/com_android_internal_os_DmabufInfoReader.cpp | 60 | ||||
| -rw-r--r-- | core/jni/com_android_internal_os_KernelAllocationStats.cpp | 97 | ||||
| -rw-r--r-- | services/core/java/com/android/server/stats/pull/StatsPullAtomService.java | 25 |
6 files changed, 134 insertions, 76 deletions
diff --git a/core/java/com/android/internal/os/DmabufInfoReader.java b/core/java/com/android/internal/os/KernelAllocationStats.java index 786a6eedf343..1c3f8b0bf095 100644 --- a/core/java/com/android/internal/os/DmabufInfoReader.java +++ b/core/java/com/android/internal/os/KernelAllocationStats.java @@ -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(); } diff --git a/core/jni/Android.bp b/core/jni/Android.bp index 1a1a8badf82b..da628635af36 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -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", diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 18e85b6eb0be..04fafb441a28 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -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), diff --git a/core/jni/com_android_internal_os_DmabufInfoReader.cpp b/core/jni/com_android_internal_os_DmabufInfoReader.cpp deleted file mode 100644 index 4b0a6ac5b6c4..000000000000 --- a/core/jni/com_android_internal_os_DmabufInfoReader.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <dmabufinfo/dmabufinfo.h> -#include "core_jni_helpers.h" - -namespace android { - -static jobject DmabufInfoReader_getProcessStats(JNIEnv *env, jobject, jint pid) { - std::vector<dmabufinfo::DmaBuffer> buffers; - if (!dmabufinfo::ReadDmaBufMapRefs(pid, &buffers)) { - return nullptr; - } - jint mappedSize = 0; - jint mappedCount = buffers.size(); - for (const auto &buffer : buffers) { - mappedSize += buffer.size(); - } - mappedSize /= 1024; - - jint retainedSize = -1; - jint retainedCount = -1; - if (dmabufinfo::ReadDmaBufFdRefs(pid, &buffers)) { - retainedCount = buffers.size(); - retainedSize = 0; - for (const auto &buffer : buffers) { - retainedSize += buffer.size(); - } - retainedSize /= 1024; - } - - 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 const JNINativeMethod methods[] = { - {"getProcessStats", "(I)Lcom/android/internal/os/DmabufInfoReader$ProcessDmabuf;", - (void *)DmabufInfoReader_getProcessStats}, -}; - -int register_com_android_internal_os_DmabufInfoReader(JNIEnv *env) { - return RegisterMethodsOrDie(env, "com/android/internal/os/DmabufInfoReader", methods, - NELEM(methods)); -} - -} // namespace android diff --git a/core/jni/com_android_internal_os_KernelAllocationStats.cpp b/core/jni/com_android_internal_os_KernelAllocationStats.cpp new file mode 100644 index 000000000000..e0a24430e739 --- /dev/null +++ b/core/jni/com_android_internal_os_KernelAllocationStats.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * 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 KernelAllocationStats_getDmabufAllocations(JNIEnv *env, jobject, jint pid) { + std::vector<dmabufinfo::DmaBuffer> buffers; + if (!dmabufinfo::ReadDmaBufMapRefs(pid, &buffers)) { + return nullptr; + } + jint mappedSize = 0; + jint mappedCount = buffers.size(); + for (const auto &buffer : buffers) { + mappedSize += buffer.size(); + } + mappedSize /= 1024; + + jint retainedSize = -1; + jint retainedCount = -1; + if (dmabufinfo::ReadDmaBufFdRefs(pid, &buffers)) { + retainedCount = buffers.size(); + retainedSize = 0; + for (const auto &buffer : buffers) { + retainedSize += buffer.size(); + } + retainedSize /= 1024; + } + return env->NewObject(gProcessDmabufClazz, gProcessDmabufCtor, 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[] = { + {"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_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 diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java index 45f1b163506b..b1cc51768754 100644 --- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java @@ -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; } |