diff options
| author | 2024-07-15 17:22:26 +0000 | |
|---|---|---|
| committer | 2024-07-24 18:31:43 +0000 | |
| commit | fceb1be91e1bd6ca61879dd3fad8ba8bc4fb3e42 (patch) | |
| tree | 438751680f7ac7c03d910e4bd0cedbd1c4af4ea8 | |
| parent | f8a9a6f863911a62e259adc8768400a29dc97e53 (diff) | |
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>
3 files changed, 37 insertions, 19 deletions
diff --git a/services/core/java/com/android/server/am/AppExitInfoTracker.java b/services/core/java/com/android/server/am/AppExitInfoTracker.java index 47b65eb885ab..1f88657e5dbc 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 @@ public final class AppExitInfoTracker { } /** 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 @@ public final class AppExitInfoTracker { 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 @@ public final class AppExitInfoTracker { */ @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 @@ public final class AppExitInfoTracker { immediateLog = true; } } + if (rssKb != null) { + info.setRss(rssKb.longValue()); + } scheduleLogToStatsdLocked(info, immediateLog); } @@ -523,7 +526,7 @@ public final class AppExitInfoTracker { */ @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 @@ public final class AppExitInfoTracker { // 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 @@ public final class AppExitInfoTracker { 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 @@ public final class AppExitInfoTracker { } } - 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 @@ public final class AppExitInfoTracker { // 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 97678aa922a4..b239b6476564 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 @@ public final class ProcessList { 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 adcbf5c9d059..194bf4ba73f3 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 @@ public class ApplicationExitInfoTest { 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 @@ public class ApplicationExitInfoTest { null, // subReason 0, // status app2Pss1, // pss - app2Rss1, // rss + lmkd_reported_rss, // rss IMPORTANCE_CACHED, // importance null); // description @@ -499,6 +503,11 @@ public class ApplicationExitInfoTest { 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 @@ public class ApplicationExitInfoTest { null, // subReason 0, // status app2Pss1, // pss - app2Rss1, // rss + lmkd_reported_rss, // rss IMPORTANCE_CACHED, // importance null); // description |