diff options
3 files changed, 54 insertions, 3 deletions
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index b84bf6b90711..f42641ece09b 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -1376,9 +1376,11 @@ public class OomAdjuster { ProcessRecord app = lruList.get(i); final ProcessStateRecord state = app.mState; if (!app.isKilledByAm() && app.getThread() != null) { - // We don't need to apply the update for the process which didn't get computed - if (state.getCompletedAdjSeq() == mAdjSeq) { - applyOomAdjLSP(app, doingAll, now, nowElapsed, oomAdjReason, true); + if (!Flags.fixApplyOomadjOrder()) { + // We don't need to apply the update for the process which didn't get computed + if (state.getCompletedAdjSeq() == mAdjSeq) { + applyOomAdjLSP(app, doingAll, now, nowElapsed, oomAdjReason, true); + } } if (app.isPendingFinishAttach()) { @@ -1480,6 +1482,19 @@ public class OomAdjuster { } } + if (Flags.fixApplyOomadjOrder()) { + // We need to apply the update starting from the least recently used. + // Otherwise, they won't be in the correct LRU order in LMKD. + for (int i = 0; i < numLru; i++) { + ProcessRecord app = lruList.get(i); + // We don't need to apply the update for the process which didn't get computed + if (!app.isKilledByAm() && app.getThread() != null + && app.mState.getCompletedAdjSeq() == mAdjSeq) { + applyOomAdjLSP(app, doingAll, now, nowElapsed, oomAdjReason, true); + } + } + } + if (!mProcsToOomAdj.isEmpty()) { mInjector.batchSetOomAdj(mProcsToOomAdj); mProcsToOomAdj.clear(); diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig index 6d247d227774..89e4a8d82676 100644 --- a/services/core/java/com/android/server/am/flags.aconfig +++ b/services/core/java/com/android/server/am/flags.aconfig @@ -245,6 +245,14 @@ flag { } flag { + name: "fix_apply_oomadj_order" + namespace: "backstage_power" + is_fixed_read_only: true + description: "Fix the iteration direction of process LRU list when applying oom adj" + bug: "378580264" +} + +flag { name: "phantom_processes_fix" namespace: "backstage_power" description: "Make sure setProcessGroupForPhantomProcessOfApp deals with phantom processes properly" diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java index a9569b4096ff..1efe4707fc11 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java @@ -105,6 +105,7 @@ import android.os.PowerManagerInternal; import android.os.Process; import android.os.SystemClock; import android.os.UserHandle; +import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.Presubmit; import android.platform.test.flag.junit.SetFlagsRule; import android.util.ArrayMap; @@ -3260,6 +3261,24 @@ public class MockingOomAdjusterTests { "cch-empty"); } + @SuppressWarnings("GuardedBy") + @Test + @EnableFlags(Flags.FLAG_FIX_APPLY_OOMADJ_ORDER) + public void testUpdateOomAdj_ApplyOomAdjInCorrectOrder() { + final int numberOfApps = 5; + final ProcessRecord[] apps = new ProcessRecord[numberOfApps]; + for (int i = 0; i < numberOfApps; i++) { + apps[i] = spy(makeDefaultProcessRecord(MOCKAPP_PID + i, MOCKAPP_UID + i, + MOCKAPP_PROCESSNAME + i, MOCKAPP_PACKAGENAME + i, true)); + } + updateOomAdj(apps); + for (int i = 1; i < numberOfApps; i++) { + final int pre = mInjector.mSetOomAdjAppliedAt.get(apps[i - 1].mPid); + final int cur = mInjector.mSetOomAdjAppliedAt.get(apps[i].mPid); + assertTrue("setOomAdj is called in wrong order", pre < cur); + } + } + private ProcessRecord makeDefaultProcessRecord(int pid, int uid, String processName, String packageName, boolean hasShownUi) { return new ProcessRecordBuilder(pid, uid, processName, packageName).setHasShownUi( @@ -3589,9 +3608,16 @@ public class MockingOomAdjusterTests { long mTimeOffsetMillis = 0; private SparseIntArray mLastSetOomAdj = new SparseIntArray(); + // A sequence number that increases every time setOomAdj is called + int mLastAppliedAt = 0; + // Holds the last sequence number setOomAdj is called for a pid + private SparseIntArray mSetOomAdjAppliedAt = new SparseIntArray(); + void reset() { mTimeOffsetMillis = 0; mLastSetOomAdj.clear(); + mLastAppliedAt = 0; + mSetOomAdjAppliedAt.clear(); } void jumpUptimeAheadTo(long uptimeMillis) { @@ -3616,6 +3642,7 @@ public class MockingOomAdjusterTests { final int pid = proc.getPid(); if (pid <= 0) continue; mLastSetOomAdj.put(pid, proc.mState.getCurAdj()); + mSetOomAdjAppliedAt.put(pid, mLastAppliedAt++); } } @@ -3623,6 +3650,7 @@ public class MockingOomAdjusterTests { void setOomAdj(int pid, int uid, int adj) { if (pid <= 0) return; mLastSetOomAdj.put(pid, adj); + mSetOomAdjAppliedAt.put(pid, mLastAppliedAt++); } @Override |