Loading services/core/java/com/android/server/am/ActivityManagerConstants.java +25 −0 Original line number Diff line number Diff line Loading @@ -169,6 +169,11 @@ final class ActivityManagerConstants extends ContentObserver { */ static final String KEY_ENABLE_NEW_OOMADJ = "enable_new_oom_adj"; /** * Whether or not to enable the batching of OOM adjuster calls to LMKD */ static final String KEY_ENABLE_BATCHING_OOM_ADJ = "enable_batching_oom_adj"; private static final int DEFAULT_MAX_CACHED_PROCESSES = 1024; private static final boolean DEFAULT_PRIORITIZE_ALARM_BROADCASTS = true; private static final long DEFAULT_FGSERVICE_MIN_SHOWN_TIME = 2*1000; Loading Loading @@ -243,6 +248,11 @@ final class ActivityManagerConstants extends ContentObserver { */ private static final boolean DEFAULT_ENABLE_NEW_OOM_ADJ = Flags.oomadjusterCorrectnessRewrite(); /** * The default value to {@link #KEY_ENABLE_BATCHING_OOM_ADJ}. */ private static final boolean DEFAULT_ENABLE_BATCHING_OOM_ADJ = Flags.batchingOomAdj(); /** * Same as {@link TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED} */ Loading Loading @@ -1136,6 +1146,9 @@ final class ActivityManagerConstants extends ContentObserver { /** @see #KEY_ENABLE_NEW_OOMADJ */ public boolean ENABLE_NEW_OOMADJ = DEFAULT_ENABLE_NEW_OOM_ADJ; /** @see #KEY_ENABLE_BATCHING_OOM_ADJ */ public boolean ENABLE_BATCHING_OOM_ADJ = DEFAULT_ENABLE_BATCHING_OOM_ADJ; /** * Indicates whether PSS profiling in AppProfiler is disabled or not. */ Loading Loading @@ -1479,6 +1492,8 @@ final class ActivityManagerConstants extends ContentObserver { private void loadNativeBootDeviceConfigConstants() { ENABLE_NEW_OOMADJ = getDeviceConfigBoolean(KEY_ENABLE_NEW_OOMADJ, DEFAULT_ENABLE_NEW_OOM_ADJ); ENABLE_BATCHING_OOM_ADJ = getDeviceConfigBoolean(KEY_ENABLE_BATCHING_OOM_ADJ, DEFAULT_ENABLE_BATCHING_OOM_ADJ); } public void setOverrideMaxCachedProcesses(int value) { Loading Loading @@ -2248,6 +2263,13 @@ final class ActivityManagerConstants extends ContentObserver { mDefaultPssToRssThresholdModifier); } private void updateEnableBatchingOomAdj() { ENABLE_BATCHING_OOM_ADJ = DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_NATIVE_BOOT, KEY_ENABLE_BATCHING_OOM_ADJ, DEFAULT_ENABLE_BATCHING_OOM_ADJ); } boolean shouldDebugUidForProcState(int uid) { SparseBooleanArray ar = mProcStateDebugUids; final var size = ar.size(); Loading Loading @@ -2476,6 +2498,9 @@ final class ActivityManagerConstants extends ContentObserver { pw.print(" "); pw.print(KEY_MAX_PREVIOUS_TIME); pw.print("="); pw.println(MAX_PREVIOUS_TIME); pw.print(" "); pw.print(KEY_ENABLE_BATCHING_OOM_ADJ); pw.print("="); pw.println(ENABLE_BATCHING_OOM_ADJ); pw.println(); if (mOverrideMaxCachedProcesses >= 0) { pw.print(" mOverrideMaxCachedProcesses="); pw.println(mOverrideMaxCachedProcesses); Loading services/core/java/com/android/server/am/OomAdjuster.java +26 −3 Original line number Diff line number Diff line Loading @@ -383,6 +383,13 @@ public class OomAdjuster { protected final ArraySet<ProcessRecord> mPendingProcessSet = new ArraySet<>(); protected final ArraySet<ProcessRecord> mProcessesInCycle = new ArraySet<>(); /** * List of processes that we want to batch for LMKD to adjust their respective * OOM scores. */ @GuardedBy("mService") protected final ArrayList<ProcessRecord> mProcsToOomAdj = new ArrayList<ProcessRecord>(); /** * Flag to mark if there is an ongoing oomAdjUpdate: potentially the oomAdjUpdate * could be called recursively because of the indirect calls during the update; Loading Loading @@ -1246,7 +1253,7 @@ public class OomAdjuster { 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); applyOomAdjLSP(app, doingAll, now, nowElapsed, oomAdjReason, true); } if (app.isPendingFinishAttach()) { Loading Loading @@ -1348,6 +1355,11 @@ public class OomAdjuster { } } if (!mProcsToOomAdj.isEmpty()) { ProcessList.batchSetOomAdj(mProcsToOomAdj); mProcsToOomAdj.clear(); } if (proactiveKillsEnabled // Proactive kills enabled? && doKillExcessiveProcesses // Should kill excessive processes? && freeSwapPercent < lowSwapThresholdPercent // Swap below threshold? Loading Loading @@ -3246,10 +3258,16 @@ public class OomAdjuster { mCachedAppOptimizer.onWakefulnessChanged(wakefulness); } @GuardedBy({"mService", "mProcLock"}) protected boolean applyOomAdjLSP(ProcessRecord app, boolean doingAll, long now, long nowElapsed, @OomAdjReason int oomAdjReason) { return applyOomAdjLSP(app, doingAll, now, nowElapsed, oomAdjReason, false); } /** Applies the computed oomadj, procstate and sched group values and freezes them in set* */ @GuardedBy({"mService", "mProcLock"}) protected boolean applyOomAdjLSP(ProcessRecord app, boolean doingAll, long now, long nowElapsed, @OomAdjReason int oomAdjReson) { long nowElapsed, @OomAdjReason int oomAdjReson, boolean isBatchingOomAdj) { boolean success = true; final ProcessStateRecord state = app.mState; final UidRecord uidRec = app.getUidRecord(); Loading @@ -3266,7 +3284,12 @@ public class OomAdjuster { final int oldOomAdj = state.getSetAdj(); if (state.getCurAdj() != state.getSetAdj()) { if (isBatchingOomAdj && mConstants.ENABLE_BATCHING_OOM_ADJ) { mProcsToOomAdj.add(app); } else { ProcessList.setOomAdj(app.getPid(), app.uid, state.getCurAdj()); } if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mService.mCurOomAdjUid == app.info.uid) { String msg = "Set " + app.getPid() + " " + app.processName + " adj " + state.getCurAdj() + ": " + state.getAdjType(); Loading services/core/java/com/android/server/am/ProcessList.java +46 −0 Original line number Diff line number Diff line Loading @@ -354,6 +354,7 @@ public final class ProcessList { // LMK_KILL_OCCURRED // LMK_START_MONITORING // LMK_BOOT_COMPLETED // LMK_PROCS_PRIO static final byte LMK_TARGET = 0; static final byte LMK_PROCPRIO = 1; static final byte LMK_PROCREMOVE = 2; Loading @@ -365,6 +366,7 @@ public final class ProcessList { static final byte LMK_KILL_OCCURRED = 8; // Msg to subscribed clients on kill occurred event static final byte LMK_START_MONITORING = 9; // Start monitoring if delayed earlier static final byte LMK_BOOT_COMPLETED = 10; static final byte LMK_PROCS_PRIO = 11; // Batch option for LMK_PROCPRIO // Low Memory Killer Daemon command codes. // These must be kept in sync with async_event_type definitions in lmkd.h Loading Loading @@ -1561,6 +1563,50 @@ public final class ProcessList { } } // The max size for PROCS_PRIO cmd in LMKD private static final int MAX_PROCS_PRIO_PACKET_SIZE = 3; // (4 bytes per field * 4 fields * 3 processes per batch) + 4 bytes for the LMKD cmd private static final int MAX_OOM_ADJ_BATCH_LENGTH = ((4 * 4) * MAX_PROCS_PRIO_PACKET_SIZE) + 4; /** * Set the out-of-memory badness adjustment for a list of processes. * * @param apps App list to adjust their respective oom score. * * {@hide} */ public static void batchSetOomAdj(ArrayList<ProcessRecord> apps) { final int totalApps = apps.size(); if (totalApps == 0) { return; } ByteBuffer buf = ByteBuffer.allocate(MAX_OOM_ADJ_BATCH_LENGTH); int total_procs_in_buf = 0; buf.putInt(LMK_PROCS_PRIO); for (int i = 0; i < totalApps; i++) { final int pid = apps.get(i).getPid(); final int amt = apps.get(i).mState.getCurAdj(); final int uid = apps.get(i).uid; if (pid <= 0 || amt == UNKNOWN_ADJ) continue; if (total_procs_in_buf >= MAX_PROCS_PRIO_PACKET_SIZE) { writeLmkd(buf, null); buf.clear(); total_procs_in_buf = 0; buf.allocate(MAX_OOM_ADJ_BATCH_LENGTH); buf.putInt(LMK_PROCS_PRIO); } buf.putInt(pid); buf.putInt(uid); buf.putInt(amt); buf.putInt(0); // Default proc type to PROC_TYPE_APP total_procs_in_buf++; } writeLmkd(buf, null); } /* * {@hide} */ Loading services/core/java/com/android/server/am/flags.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -134,3 +134,11 @@ flag { purpose: PURPOSE_BUGFIX } } flag { name: "batching_oom_adj" namespace: "backstage_power" description: "Batch OOM adjustment calls to LMKD" bug: "244232958" is_fixed_read_only: true } Loading
services/core/java/com/android/server/am/ActivityManagerConstants.java +25 −0 Original line number Diff line number Diff line Loading @@ -169,6 +169,11 @@ final class ActivityManagerConstants extends ContentObserver { */ static final String KEY_ENABLE_NEW_OOMADJ = "enable_new_oom_adj"; /** * Whether or not to enable the batching of OOM adjuster calls to LMKD */ static final String KEY_ENABLE_BATCHING_OOM_ADJ = "enable_batching_oom_adj"; private static final int DEFAULT_MAX_CACHED_PROCESSES = 1024; private static final boolean DEFAULT_PRIORITIZE_ALARM_BROADCASTS = true; private static final long DEFAULT_FGSERVICE_MIN_SHOWN_TIME = 2*1000; Loading Loading @@ -243,6 +248,11 @@ final class ActivityManagerConstants extends ContentObserver { */ private static final boolean DEFAULT_ENABLE_NEW_OOM_ADJ = Flags.oomadjusterCorrectnessRewrite(); /** * The default value to {@link #KEY_ENABLE_BATCHING_OOM_ADJ}. */ private static final boolean DEFAULT_ENABLE_BATCHING_OOM_ADJ = Flags.batchingOomAdj(); /** * Same as {@link TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED} */ Loading Loading @@ -1136,6 +1146,9 @@ final class ActivityManagerConstants extends ContentObserver { /** @see #KEY_ENABLE_NEW_OOMADJ */ public boolean ENABLE_NEW_OOMADJ = DEFAULT_ENABLE_NEW_OOM_ADJ; /** @see #KEY_ENABLE_BATCHING_OOM_ADJ */ public boolean ENABLE_BATCHING_OOM_ADJ = DEFAULT_ENABLE_BATCHING_OOM_ADJ; /** * Indicates whether PSS profiling in AppProfiler is disabled or not. */ Loading Loading @@ -1479,6 +1492,8 @@ final class ActivityManagerConstants extends ContentObserver { private void loadNativeBootDeviceConfigConstants() { ENABLE_NEW_OOMADJ = getDeviceConfigBoolean(KEY_ENABLE_NEW_OOMADJ, DEFAULT_ENABLE_NEW_OOM_ADJ); ENABLE_BATCHING_OOM_ADJ = getDeviceConfigBoolean(KEY_ENABLE_BATCHING_OOM_ADJ, DEFAULT_ENABLE_BATCHING_OOM_ADJ); } public void setOverrideMaxCachedProcesses(int value) { Loading Loading @@ -2248,6 +2263,13 @@ final class ActivityManagerConstants extends ContentObserver { mDefaultPssToRssThresholdModifier); } private void updateEnableBatchingOomAdj() { ENABLE_BATCHING_OOM_ADJ = DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_NATIVE_BOOT, KEY_ENABLE_BATCHING_OOM_ADJ, DEFAULT_ENABLE_BATCHING_OOM_ADJ); } boolean shouldDebugUidForProcState(int uid) { SparseBooleanArray ar = mProcStateDebugUids; final var size = ar.size(); Loading Loading @@ -2476,6 +2498,9 @@ final class ActivityManagerConstants extends ContentObserver { pw.print(" "); pw.print(KEY_MAX_PREVIOUS_TIME); pw.print("="); pw.println(MAX_PREVIOUS_TIME); pw.print(" "); pw.print(KEY_ENABLE_BATCHING_OOM_ADJ); pw.print("="); pw.println(ENABLE_BATCHING_OOM_ADJ); pw.println(); if (mOverrideMaxCachedProcesses >= 0) { pw.print(" mOverrideMaxCachedProcesses="); pw.println(mOverrideMaxCachedProcesses); Loading
services/core/java/com/android/server/am/OomAdjuster.java +26 −3 Original line number Diff line number Diff line Loading @@ -383,6 +383,13 @@ public class OomAdjuster { protected final ArraySet<ProcessRecord> mPendingProcessSet = new ArraySet<>(); protected final ArraySet<ProcessRecord> mProcessesInCycle = new ArraySet<>(); /** * List of processes that we want to batch for LMKD to adjust their respective * OOM scores. */ @GuardedBy("mService") protected final ArrayList<ProcessRecord> mProcsToOomAdj = new ArrayList<ProcessRecord>(); /** * Flag to mark if there is an ongoing oomAdjUpdate: potentially the oomAdjUpdate * could be called recursively because of the indirect calls during the update; Loading Loading @@ -1246,7 +1253,7 @@ public class OomAdjuster { 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); applyOomAdjLSP(app, doingAll, now, nowElapsed, oomAdjReason, true); } if (app.isPendingFinishAttach()) { Loading Loading @@ -1348,6 +1355,11 @@ public class OomAdjuster { } } if (!mProcsToOomAdj.isEmpty()) { ProcessList.batchSetOomAdj(mProcsToOomAdj); mProcsToOomAdj.clear(); } if (proactiveKillsEnabled // Proactive kills enabled? && doKillExcessiveProcesses // Should kill excessive processes? && freeSwapPercent < lowSwapThresholdPercent // Swap below threshold? Loading Loading @@ -3246,10 +3258,16 @@ public class OomAdjuster { mCachedAppOptimizer.onWakefulnessChanged(wakefulness); } @GuardedBy({"mService", "mProcLock"}) protected boolean applyOomAdjLSP(ProcessRecord app, boolean doingAll, long now, long nowElapsed, @OomAdjReason int oomAdjReason) { return applyOomAdjLSP(app, doingAll, now, nowElapsed, oomAdjReason, false); } /** Applies the computed oomadj, procstate and sched group values and freezes them in set* */ @GuardedBy({"mService", "mProcLock"}) protected boolean applyOomAdjLSP(ProcessRecord app, boolean doingAll, long now, long nowElapsed, @OomAdjReason int oomAdjReson) { long nowElapsed, @OomAdjReason int oomAdjReson, boolean isBatchingOomAdj) { boolean success = true; final ProcessStateRecord state = app.mState; final UidRecord uidRec = app.getUidRecord(); Loading @@ -3266,7 +3284,12 @@ public class OomAdjuster { final int oldOomAdj = state.getSetAdj(); if (state.getCurAdj() != state.getSetAdj()) { if (isBatchingOomAdj && mConstants.ENABLE_BATCHING_OOM_ADJ) { mProcsToOomAdj.add(app); } else { ProcessList.setOomAdj(app.getPid(), app.uid, state.getCurAdj()); } if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mService.mCurOomAdjUid == app.info.uid) { String msg = "Set " + app.getPid() + " " + app.processName + " adj " + state.getCurAdj() + ": " + state.getAdjType(); Loading
services/core/java/com/android/server/am/ProcessList.java +46 −0 Original line number Diff line number Diff line Loading @@ -354,6 +354,7 @@ public final class ProcessList { // LMK_KILL_OCCURRED // LMK_START_MONITORING // LMK_BOOT_COMPLETED // LMK_PROCS_PRIO static final byte LMK_TARGET = 0; static final byte LMK_PROCPRIO = 1; static final byte LMK_PROCREMOVE = 2; Loading @@ -365,6 +366,7 @@ public final class ProcessList { static final byte LMK_KILL_OCCURRED = 8; // Msg to subscribed clients on kill occurred event static final byte LMK_START_MONITORING = 9; // Start monitoring if delayed earlier static final byte LMK_BOOT_COMPLETED = 10; static final byte LMK_PROCS_PRIO = 11; // Batch option for LMK_PROCPRIO // Low Memory Killer Daemon command codes. // These must be kept in sync with async_event_type definitions in lmkd.h Loading Loading @@ -1561,6 +1563,50 @@ public final class ProcessList { } } // The max size for PROCS_PRIO cmd in LMKD private static final int MAX_PROCS_PRIO_PACKET_SIZE = 3; // (4 bytes per field * 4 fields * 3 processes per batch) + 4 bytes for the LMKD cmd private static final int MAX_OOM_ADJ_BATCH_LENGTH = ((4 * 4) * MAX_PROCS_PRIO_PACKET_SIZE) + 4; /** * Set the out-of-memory badness adjustment for a list of processes. * * @param apps App list to adjust their respective oom score. * * {@hide} */ public static void batchSetOomAdj(ArrayList<ProcessRecord> apps) { final int totalApps = apps.size(); if (totalApps == 0) { return; } ByteBuffer buf = ByteBuffer.allocate(MAX_OOM_ADJ_BATCH_LENGTH); int total_procs_in_buf = 0; buf.putInt(LMK_PROCS_PRIO); for (int i = 0; i < totalApps; i++) { final int pid = apps.get(i).getPid(); final int amt = apps.get(i).mState.getCurAdj(); final int uid = apps.get(i).uid; if (pid <= 0 || amt == UNKNOWN_ADJ) continue; if (total_procs_in_buf >= MAX_PROCS_PRIO_PACKET_SIZE) { writeLmkd(buf, null); buf.clear(); total_procs_in_buf = 0; buf.allocate(MAX_OOM_ADJ_BATCH_LENGTH); buf.putInt(LMK_PROCS_PRIO); } buf.putInt(pid); buf.putInt(uid); buf.putInt(amt); buf.putInt(0); // Default proc type to PROC_TYPE_APP total_procs_in_buf++; } writeLmkd(buf, null); } /* * {@hide} */ Loading
services/core/java/com/android/server/am/flags.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -134,3 +134,11 @@ flag { purpose: PURPOSE_BUGFIX } } flag { name: "batching_oom_adj" namespace: "backstage_power" description: "Batch OOM adjustment calls to LMKD" bug: "244232958" is_fixed_read_only: true }