Loading core/java/com/android/internal/os/DmabufInfoReader.java 0 → 100644 +51 −0 Original line number Diff line number Diff line /* * 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. */ package com.android.internal.os; import android.annotation.Nullable; /** Wrapper around libdmabufinfo. */ public final class DmabufInfoReader { private DmabufInfoReader() {} /** Process dma-buf stats. */ public static final class ProcessDmabuf { /** Size of buffers retained by the process. */ public final int retainedSizeKb; /** Number of buffers retained by the process. */ public final int retainedBuffersCount; /** Size of buffers mapped to the address space. */ public final int mappedSizeKb; /** Count of buffers mapped to the address space. */ public final int mappedBuffersCount; ProcessDmabuf(int retainedSizeKb, int retainedBuffersCount, int mappedSizeKb, int mappedBuffersCount) { this.retainedSizeKb = retainedSizeKb; this.retainedBuffersCount = retainedBuffersCount; this.mappedSizeKb = mappedSizeKb; this.mappedBuffersCount = mappedBuffersCount; } } /** * Return stats for DMA-BUFs retained by process pid or null if the DMA-BUF * stats could not be read. */ @Nullable public static native ProcessDmabuf getProcessStats(int pid); } core/jni/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -202,6 +202,7 @@ 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_KernelCpuBpfTracking.cpp", "com_android_internal_os_KernelCpuTotalBpfMapReader.cpp", Loading core/jni/AndroidRuntime.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -191,6 +191,7 @@ 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_KernelCpuBpfTracking(JNIEnv* env); extern int register_com_android_internal_os_KernelCpuTotalBpfMapReader(JNIEnv* env); Loading Loading @@ -1616,6 +1617,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_animation_PropertyValuesHolder), REG_JNI(register_android_security_Scrypt), 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_KernelCpuBpfTracking), REG_JNI(register_com_android_internal_os_KernelCpuTotalBpfMapReader), Loading core/jni/com_android_internal_os_DmabufInfoReader.cpp 0 → 100644 +60 −0 Original line number Diff line number Diff line /* * 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 services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +43 −0 Original line number Diff line number Diff line Loading @@ -111,6 +111,7 @@ import android.os.IThermalService; import android.os.OutcomeReceiver; import android.os.ParcelFileDescriptor; import android.os.Parcelable; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.StatFs; Loading Loading @@ -148,6 +149,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.KernelCpuBpfTracking; import com.android.internal.os.KernelCpuThreadReader; import com.android.internal.os.KernelCpuThreadReaderDiff; Loading Loading @@ -198,6 +200,7 @@ import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Map; Loading Loading @@ -528,6 +531,8 @@ public class StatsPullAtomService extends SystemService { synchronized (mProcessSystemIonHeapSizeLock) { return pullProcessSystemIonHeapSizeLocked(atomTag, data); } case FrameworkStatsLog.PROCESS_DMABUF_MEMORY: return pullProcessDmabufMemory(atomTag, data); case FrameworkStatsLog.SYSTEM_MEMORY: return pullSystemMemory(atomTag, data); case FrameworkStatsLog.TEMPERATURE: Loading Loading @@ -818,6 +823,7 @@ public class StatsPullAtomService extends SystemService { registerIonHeapSize(); registerProcessSystemIonHeapSize(); registerSystemMemory(); registerProcessDmabufMemory(); registerTemperature(); registerCoolingDevice(); registerBinderCallsStats(); Loading Loading @@ -2183,6 +2189,43 @@ public class StatsPullAtomService extends SystemService { return StatsManager.PULL_SUCCESS; } private void registerProcessDmabufMemory() { int tagId = FrameworkStatsLog.PROCESS_DMABUF_MEMORY; mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values DIRECT_EXECUTOR, mStatsCallbackImpl ); } int pullProcessDmabufMemory(int atomTag, List<StatsEvent> pulledData) { List<ProcessMemoryState> managedProcessList = LocalServices.getService(ActivityManagerInternal.class) .getMemoryStateForProcesses(); managedProcessList.sort(Comparator.comparingInt(x -> x.oomScore)); for (ProcessMemoryState process : managedProcessList) { if (process.uid == Process.SYSTEM_UID) { continue; } DmabufInfoReader.ProcessDmabuf proc = DmabufInfoReader.getProcessStats(process.pid); if (proc == null || (proc.retainedBuffersCount <= 0 && proc.mappedBuffersCount <= 0)) { continue; } pulledData.add( FrameworkStatsLog.buildStatsEvent( atomTag, process.uid, process.processName, process.oomScore, proc.retainedSizeKb, proc.retainedBuffersCount, proc.mappedSizeKb, proc.mappedBuffersCount)); } return StatsManager.PULL_SUCCESS; } private void registerSystemMemory() { int tagId = FrameworkStatsLog.SYSTEM_MEMORY; mStatsManager.setPullAtomCallback( Loading Loading
core/java/com/android/internal/os/DmabufInfoReader.java 0 → 100644 +51 −0 Original line number Diff line number Diff line /* * 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. */ package com.android.internal.os; import android.annotation.Nullable; /** Wrapper around libdmabufinfo. */ public final class DmabufInfoReader { private DmabufInfoReader() {} /** Process dma-buf stats. */ public static final class ProcessDmabuf { /** Size of buffers retained by the process. */ public final int retainedSizeKb; /** Number of buffers retained by the process. */ public final int retainedBuffersCount; /** Size of buffers mapped to the address space. */ public final int mappedSizeKb; /** Count of buffers mapped to the address space. */ public final int mappedBuffersCount; ProcessDmabuf(int retainedSizeKb, int retainedBuffersCount, int mappedSizeKb, int mappedBuffersCount) { this.retainedSizeKb = retainedSizeKb; this.retainedBuffersCount = retainedBuffersCount; this.mappedSizeKb = mappedSizeKb; this.mappedBuffersCount = mappedBuffersCount; } } /** * Return stats for DMA-BUFs retained by process pid or null if the DMA-BUF * stats could not be read. */ @Nullable public static native ProcessDmabuf getProcessStats(int pid); }
core/jni/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -202,6 +202,7 @@ 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_KernelCpuBpfTracking.cpp", "com_android_internal_os_KernelCpuTotalBpfMapReader.cpp", Loading
core/jni/AndroidRuntime.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -191,6 +191,7 @@ 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_KernelCpuBpfTracking(JNIEnv* env); extern int register_com_android_internal_os_KernelCpuTotalBpfMapReader(JNIEnv* env); Loading Loading @@ -1616,6 +1617,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_animation_PropertyValuesHolder), REG_JNI(register_android_security_Scrypt), 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_KernelCpuBpfTracking), REG_JNI(register_com_android_internal_os_KernelCpuTotalBpfMapReader), Loading
core/jni/com_android_internal_os_DmabufInfoReader.cpp 0 → 100644 +60 −0 Original line number Diff line number Diff line /* * 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
services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +43 −0 Original line number Diff line number Diff line Loading @@ -111,6 +111,7 @@ import android.os.IThermalService; import android.os.OutcomeReceiver; import android.os.ParcelFileDescriptor; import android.os.Parcelable; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.StatFs; Loading Loading @@ -148,6 +149,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.KernelCpuBpfTracking; import com.android.internal.os.KernelCpuThreadReader; import com.android.internal.os.KernelCpuThreadReaderDiff; Loading Loading @@ -198,6 +200,7 @@ import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Map; Loading Loading @@ -528,6 +531,8 @@ public class StatsPullAtomService extends SystemService { synchronized (mProcessSystemIonHeapSizeLock) { return pullProcessSystemIonHeapSizeLocked(atomTag, data); } case FrameworkStatsLog.PROCESS_DMABUF_MEMORY: return pullProcessDmabufMemory(atomTag, data); case FrameworkStatsLog.SYSTEM_MEMORY: return pullSystemMemory(atomTag, data); case FrameworkStatsLog.TEMPERATURE: Loading Loading @@ -818,6 +823,7 @@ public class StatsPullAtomService extends SystemService { registerIonHeapSize(); registerProcessSystemIonHeapSize(); registerSystemMemory(); registerProcessDmabufMemory(); registerTemperature(); registerCoolingDevice(); registerBinderCallsStats(); Loading Loading @@ -2183,6 +2189,43 @@ public class StatsPullAtomService extends SystemService { return StatsManager.PULL_SUCCESS; } private void registerProcessDmabufMemory() { int tagId = FrameworkStatsLog.PROCESS_DMABUF_MEMORY; mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values DIRECT_EXECUTOR, mStatsCallbackImpl ); } int pullProcessDmabufMemory(int atomTag, List<StatsEvent> pulledData) { List<ProcessMemoryState> managedProcessList = LocalServices.getService(ActivityManagerInternal.class) .getMemoryStateForProcesses(); managedProcessList.sort(Comparator.comparingInt(x -> x.oomScore)); for (ProcessMemoryState process : managedProcessList) { if (process.uid == Process.SYSTEM_UID) { continue; } DmabufInfoReader.ProcessDmabuf proc = DmabufInfoReader.getProcessStats(process.pid); if (proc == null || (proc.retainedBuffersCount <= 0 && proc.mappedBuffersCount <= 0)) { continue; } pulledData.add( FrameworkStatsLog.buildStatsEvent( atomTag, process.uid, process.processName, process.oomScore, proc.retainedSizeKb, proc.retainedBuffersCount, proc.mappedSizeKb, proc.mappedBuffersCount)); } return StatsManager.PULL_SUCCESS; } private void registerSystemMemory() { int tagId = FrameworkStatsLog.SYSTEM_MEMORY; mStatsManager.setPullAtomCallback( Loading