Loading core/java/com/android/internal/os/ProcfsMemoryUtil.java +51 −1 Original line number Diff line number Diff line Loading @@ -15,7 +15,9 @@ */ package com.android.internal.os; import static android.os.Process.*; import static android.os.Process.PROC_NEWLINE_TERM; import static android.os.Process.PROC_OUT_LONG; import static android.os.Process.PROC_OUT_STRING; import android.annotation.Nullable; import android.os.Process; Loading @@ -35,6 +37,13 @@ public final class ProcfsMemoryUtil { private static final String[] VMSTAT_KEYS = new String[] { "oom_kill" }; private static final int[] DMABUF_FILE_FORMAT = new int[] {PROC_OUT_LONG}; public enum DmaBufType { RSS, RSS_HWM, PSS }; private ProcfsMemoryUtil() {} Loading Loading @@ -81,6 +90,47 @@ public final class ProcfsMemoryUtil { return snapshot; } /** * Reads dmabuf stats of the current process from procfs. * * <p>Returns values related to RSS, RSS_HWM and PSS from, respectively, /proc/pid/{dmabuf_rss, * dmabuf_rss_hwm, dmabuf_pss}, in kilobytes or -1 if not available. */ public static int readDmabufFromProcfs(DmaBufType type, int pid) { return readDmabufFromProcfs(type, String.valueOf(pid)); } /** * Reads dmabuf stats of the current process from procfs. * * <p>Returns values related to RSS, RSS_HWM and PSS from, respectively, /proc/self/{dmabuf_rss, * dmabuf_rss_hwm, dmabuf_pss}, in kilobytes or -1 if not available. */ public static int readDmabufFromProcfs(DmaBufType type) { return readDmabufFromProcfs(type, "self"); } private static int readDmabufFromProcfs(DmaBufType type, String path) { // These files have maximum 1 line. long[] output = new long[1]; String dmabuf_file = switch (type) { case RSS -> "dmabuf_rss"; case RSS_HWM -> "dmabuf_rss_hwm"; case PSS -> "dmabuf_pss"; }; if (!Process.readProcFile( "/proc/" + path + "/" + dmabuf_file, DMABUF_FILE_FORMAT, null, output, null)) { /* Catches the case when the file is empty, doesn't exist, or the * kernel does not support reporting these values. We should not * report the value 0, as it would correspond to no dmabuf memory * allocations, so we report an error value of -1. */ return -1; } return (int) (output[0] / 1024); } /** * Reads cmdline of a process from procfs. * Loading services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +62 −27 Original line number Diff line number Diff line Loading @@ -50,8 +50,10 @@ import static android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID; import static android.util.MathUtils.constrain; import static android.view.Display.HdrCapabilities.HDR_TYPE_INVALID; import static com.android.internal.os.ProcfsMemoryUtil.DmaBufType; import static com.android.internal.os.ProcfsMemoryUtil.getProcessCmdlines; import static com.android.internal.os.ProcfsMemoryUtil.readCmdlineFromProcfs; import static com.android.internal.os.ProcfsMemoryUtil.readDmabufFromProcfs; import static com.android.internal.os.ProcfsMemoryUtil.readMemorySnapshotFromProcfs; import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_STATS__GESTURE_SHORTCUT_TYPE__TRIPLE_TAP; Loading Loading @@ -2549,11 +2551,17 @@ public class StatsPullAtomService extends SystemService { if (snapshot == null) { continue; } pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, managedProcess.uid, final int dmaBufRssHighWaterMarkInKilobytes = readDmabufFromProcfs(DmaBufType.RSS_HWM, managedProcess.pid); pulledData.add( FrameworkStatsLog.buildStatsEvent( atomTag, managedProcess.uid, managedProcess.processName, // RSS high-water mark in bytes. snapshot.rssHighWaterMarkInKilobytes * 1024L, snapshot.rssHighWaterMarkInKilobytes)); snapshot.rssHighWaterMarkInKilobytes, dmaBufRssHighWaterMarkInKilobytes)); } // Complement the data with native system processes SparseArray<String> processCmdlines = getProcessCmdlines(); Loading @@ -2564,11 +2572,17 @@ public class StatsPullAtomService extends SystemService { if (snapshot == null) { continue; } pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, snapshot.uid, final int dmaBufRssHighWaterMarkInKilobytes = readDmabufFromProcfs(DmaBufType.RSS_HWM, processCmdlines.keyAt(i)); pulledData.add( FrameworkStatsLog.buildStatsEvent( atomTag, snapshot.uid, processCmdlines.valueAt(i), // RSS high-water mark in bytes. snapshot.rssHighWaterMarkInKilobytes * 1024L, snapshot.rssHighWaterMarkInKilobytes)); snapshot.rssHighWaterMarkInKilobytes, dmaBufRssHighWaterMarkInKilobytes)); } // Invoke rss_hwm_reset binary to reset RSS HWM counters for all processes. SystemProperties.set("sys.rss_hwm_reset.on", "1"); Loading Loading @@ -2600,13 +2614,25 @@ public class StatsPullAtomService extends SystemService { if (snapshot == null) { continue; } pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, managedProcess.uid, managedProcess.processName, managedProcess.pid, managedProcess.oomScore, snapshot.rssInKilobytes, snapshot.anonRssInKilobytes, snapshot.swapInKilobytes, final int dmaBufRssInKilobytes = readDmabufFromProcfs(DmaBufType.RSS, managedProcess.pid); pulledData.add( FrameworkStatsLog.buildStatsEvent( atomTag, managedProcess.uid, managedProcess.processName, managedProcess.pid, managedProcess.oomScore, snapshot.rssInKilobytes, snapshot.anonRssInKilobytes, snapshot.swapInKilobytes, snapshot.anonRssInKilobytes + snapshot.swapInKilobytes, gpuMemPerPid.get(managedProcess.pid), managedProcess.hasForegroundServices, snapshot.rssShmemKilobytes, managedProcess.mHostingComponentTypes, managedProcess.mHistoricalHostingComponentTypes)); gpuMemPerPid.get(managedProcess.pid), managedProcess.hasForegroundServices, snapshot.rssShmemKilobytes, managedProcess.mHostingComponentTypes, managedProcess.mHistoricalHostingComponentTypes, dmaBufRssInKilobytes)); } // 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 Loading @@ -2620,16 +2646,25 @@ public class StatsPullAtomService extends SystemService { if (snapshot == null) { continue; } pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, snapshot.uid, processCmdlines.valueAt(i), pid, final int dmaBufRssInKilobytes = readDmabufFromProcfs(DmaBufType.RSS, pid); pulledData.add( FrameworkStatsLog.buildStatsEvent( atomTag, snapshot.uid, processCmdlines.valueAt(i), pid, -1001 /*Placeholder for native processes, OOM_SCORE_ADJ_MIN - 1.*/, snapshot.rssInKilobytes, snapshot.anonRssInKilobytes, snapshot.swapInKilobytes, snapshot.rssInKilobytes, snapshot.anonRssInKilobytes, snapshot.swapInKilobytes, snapshot.anonRssInKilobytes + snapshot.swapInKilobytes, gpuMemPerPid.get(pid), false /* has_foreground_services */, gpuMemPerPid.get(pid), false /* has_foreground_services */, snapshot.rssShmemKilobytes, // Native processes don't really have a hosting component type. HOSTING_COMPONENT_TYPE_EMPTY, HOSTING_COMPONENT_TYPE_EMPTY)); HOSTING_COMPONENT_TYPE_EMPTY, dmaBufRssInKilobytes)); } return StatsManager.PULL_SUCCESS; } Loading Loading
core/java/com/android/internal/os/ProcfsMemoryUtil.java +51 −1 Original line number Diff line number Diff line Loading @@ -15,7 +15,9 @@ */ package com.android.internal.os; import static android.os.Process.*; import static android.os.Process.PROC_NEWLINE_TERM; import static android.os.Process.PROC_OUT_LONG; import static android.os.Process.PROC_OUT_STRING; import android.annotation.Nullable; import android.os.Process; Loading @@ -35,6 +37,13 @@ public final class ProcfsMemoryUtil { private static final String[] VMSTAT_KEYS = new String[] { "oom_kill" }; private static final int[] DMABUF_FILE_FORMAT = new int[] {PROC_OUT_LONG}; public enum DmaBufType { RSS, RSS_HWM, PSS }; private ProcfsMemoryUtil() {} Loading Loading @@ -81,6 +90,47 @@ public final class ProcfsMemoryUtil { return snapshot; } /** * Reads dmabuf stats of the current process from procfs. * * <p>Returns values related to RSS, RSS_HWM and PSS from, respectively, /proc/pid/{dmabuf_rss, * dmabuf_rss_hwm, dmabuf_pss}, in kilobytes or -1 if not available. */ public static int readDmabufFromProcfs(DmaBufType type, int pid) { return readDmabufFromProcfs(type, String.valueOf(pid)); } /** * Reads dmabuf stats of the current process from procfs. * * <p>Returns values related to RSS, RSS_HWM and PSS from, respectively, /proc/self/{dmabuf_rss, * dmabuf_rss_hwm, dmabuf_pss}, in kilobytes or -1 if not available. */ public static int readDmabufFromProcfs(DmaBufType type) { return readDmabufFromProcfs(type, "self"); } private static int readDmabufFromProcfs(DmaBufType type, String path) { // These files have maximum 1 line. long[] output = new long[1]; String dmabuf_file = switch (type) { case RSS -> "dmabuf_rss"; case RSS_HWM -> "dmabuf_rss_hwm"; case PSS -> "dmabuf_pss"; }; if (!Process.readProcFile( "/proc/" + path + "/" + dmabuf_file, DMABUF_FILE_FORMAT, null, output, null)) { /* Catches the case when the file is empty, doesn't exist, or the * kernel does not support reporting these values. We should not * report the value 0, as it would correspond to no dmabuf memory * allocations, so we report an error value of -1. */ return -1; } return (int) (output[0] / 1024); } /** * Reads cmdline of a process from procfs. * Loading
services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +62 −27 Original line number Diff line number Diff line Loading @@ -50,8 +50,10 @@ import static android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID; import static android.util.MathUtils.constrain; import static android.view.Display.HdrCapabilities.HDR_TYPE_INVALID; import static com.android.internal.os.ProcfsMemoryUtil.DmaBufType; import static com.android.internal.os.ProcfsMemoryUtil.getProcessCmdlines; import static com.android.internal.os.ProcfsMemoryUtil.readCmdlineFromProcfs; import static com.android.internal.os.ProcfsMemoryUtil.readDmabufFromProcfs; import static com.android.internal.os.ProcfsMemoryUtil.readMemorySnapshotFromProcfs; import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_STATS__GESTURE_SHORTCUT_TYPE__TRIPLE_TAP; Loading Loading @@ -2549,11 +2551,17 @@ public class StatsPullAtomService extends SystemService { if (snapshot == null) { continue; } pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, managedProcess.uid, final int dmaBufRssHighWaterMarkInKilobytes = readDmabufFromProcfs(DmaBufType.RSS_HWM, managedProcess.pid); pulledData.add( FrameworkStatsLog.buildStatsEvent( atomTag, managedProcess.uid, managedProcess.processName, // RSS high-water mark in bytes. snapshot.rssHighWaterMarkInKilobytes * 1024L, snapshot.rssHighWaterMarkInKilobytes)); snapshot.rssHighWaterMarkInKilobytes, dmaBufRssHighWaterMarkInKilobytes)); } // Complement the data with native system processes SparseArray<String> processCmdlines = getProcessCmdlines(); Loading @@ -2564,11 +2572,17 @@ public class StatsPullAtomService extends SystemService { if (snapshot == null) { continue; } pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, snapshot.uid, final int dmaBufRssHighWaterMarkInKilobytes = readDmabufFromProcfs(DmaBufType.RSS_HWM, processCmdlines.keyAt(i)); pulledData.add( FrameworkStatsLog.buildStatsEvent( atomTag, snapshot.uid, processCmdlines.valueAt(i), // RSS high-water mark in bytes. snapshot.rssHighWaterMarkInKilobytes * 1024L, snapshot.rssHighWaterMarkInKilobytes)); snapshot.rssHighWaterMarkInKilobytes, dmaBufRssHighWaterMarkInKilobytes)); } // Invoke rss_hwm_reset binary to reset RSS HWM counters for all processes. SystemProperties.set("sys.rss_hwm_reset.on", "1"); Loading Loading @@ -2600,13 +2614,25 @@ public class StatsPullAtomService extends SystemService { if (snapshot == null) { continue; } pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, managedProcess.uid, managedProcess.processName, managedProcess.pid, managedProcess.oomScore, snapshot.rssInKilobytes, snapshot.anonRssInKilobytes, snapshot.swapInKilobytes, final int dmaBufRssInKilobytes = readDmabufFromProcfs(DmaBufType.RSS, managedProcess.pid); pulledData.add( FrameworkStatsLog.buildStatsEvent( atomTag, managedProcess.uid, managedProcess.processName, managedProcess.pid, managedProcess.oomScore, snapshot.rssInKilobytes, snapshot.anonRssInKilobytes, snapshot.swapInKilobytes, snapshot.anonRssInKilobytes + snapshot.swapInKilobytes, gpuMemPerPid.get(managedProcess.pid), managedProcess.hasForegroundServices, snapshot.rssShmemKilobytes, managedProcess.mHostingComponentTypes, managedProcess.mHistoricalHostingComponentTypes)); gpuMemPerPid.get(managedProcess.pid), managedProcess.hasForegroundServices, snapshot.rssShmemKilobytes, managedProcess.mHostingComponentTypes, managedProcess.mHistoricalHostingComponentTypes, dmaBufRssInKilobytes)); } // 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 Loading @@ -2620,16 +2646,25 @@ public class StatsPullAtomService extends SystemService { if (snapshot == null) { continue; } pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, snapshot.uid, processCmdlines.valueAt(i), pid, final int dmaBufRssInKilobytes = readDmabufFromProcfs(DmaBufType.RSS, pid); pulledData.add( FrameworkStatsLog.buildStatsEvent( atomTag, snapshot.uid, processCmdlines.valueAt(i), pid, -1001 /*Placeholder for native processes, OOM_SCORE_ADJ_MIN - 1.*/, snapshot.rssInKilobytes, snapshot.anonRssInKilobytes, snapshot.swapInKilobytes, snapshot.rssInKilobytes, snapshot.anonRssInKilobytes, snapshot.swapInKilobytes, snapshot.anonRssInKilobytes + snapshot.swapInKilobytes, gpuMemPerPid.get(pid), false /* has_foreground_services */, gpuMemPerPid.get(pid), false /* has_foreground_services */, snapshot.rssShmemKilobytes, // Native processes don't really have a hosting component type. HOSTING_COMPONENT_TYPE_EMPTY, HOSTING_COMPONENT_TYPE_EMPTY)); HOSTING_COMPONENT_TYPE_EMPTY, dmaBufRssInKilobytes)); } return StatsManager.PULL_SUCCESS; } Loading