Loading cmds/statsd/src/atoms.proto +12 −1 Original line number Diff line number Diff line Loading @@ -253,7 +253,7 @@ message Atom { } // Pulled events will start at field 10000. // Next: 10056 // Next: 10057 oneof pulled { WifiBytesTransfer wifi_bytes_transfer = 10000; WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001; Loading Loading @@ -311,6 +311,7 @@ message Atom { SDCardInfo sdcard_info = 10053; GpuStatsGlobalInfo gpu_stats_global_info = 10054; GpuStatsAppInfo gpu_stats_app_info = 10055; SystemIonHeapSize system_ion_heap_size = 10056; } // DO NOT USE field numbers above 100,000 in AOSP. Loading Loading @@ -5822,3 +5823,13 @@ message GpuStatsAppInfo { optional GpuDriverLoadingTime vk_driver_loading_time = 4 [(android.os.statsd.log_mode) = MODE_BYTES]; } /* * Logs the size of the system ion heap. * * Pulled from StatsCompanionService. */ message SystemIonHeapSize { // Size of the system ion heap in bytes. optional int64 size_in_bytes = 1; } cmds/statsd/src/external/StatsPullerManager.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -148,10 +148,14 @@ std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = { {android::util::NATIVE_PROCESS_MEMORY_STATE, {.additiveFields = {3, 4, 5, 6}, .puller = new StatsCompanionServicePuller(android::util::NATIVE_PROCESS_MEMORY_STATE)}}, // process_memory_high_water_mark {android::util::PROCESS_MEMORY_HIGH_WATER_MARK, {.additiveFields = {3}, .puller = new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_HIGH_WATER_MARK)}}, // system_ion_heap_size {android::util::SYSTEM_ION_HEAP_SIZE, {.puller = new StatsCompanionServicePuller(android::util::SYSTEM_ION_HEAP_SIZE)}}, // temperature {android::util::TEMPERATURE, {.puller = new StatsCompanionServicePuller(android::util::TEMPERATURE)}}, Loading services/core/java/com/android/server/am/MemoryStatUtil.java +27 −1 Original line number Diff line number Diff line Loading @@ -57,15 +57,18 @@ public final class MemoryStatUtil { private static final String PROC_STATUS_FILE_FMT = "/proc/%d/status"; /** Path to procfs cmdline file. Used with pid: /proc/pid/cmdline. */ private static final String PROC_CMDLINE_FILE_FMT = "/proc/%d/cmdline"; /** Path to debugfs file for the system ion heap. */ private static final String DEBUG_SYSTEM_ION_HEAP_FILE = "/sys/kernel/debug/ion/heaps/system"; private static final Pattern PGFAULT = Pattern.compile("total_pgfault (\\d+)"); private static final Pattern PGMAJFAULT = Pattern.compile("total_pgmajfault (\\d+)"); private static final Pattern RSS_IN_BYTES = Pattern.compile("total_rss (\\d+)"); private static final Pattern CACHE_IN_BYTES = Pattern.compile("total_cache (\\d+)"); private static final Pattern SWAP_IN_BYTES = Pattern.compile("total_swap (\\d+)"); private static final Pattern RSS_HIGH_WATERMARK_IN_BYTES = Pattern.compile("VmHWM:\\s*(\\d+)\\s*kB"); private static final Pattern ION_HEAP_SIZE_IN_BYTES = Pattern.compile("\n\\s*total\\s*(\\d+)\\s*\n"); private static final int PGFAULT_INDEX = 9; private static final int PGMAJFAULT_INDEX = 11; Loading Loading @@ -127,6 +130,16 @@ public final class MemoryStatUtil { return parseCmdlineFromProcfs(readFileContents(path)); } /** * Reads size of the system ion heap from debugfs. * * Returns value of the total size in bytes of the system ion heap from * /sys/kernel/debug/ion/heaps/system. */ public static long readSystemIonHeapSizeFromDebugfs() { return parseIonHeapSizeFromDebugfs(readFileContents(DEBUG_SYSTEM_ION_HEAP_FILE)); } private static String readFileContents(String path) { final File file = new File(path); if (!file.exists()) { Loading Loading @@ -227,6 +240,19 @@ public final class MemoryStatUtil { return cmdline.substring(0, firstNullByte); } /** * Parses the ion heap size from the contents of a file under /sys/kernel/debug/ion/heaps in * debugfs. The returned value is in bytes. */ @VisibleForTesting static long parseIonHeapSizeFromDebugfs(String contents) { if (contents == null || contents.isEmpty()) { return 0; } Matcher m = ION_HEAP_SIZE_IN_BYTES.matcher(contents); return m.find() ? Long.parseLong(m.group(1)) : 0; } /** * Returns whether per-app memcg is available on device. */ Loading services/core/java/com/android/server/stats/StatsCompanionService.java +14 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static com.android.internal.util.Preconditions.checkNotNull; import static com.android.server.am.MemoryStatUtil.readCmdlineFromProcfs; import static com.android.server.am.MemoryStatUtil.readMemoryStatFromProcfs; import static com.android.server.am.MemoryStatUtil.readRssHighWaterMarkFromProcfs; import static com.android.server.am.MemoryStatUtil.readSystemIonHeapSizeFromDebugfs; import android.annotation.NonNull; import android.annotation.Nullable; Loading Loading @@ -1182,6 +1183,15 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { SystemProperties.set("sys.rss_hwm_reset.on", "1"); } private void pullSystemIonHeapSize( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData) { final long systemIonHeapSizeInBytes = readSystemIonHeapSizeFromDebugfs(); StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeLong(systemIonHeapSizeInBytes); pulledData.add(e); } private void pullBinderCallsStats( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData) { Loading Loading @@ -2068,6 +2078,10 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { pullProcessMemoryHighWaterMark(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.SYSTEM_ION_HEAP_SIZE: { pullSystemIonHeapSize(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.BINDER_CALLS: { pullBinderCallsStats(tagId, elapsedNanos, wallClockNanos, ret); break; Loading services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java +45 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static com.android.server.am.MemoryStatUtil.JIFFY_NANOS; import static com.android.server.am.MemoryStatUtil.MemoryStat; import static com.android.server.am.MemoryStatUtil.PAGE_SIZE; import static com.android.server.am.MemoryStatUtil.parseCmdlineFromProcfs; import static com.android.server.am.MemoryStatUtil.parseIonHeapSizeFromDebugfs; import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromMemcg; import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromProcfs; import static com.android.server.am.MemoryStatUtil.parseVmHWMFromProcfs; Loading Loading @@ -178,6 +179,33 @@ public class MemoryStatUtilTest { + "voluntary_ctxt_switches:\t903\n" + "nonvoluntary_ctxt_switches:\t104\n"; private static final String DEBUG_SYSTEM_ION_HEAP_CONTENTS = String.join( " client pid size\n", "----------------------------------------------------\n", " audio@2.0-servi 765 4096\n", " audio@2.0-servi 765 61440\n", " audio@2.0-servi 765 4096\n", " voip_client 96 8192\n", " voip_client 96 4096\n", " system_server 1232 16728064\n", " surfaceflinger 611 50642944\n", "----------------------------------------------------\n", "orphaned allocations (info is from last known client):\n", "----------------------------------------------------\n", " total orphaned 0\n", " total 55193600\n", " deferred free 0\n", "----------------------------------------------------\n", "0 order 4 highmem pages in uncached pool = 0 total\n", "0 order 4 lowmem pages in uncached pool = 0 total\n", "1251 order 4 lowmem pages in cached pool = 81985536 total\n", "VMID 8: 0 order 4 highmem pages in secure pool = 0 total\n", "VMID 8: 0 order 4 lowmem pages in secure pool = 0 total\n", "--------------------------------------------\n", "uncached pool = 4096 cached pool = 83566592 secure pool = 0\n", "pool total (uncached + cached + secure) = 83570688\n", "--------------------------------------------\n"); @Test public void testParseMemoryStatFromMemcg_parsesCorrectValues() { MemoryStat stat = parseMemoryStatFromMemcg(MEMORY_STAT_CONTENTS); Loading Loading @@ -271,4 +299,21 @@ public class MemoryStatUtilTest { output.write(bytes, 0, bytes.length); return output.toString(); } @Test public void testParseIonHeapSizeFromDebugfs_emptyContents() { assertEquals(0, parseIonHeapSizeFromDebugfs("")); assertEquals(0, parseIonHeapSizeFromDebugfs(null)); } @Test public void testParseIonHeapSizeFromDebugfs_invalidValue() { assertEquals(0, parseIonHeapSizeFromDebugfs("<<no-value>>")); } @Test public void testParseIonHeapSizeFromDebugfs_correctValue() { assertEquals(55193600, parseIonHeapSizeFromDebugfs(DEBUG_SYSTEM_ION_HEAP_CONTENTS)); } } Loading
cmds/statsd/src/atoms.proto +12 −1 Original line number Diff line number Diff line Loading @@ -253,7 +253,7 @@ message Atom { } // Pulled events will start at field 10000. // Next: 10056 // Next: 10057 oneof pulled { WifiBytesTransfer wifi_bytes_transfer = 10000; WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001; Loading Loading @@ -311,6 +311,7 @@ message Atom { SDCardInfo sdcard_info = 10053; GpuStatsGlobalInfo gpu_stats_global_info = 10054; GpuStatsAppInfo gpu_stats_app_info = 10055; SystemIonHeapSize system_ion_heap_size = 10056; } // DO NOT USE field numbers above 100,000 in AOSP. Loading Loading @@ -5822,3 +5823,13 @@ message GpuStatsAppInfo { optional GpuDriverLoadingTime vk_driver_loading_time = 4 [(android.os.statsd.log_mode) = MODE_BYTES]; } /* * Logs the size of the system ion heap. * * Pulled from StatsCompanionService. */ message SystemIonHeapSize { // Size of the system ion heap in bytes. optional int64 size_in_bytes = 1; }
cmds/statsd/src/external/StatsPullerManager.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -148,10 +148,14 @@ std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = { {android::util::NATIVE_PROCESS_MEMORY_STATE, {.additiveFields = {3, 4, 5, 6}, .puller = new StatsCompanionServicePuller(android::util::NATIVE_PROCESS_MEMORY_STATE)}}, // process_memory_high_water_mark {android::util::PROCESS_MEMORY_HIGH_WATER_MARK, {.additiveFields = {3}, .puller = new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_HIGH_WATER_MARK)}}, // system_ion_heap_size {android::util::SYSTEM_ION_HEAP_SIZE, {.puller = new StatsCompanionServicePuller(android::util::SYSTEM_ION_HEAP_SIZE)}}, // temperature {android::util::TEMPERATURE, {.puller = new StatsCompanionServicePuller(android::util::TEMPERATURE)}}, Loading
services/core/java/com/android/server/am/MemoryStatUtil.java +27 −1 Original line number Diff line number Diff line Loading @@ -57,15 +57,18 @@ public final class MemoryStatUtil { private static final String PROC_STATUS_FILE_FMT = "/proc/%d/status"; /** Path to procfs cmdline file. Used with pid: /proc/pid/cmdline. */ private static final String PROC_CMDLINE_FILE_FMT = "/proc/%d/cmdline"; /** Path to debugfs file for the system ion heap. */ private static final String DEBUG_SYSTEM_ION_HEAP_FILE = "/sys/kernel/debug/ion/heaps/system"; private static final Pattern PGFAULT = Pattern.compile("total_pgfault (\\d+)"); private static final Pattern PGMAJFAULT = Pattern.compile("total_pgmajfault (\\d+)"); private static final Pattern RSS_IN_BYTES = Pattern.compile("total_rss (\\d+)"); private static final Pattern CACHE_IN_BYTES = Pattern.compile("total_cache (\\d+)"); private static final Pattern SWAP_IN_BYTES = Pattern.compile("total_swap (\\d+)"); private static final Pattern RSS_HIGH_WATERMARK_IN_BYTES = Pattern.compile("VmHWM:\\s*(\\d+)\\s*kB"); private static final Pattern ION_HEAP_SIZE_IN_BYTES = Pattern.compile("\n\\s*total\\s*(\\d+)\\s*\n"); private static final int PGFAULT_INDEX = 9; private static final int PGMAJFAULT_INDEX = 11; Loading Loading @@ -127,6 +130,16 @@ public final class MemoryStatUtil { return parseCmdlineFromProcfs(readFileContents(path)); } /** * Reads size of the system ion heap from debugfs. * * Returns value of the total size in bytes of the system ion heap from * /sys/kernel/debug/ion/heaps/system. */ public static long readSystemIonHeapSizeFromDebugfs() { return parseIonHeapSizeFromDebugfs(readFileContents(DEBUG_SYSTEM_ION_HEAP_FILE)); } private static String readFileContents(String path) { final File file = new File(path); if (!file.exists()) { Loading Loading @@ -227,6 +240,19 @@ public final class MemoryStatUtil { return cmdline.substring(0, firstNullByte); } /** * Parses the ion heap size from the contents of a file under /sys/kernel/debug/ion/heaps in * debugfs. The returned value is in bytes. */ @VisibleForTesting static long parseIonHeapSizeFromDebugfs(String contents) { if (contents == null || contents.isEmpty()) { return 0; } Matcher m = ION_HEAP_SIZE_IN_BYTES.matcher(contents); return m.find() ? Long.parseLong(m.group(1)) : 0; } /** * Returns whether per-app memcg is available on device. */ Loading
services/core/java/com/android/server/stats/StatsCompanionService.java +14 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static com.android.internal.util.Preconditions.checkNotNull; import static com.android.server.am.MemoryStatUtil.readCmdlineFromProcfs; import static com.android.server.am.MemoryStatUtil.readMemoryStatFromProcfs; import static com.android.server.am.MemoryStatUtil.readRssHighWaterMarkFromProcfs; import static com.android.server.am.MemoryStatUtil.readSystemIonHeapSizeFromDebugfs; import android.annotation.NonNull; import android.annotation.Nullable; Loading Loading @@ -1182,6 +1183,15 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { SystemProperties.set("sys.rss_hwm_reset.on", "1"); } private void pullSystemIonHeapSize( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData) { final long systemIonHeapSizeInBytes = readSystemIonHeapSizeFromDebugfs(); StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeLong(systemIonHeapSizeInBytes); pulledData.add(e); } private void pullBinderCallsStats( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData) { Loading Loading @@ -2068,6 +2078,10 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { pullProcessMemoryHighWaterMark(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.SYSTEM_ION_HEAP_SIZE: { pullSystemIonHeapSize(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.BINDER_CALLS: { pullBinderCallsStats(tagId, elapsedNanos, wallClockNanos, ret); break; Loading
services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java +45 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static com.android.server.am.MemoryStatUtil.JIFFY_NANOS; import static com.android.server.am.MemoryStatUtil.MemoryStat; import static com.android.server.am.MemoryStatUtil.PAGE_SIZE; import static com.android.server.am.MemoryStatUtil.parseCmdlineFromProcfs; import static com.android.server.am.MemoryStatUtil.parseIonHeapSizeFromDebugfs; import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromMemcg; import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromProcfs; import static com.android.server.am.MemoryStatUtil.parseVmHWMFromProcfs; Loading Loading @@ -178,6 +179,33 @@ public class MemoryStatUtilTest { + "voluntary_ctxt_switches:\t903\n" + "nonvoluntary_ctxt_switches:\t104\n"; private static final String DEBUG_SYSTEM_ION_HEAP_CONTENTS = String.join( " client pid size\n", "----------------------------------------------------\n", " audio@2.0-servi 765 4096\n", " audio@2.0-servi 765 61440\n", " audio@2.0-servi 765 4096\n", " voip_client 96 8192\n", " voip_client 96 4096\n", " system_server 1232 16728064\n", " surfaceflinger 611 50642944\n", "----------------------------------------------------\n", "orphaned allocations (info is from last known client):\n", "----------------------------------------------------\n", " total orphaned 0\n", " total 55193600\n", " deferred free 0\n", "----------------------------------------------------\n", "0 order 4 highmem pages in uncached pool = 0 total\n", "0 order 4 lowmem pages in uncached pool = 0 total\n", "1251 order 4 lowmem pages in cached pool = 81985536 total\n", "VMID 8: 0 order 4 highmem pages in secure pool = 0 total\n", "VMID 8: 0 order 4 lowmem pages in secure pool = 0 total\n", "--------------------------------------------\n", "uncached pool = 4096 cached pool = 83566592 secure pool = 0\n", "pool total (uncached + cached + secure) = 83570688\n", "--------------------------------------------\n"); @Test public void testParseMemoryStatFromMemcg_parsesCorrectValues() { MemoryStat stat = parseMemoryStatFromMemcg(MEMORY_STAT_CONTENTS); Loading Loading @@ -271,4 +299,21 @@ public class MemoryStatUtilTest { output.write(bytes, 0, bytes.length); return output.toString(); } @Test public void testParseIonHeapSizeFromDebugfs_emptyContents() { assertEquals(0, parseIonHeapSizeFromDebugfs("")); assertEquals(0, parseIonHeapSizeFromDebugfs(null)); } @Test public void testParseIonHeapSizeFromDebugfs_invalidValue() { assertEquals(0, parseIonHeapSizeFromDebugfs("<<no-value>>")); } @Test public void testParseIonHeapSizeFromDebugfs_correctValue() { assertEquals(55193600, parseIonHeapSizeFromDebugfs(DEBUG_SYSTEM_ION_HEAP_CONTENTS)); } }