Report latest RSS for LMKD kills
Adjust LMK_PROCKILL message to receive the victim's RSS at the time of
the kill. Update ApplicationExitInfo, of the related LMKD victim, and
set the latest RSS data.
Test: Verify LMKD reported kill is reported with latest RSS to telemetry
Test: atest ApplicationExitInfoTest -c
Flag: NA
Bug: 322549716
Change-Id: I7e6cd0368013815ddc298ea2bb2a5afd584654d7
Signed-off-by: Carlos Galo <carlosgalo@google.com>
diff --git a/services/core/java/com/android/server/am/AppExitInfoTracker.java b/services/core/java/com/android/server/am/AppExitInfoTracker.java
index 47b65eb..1f88657 100644
--- a/services/core/java/com/android/server/am/AppExitInfoTracker.java
+++ b/services/core/java/com/android/server/am/AppExitInfoTracker.java
@@ -353,8 +353,8 @@
}
/** Called when there is a low memory kill */
- void scheduleNoteLmkdProcKilled(final int pid, final int uid) {
- mKillHandler.obtainMessage(KillHandler.MSG_LMKD_PROC_KILLED, pid, uid)
+ void scheduleNoteLmkdProcKilled(final int pid, final int uid, final int rssKb) {
+ mKillHandler.obtainMessage(KillHandler.MSG_LMKD_PROC_KILLED, pid, uid, Long.valueOf(rssKb))
.sendToTarget();
}
@@ -401,9 +401,9 @@
if (lmkd != null) {
updateExistingExitInfoRecordLocked(info, null,
- ApplicationExitInfo.REASON_LOW_MEMORY);
+ ApplicationExitInfo.REASON_LOW_MEMORY, (Long) lmkd.second);
} else if (zygote != null) {
- updateExistingExitInfoRecordLocked(info, (Integer) zygote.second, null);
+ updateExistingExitInfoRecordLocked(info, (Integer) zygote.second, null, null);
} else {
scheduleLogToStatsdLocked(info, false);
}
@@ -486,7 +486,7 @@
*/
@GuardedBy("mLock")
private void updateExistingExitInfoRecordLocked(ApplicationExitInfo info,
- Integer status, Integer reason) {
+ Integer status, Integer reason, Long rssKb) {
if (info == null || !isFresh(info.getTimestamp())) {
// if the record is way outdated, don't update it then (because of potential pid reuse)
return;
@@ -513,6 +513,9 @@
immediateLog = true;
}
}
+ if (rssKb != null) {
+ info.setRss(rssKb.longValue());
+ }
scheduleLogToStatsdLocked(info, immediateLog);
}
@@ -523,7 +526,7 @@
*/
@GuardedBy("mLock")
private boolean updateExitInfoIfNecessaryLocked(
- int pid, int uid, Integer status, Integer reason) {
+ int pid, int uid, Integer status, Integer reason, Long rssKb) {
Integer k = mIsolatedUidRecords.getUidByIsolatedUid(uid);
if (k != null) {
uid = k;
@@ -552,7 +555,7 @@
// always be the first one we se as `getExitInfosLocked()` returns them sorted
// by most-recent-first.
isModified[0] = true;
- updateExistingExitInfoRecordLocked(info, status, reason);
+ updateExistingExitInfoRecordLocked(info, status, reason, rssKb);
return FOREACH_ACTION_STOP_ITERATION;
}
return FOREACH_ACTION_NONE;
@@ -1668,11 +1671,11 @@
switch (msg.what) {
case MSG_LMKD_PROC_KILLED:
mAppExitInfoSourceLmkd.onProcDied(msg.arg1 /* pid */, msg.arg2 /* uid */,
- null /* status */);
+ null /* status */, (Long) msg.obj /* rss_kb */);
break;
case MSG_CHILD_PROC_DIED:
mAppExitInfoSourceZygote.onProcDied(msg.arg1 /* pid */, msg.arg2 /* uid */,
- (Integer) msg.obj /* status */);
+ (Integer) msg.obj /* status */, null /* rss_kb */);
break;
case MSG_PROC_DIED: {
ApplicationExitInfo raw = (ApplicationExitInfo) msg.obj;
@@ -1833,7 +1836,7 @@
}
}
- void onProcDied(final int pid, final int uid, final Integer status) {
+ void onProcDied(final int pid, final int uid, final Integer status, final Long rssKb) {
if (DEBUG_PROCESSES) {
Slog.i(TAG, mTag + ": proc died: pid=" + pid + " uid=" + uid
+ ", status=" + status);
@@ -1846,8 +1849,12 @@
// Unlikely but possible: the record has been created
// Let's update it if we could find a ApplicationExitInfo record
synchronized (mLock) {
- if (!updateExitInfoIfNecessaryLocked(pid, uid, status, mPresetReason)) {
- addLocked(pid, uid, status);
+ if (!updateExitInfoIfNecessaryLocked(pid, uid, status, mPresetReason, rssKb)) {
+ if (rssKb != null) {
+ addLocked(pid, uid, rssKb); // lmkd
+ } else {
+ addLocked(pid, uid, status); // zygote
+ }
}
// Notify any interesed party regarding the lmkd kills
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 97678aa..b239b64 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -945,12 +945,14 @@
try {
switch (inputData.readInt()) {
case LMK_PROCKILL:
- if (receivedLen != 12) {
+ if (receivedLen != 16) {
return false;
}
final int pid = inputData.readInt();
final int uid = inputData.readInt();
- mAppExitInfoTracker.scheduleNoteLmkdProcKilled(pid, uid);
+ final int rssKb = inputData.readInt();
+ mAppExitInfoTracker.scheduleNoteLmkdProcKilled(pid, uid,
+ rssKb);
return true;
case LMK_KILL_OCCURRED:
if (receivedLen
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
index adcbf5c..194bf4b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
@@ -442,20 +442,24 @@
IMPORTANCE_FOREGROUND_SERVICE, // importance
null); // description
- // Case 4: Create a process from another package with kill from lmkd
+ /*
+ * Case 4: Create a process from another package with kill from lmkd
+ * We expect LMKD's reported RSS to be the process' last seen RSS.
+ */
final int app2UidUser2 = 1010234;
final int app2PidUser2 = 12348;
final long app2Pss1 = 54321;
final long app2Rss1 = 65432;
+ final long lmkd_reported_rss = 43215;
final String app2ProcessName = "com.android.test.stub2:process";
final String app2PackageName = "com.android.test.stub2";
sleep(1);
final long now4 = System.currentTimeMillis();
- doReturn(new Pair<Long, Object>(now4, Integer.valueOf(0)))
+ doReturn(null)
.when(mAppExitInfoTracker.mAppExitInfoSourceZygote)
.remove(anyInt(), anyInt());
- doReturn(new Pair<Long, Object>(now4, null))
+ doReturn(new Pair<Long, Object>(now4, Long.valueOf(lmkd_reported_rss)))
.when(mAppExitInfoTracker.mAppExitInfoSourceLmkd)
.remove(anyInt(), anyInt());
@@ -490,7 +494,7 @@
null, // subReason
0, // status
app2Pss1, // pss
- app2Rss1, // rss
+ lmkd_reported_rss, // rss
IMPORTANCE_CACHED, // importance
null); // description
@@ -499,6 +503,11 @@
mAppExitInfoTracker.getExitInfo(null, app2UidUser2, 0, 0, list);
assertEquals(1, list.size());
+ info = list.get(0);
+
+ // Verify the AppExitInfo has the LMKD reported RSS
+ assertEquals(lmkd_reported_rss, info.getRss());
+
// Case 5: App native crash
final int app3UidUser2 = 1010345;
final int app3PidUser2 = 12349;
@@ -599,7 +608,7 @@
null, // subReason
0, // status
app2Pss1, // pss
- app2Rss1, // rss
+ lmkd_reported_rss, // rss
IMPORTANCE_CACHED, // importance
null); // description