summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2018-10-17 16:30:55 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2018-10-17 16:30:55 +0000
commit7c5c113f531d859df71244d56514b855a886165a (patch)
tree5d88123feca7a55ba82e6d19edaaca95e1e9d5cc
parent03cc437b08441f67d5e1f3d18f224385b61a4afe (diff)
parent0862158f13be9b6a940cc0b5940fe639edb89968 (diff)
Merge "Snapshot memory state for some native processes"
-rw-r--r--cmds/statsd/src/atoms.proto30
-rw-r--r--cmds/statsd/src/external/StatsPullerManager.cpp6
-rw-r--r--core/java/android/app/ActivityManagerInternal.java9
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java27
-rw-r--r--services/core/java/com/android/server/am/MemoryStatUtil.java25
-rw-r--r--services/core/java/com/android/server/stats/StatsCompanionService.java21
6 files changed, 116 insertions, 2 deletions
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 404599636aec..10b7c0b0117d 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -146,7 +146,7 @@ message Atom {
}
// Pulled events will start at field 10000.
- // Next: 10025
+ // Next: 10037
oneof pulled {
WifiBytesTransfer wifi_bytes_transfer = 10000;
WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001;
@@ -184,6 +184,7 @@ message Atom {
PowerProfile power_profile = 10033;
ProcStats proc_stats_pkg_proc = 10034;
ProcessCpuTime process_cpu_time = 10035;
+ NativeProcessMemoryState native_process_memory_state = 10036;
}
// DO NOT USE field numbers above 100,000 in AOSP.
@@ -2345,6 +2346,31 @@ message ProcessMemoryState {
}
/*
+ * Logs the memory stats for a native process (from procfs).
+ */
+message NativeProcessMemoryState {
+ // The uid if available. -1 means not available.
+ optional int32 uid = 1 [(is_uid) = true];
+
+ // The process name.
+ optional string process_name = 2;
+
+ // # of page-faults
+ optional int64 pgfault = 3;
+
+ // # of major page-faults
+ optional int64 pgmajfault = 4;
+
+ // RSS
+ optional int64 rss_in_bytes = 5;
+
+ // RSS high watermark.
+ // Peak RSS usage of the process. Value is read from the VmHWM field in /proc/PID/status or
+ // from memory.max_usage_in_bytes under /dev/memcg if the device uses per-app memory cgroups.
+ optional int64 rss_high_watermark_in_bytes = 6;
+}
+
+/*
* Elapsed real time from SystemClock.
*/
message SystemElapsedRealtime {
@@ -3022,4 +3048,4 @@ message ProcessCpuTime {
optional int64 user_time_millis = 3;
// Process cpu time in system space, cumulative from boot/process start
optional int64 system_time_millis = 4;
-} \ No newline at end of file
+}
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index 4c74c1701f3e..8871d4d054c5 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -170,6 +170,12 @@ const std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = {
{2, 3},
1 * NS_PER_SEC,
new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_STATE)}},
+ // native_process_memory_state
+ {android::util::NATIVE_PROCESS_MEMORY_STATE,
+ {{3, 4, 5, 6},
+ {2},
+ 1 * NS_PER_SEC,
+ new StatsCompanionServicePuller(android::util::NATIVE_PROCESS_MEMORY_STATE)}},
// temperature
{android::util::TEMPERATURE, {{}, {}, 1 * NS_PER_SEC, new ResourceThermalManagerPuller()}},
// binder_calls
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 296c063f5379..a7836af2c1e5 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -166,10 +166,19 @@ public abstract class ActivityManagerInternal {
/**
* Returns a list that contains the memory stats for currently running processes.
+ *
+ * Only processes managed by ActivityManagerService are included.
*/
public abstract List<ProcessMemoryState> getMemoryStateForProcesses();
/**
+ * Returns a list that contains the memory stats for monitored native processes.
+ *
+ * The list of the monitored processes is defined in MemoryStatUtil class.
+ */
+ public abstract List<ProcessMemoryState> getMemoryStateForNativeProcesses();
+
+ /**
* Checks to see if the calling pid is allowed to handle the user. Returns adjusted user id as
* needed.
*/
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index d5b618f954df..f9e61347503f 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -72,7 +72,9 @@ import static android.os.Process.THREAD_GROUP_TOP_APP;
import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
import static android.os.Process.getFreeMemory;
+import static android.os.Process.getPidsForCommands;
import static android.os.Process.getTotalMemory;
+import static android.os.Process.getUidForPid;
import static android.os.Process.isThreadInProcess;
import static android.os.Process.killProcess;
import static android.os.Process.killProcessQuiet;
@@ -138,8 +140,11 @@ import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSER
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
+import static com.android.server.am.MemoryStatUtil.MEMORY_STAT_INTERESTING_NATIVE_PROCESSES;
import static com.android.server.am.MemoryStatUtil.hasMemcg;
+import static com.android.server.am.MemoryStatUtil.readCmdlineFromProcfs;
import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
+import static com.android.server.am.MemoryStatUtil.readMemoryStatFromProcfs;
import android.Manifest;
import android.Manifest.permission;
@@ -20498,6 +20503,28 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
+ public List<ProcessMemoryState> getMemoryStateForNativeProcesses() {
+ List<ProcessMemoryState> processMemoryStates = new ArrayList<>();
+ int[] pids = getPidsForCommands(MEMORY_STAT_INTERESTING_NATIVE_PROCESSES);
+ for (int i = 0; i < pids.length; i++) {
+ int pid = pids[i];
+ MemoryStat memoryStat = readMemoryStatFromProcfs(pid);
+ if (memoryStat == null) {
+ continue;
+ }
+ int uid = getUidForPid(pid);
+ String processName = readCmdlineFromProcfs(pid);
+ int oomScore = -1; // Unused, not included in the NativeProcessMemoryState atom.
+ ProcessMemoryState processMemoryState = new ProcessMemoryState(uid, processName,
+ oomScore, memoryStat.pgfault, memoryStat.pgmajfault,
+ memoryStat.rssInBytes, memoryStat.cacheInBytes, memoryStat.swapInBytes,
+ memoryStat.rssHighWatermarkInBytes);
+ processMemoryStates.add(processMemoryState);
+ }
+ return processMemoryStates;
+ }
+
+ @Override
public int handleIncomingUser(int callingPid, int callingUid, int userId,
boolean allowAll, int allowMode, String name, String callerPackage) {
return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
diff --git a/services/core/java/com/android/server/am/MemoryStatUtil.java b/services/core/java/com/android/server/am/MemoryStatUtil.java
index 98f3f95ebb87..23ae77d9a756 100644
--- a/services/core/java/com/android/server/am/MemoryStatUtil.java
+++ b/services/core/java/com/android/server/am/MemoryStatUtil.java
@@ -37,6 +37,17 @@ import java.util.regex.Pattern;
* Static utility methods related to {@link MemoryStat}.
*/
final class MemoryStatUtil {
+ /**
+ * Which native processes to create {@link MemoryStat} for.
+ *
+ * <p>Processes are matched by their cmdline in procfs. Example: cat /proc/pid/cmdline returns
+ * /system/bin/statsd for the stats daemon.
+ */
+ static final String[] MEMORY_STAT_INTERESTING_NATIVE_PROCESSES = new String[]{
+ "/system/bin/statsd", // Stats daemon.
+ "/system/bin/surfaceflinger",
+ };
+
static final int BYTES_IN_KILOBYTE = 1024;
static final int PAGE_SIZE = 4096;
@@ -57,6 +68,8 @@ final class MemoryStatUtil {
private static final String PROC_STAT_FILE_FMT = "/proc/%d/stat";
/** Path to procfs status file for logging app memory state */
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";
private static final Pattern PGFAULT = Pattern.compile("total_pgfault (\\d+)");
private static final Pattern PGMAJFAULT = Pattern.compile("total_pgmajfault (\\d+)");
@@ -119,6 +132,18 @@ final class MemoryStatUtil {
return stat;
}
+ /**
+ * Reads cmdline of a process from procfs.
+ *
+ * Returns content of /proc/pid/cmdline (e.g. /system/bin/statsd) or an empty string
+ * if the file is not available.
+ */
+ static String readCmdlineFromProcfs(int pid) {
+ String path = String.format(Locale.US, PROC_CMDLINE_FILE_FMT, pid);
+ String cmdline = readFileContents(path);
+ return cmdline != null ? cmdline : "";
+ }
+
private static String readFileContents(String path) {
final File file = new File(path);
if (!file.exists()) {
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index 14434cdcb4f7..6db7e4f1a800 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -1004,6 +1004,23 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
}
}
+ private void pullNativeProcessMemoryState(
+ int tagId, long elapsedNanos, long wallClockNanos,
+ List<StatsLogEventWrapper> pulledData) {
+ List<ProcessMemoryState> processMemoryStates = LocalServices.getService(
+ ActivityManagerInternal.class).getMemoryStateForNativeProcesses();
+ for (ProcessMemoryState processMemoryState : processMemoryStates) {
+ StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
+ e.writeInt(processMemoryState.uid);
+ e.writeString(processMemoryState.processName);
+ e.writeLong(processMemoryState.pgfault);
+ e.writeLong(processMemoryState.pgmajfault);
+ e.writeLong(processMemoryState.rssInBytes);
+ e.writeLong(processMemoryState.rssHighWatermarkInBytes);
+ pulledData.add(e);
+ }
+ }
+
private void pullBinderCallsStats(
int tagId, long elapsedNanos, long wallClockNanos,
List<StatsLogEventWrapper> pulledData) {
@@ -1509,6 +1526,10 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
pullProcessMemoryState(tagId, elapsedNanos, wallClockNanos, ret);
break;
}
+ case StatsLog.NATIVE_PROCESS_MEMORY_STATE: {
+ pullNativeProcessMemoryState(tagId, elapsedNanos, wallClockNanos, ret);
+ break;
+ }
case StatsLog.BINDER_CALLS: {
pullBinderCallsStats(tagId, elapsedNanos, wallClockNanos, ret);
break;