From 3d961ed78da86efb193d3683531db1f1cce62274 Mon Sep 17 00:00:00 2001 From: Edgar Arriaga Date: Fri, 27 Jan 2023 00:36:35 +0000 Subject: Remove some no longer used compaction variables Test: am compact file Bug: 265473345 (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:7000b175d9f173d2296bf955f6031c673b5e38b5) Merged-In: Ifb4e69857b7a0a2ef0d9d40b05de377b5be2788b Change-Id: Ifb4e69857b7a0a2ef0d9d40b05de377b5be2788b --- .../com/android/server/am/CachedAppOptimizer.java | 60 ---------------- .../android/server/am/CachedAppOptimizerTest.java | 84 ---------------------- 2 files changed, 144 deletions(-) diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index f4685f0f6125..c0c235b2c1c4 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -66,8 +66,6 @@ public final class CachedAppOptimizer { // Flags stored in the DeviceConfig API. @VisibleForTesting static final String KEY_USE_COMPACTION = "use_compaction"; @VisibleForTesting static final String KEY_USE_FREEZER = "use_freezer"; - @VisibleForTesting static final String KEY_COMPACT_ACTION_1 = "compact_action_1"; - @VisibleForTesting static final String KEY_COMPACT_ACTION_2 = "compact_action_2"; @VisibleForTesting static final String KEY_COMPACT_THROTTLE_1 = "compact_throttle_1"; @VisibleForTesting static final String KEY_COMPACT_THROTTLE_2 = "compact_throttle_2"; @VisibleForTesting static final String KEY_COMPACT_THROTTLE_3 = "compact_throttle_3"; @@ -99,15 +97,6 @@ public final class CachedAppOptimizer { private static final int RSS_ANON_INDEX = 2; private static final int RSS_SWAP_INDEX = 3; - // Phenotype sends int configurations and we map them to the strings we'll use on device, - // preventing a weird string value entering the kernel. - private static final int COMPACT_ACTION_NONE = 0; - private static final int COMPACT_ACTION_FILE = 1; - private static final int COMPACT_ACTION_ANON = 2; - private static final int COMPACT_ACTION_ALL = 3; - - private static final String COMPACT_ACTION_STRING[] = {"", "file", "anon", "all"}; - // Keeps these flags in sync with services/core/jni/com_android_server_am_CachedAppOptimizer.cpp private static final int COMPACT_ACTION_FILE_FLAG = 1; private static final int COMPACT_ACTION_ANON_FLAG = 2; @@ -120,8 +109,6 @@ public final class CachedAppOptimizer { // Defaults for phenotype flags. @VisibleForTesting static final Boolean DEFAULT_USE_COMPACTION = true; @VisibleForTesting static final Boolean DEFAULT_USE_FREEZER = true; - @VisibleForTesting static final int DEFAULT_COMPACT_ACTION_2 = COMPACT_ACTION_ALL; - @VisibleForTesting static final int DEFAULT_COMPACT_ACTION_1 = COMPACT_ACTION_FILE; @VisibleForTesting static final long DEFAULT_COMPACT_THROTTLE_1 = 5_000; @VisibleForTesting static final long DEFAULT_COMPACT_THROTTLE_2 = 10_000; @VisibleForTesting static final long DEFAULT_COMPACT_THROTTLE_3 = 500; @@ -240,9 +227,6 @@ public final class CachedAppOptimizer { for (String name : properties.getKeyset()) { if (KEY_USE_COMPACTION.equals(name)) { updateUseCompaction(); - } else if (KEY_COMPACT_ACTION_1.equals(name) - || KEY_COMPACT_ACTION_2.equals(name)) { - updateCompactionActions(); } else if (KEY_COMPACT_THROTTLE_1.equals(name) || KEY_COMPACT_THROTTLE_2.equals(name) || KEY_COMPACT_THROTTLE_3.equals(name) @@ -314,12 +298,6 @@ public final class CachedAppOptimizer { // Configured by phenotype. Updates from the server take effect immediately. @GuardedBy("mPhenotypeFlagLock") - @VisibleForTesting - volatile CompactAction mCompactActionSome = compactActionIntToAction(DEFAULT_COMPACT_ACTION_1); - @GuardedBy("mPhenotypeFlagLock") - @VisibleForTesting - volatile CompactAction mCompactActionFull = compactActionIntToAction(DEFAULT_COMPACT_ACTION_2); - @GuardedBy("mPhenotypeFlagLock") @VisibleForTesting volatile long mCompactThrottleSomeSome = DEFAULT_COMPACT_THROTTLE_1; @GuardedBy("mPhenotypeFlagLock") @VisibleForTesting volatile long mCompactThrottleSomeFull = DEFAULT_COMPACT_THROTTLE_2; @@ -542,7 +520,6 @@ public final class CachedAppOptimizer { CACHED_APP_FREEZER_ENABLED_URI, false, mSettingsObserver); synchronized (mPhenotypeFlagLock) { updateUseCompaction(); - updateCompactionActions(); updateCompactionThrottles(); updateCompactStatsdSampleRate(); updateFreezerStatsdSampleRate(); @@ -587,8 +564,6 @@ public final class CachedAppOptimizer { pw.println("CachedAppOptimizer settings"); synchronized (mPhenotypeFlagLock) { pw.println(" " + KEY_USE_COMPACTION + "=" + mUseCompaction); - pw.println(" " + KEY_COMPACT_ACTION_1 + "=" + mCompactActionSome); - pw.println(" " + KEY_COMPACT_ACTION_2 + "=" + mCompactActionFull); pw.println(" " + KEY_COMPACT_THROTTLE_1 + "=" + mCompactThrottleSomeSome); pw.println(" " + KEY_COMPACT_THROTTLE_2 + "=" + mCompactThrottleSomeFull); pw.println(" " + KEY_COMPACT_THROTTLE_3 + "=" + mCompactThrottleFullSome); @@ -761,21 +736,6 @@ public final class CachedAppOptimizer { return false; } - private CompactAction resolveCompactActionForProfile(CompactProfile profile) { - CompactAction action; - switch (profile) { - case SOME: - action = CompactAction.FILE; - break; - case FULL: - action = CompactAction.ALL; - break; - default: - action = CompactAction.NONE; - } - return action; - } - private AggregatedProcessCompactionStats getPerProcessAggregatedCompactStat( String processName) { if (processName == null) { @@ -1050,18 +1010,6 @@ public final class CachedAppOptimizer { }); } - @GuardedBy("mPhenotypeFlagLock") - private void updateCompactionActions() { - int compactAction1 = DeviceConfig.getInt(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - KEY_COMPACT_ACTION_1, DEFAULT_COMPACT_ACTION_1); - - int compactAction2 = DeviceConfig.getInt(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - KEY_COMPACT_ACTION_2, DEFAULT_COMPACT_ACTION_2); - - mCompactActionSome = compactActionIntToAction(compactAction1); - mCompactActionFull = compactActionIntToAction(compactAction2); - } - @GuardedBy("mPhenotypeFlagLock") private void updateCompactionThrottles() { boolean useThrottleDefaults = false; @@ -1235,14 +1183,6 @@ public final class CachedAppOptimizer { return true; } - static CompactAction compactActionIntToAction(int action) { - if (action < 0 || action >= CompactAction.values().length) { - return CompactAction.NONE; - } - - return CompactAction.values()[action]; - } - // This will ensure app will be out of the freezer for at least mFreezerDebounceTimeout. @GuardedBy("mAm") void unfreezeTemporarily(ProcessRecord app, @OomAdjuster.OomAdjReason int reason) { diff --git a/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java b/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java index ec9e5b50579c..b38ca627be80 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java @@ -155,12 +155,6 @@ public final class CachedAppOptimizerTest { synchronized (mCachedAppOptimizerUnderTest.mPhenotypeFlagLock) { assertThat(mCachedAppOptimizerUnderTest.useCompaction()).isEqualTo( CachedAppOptimizer.DEFAULT_USE_COMPACTION); - assertThat(mCachedAppOptimizerUnderTest.mCompactActionSome) - .isEqualTo( - compactActionIntToAction(CachedAppOptimizer.DEFAULT_COMPACT_ACTION_1)); - assertThat(mCachedAppOptimizerUnderTest.mCompactActionFull) - .isEqualTo( - compactActionIntToAction(CachedAppOptimizer.DEFAULT_COMPACT_ACTION_2)); assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleSomeSome).isEqualTo( CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_1); assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleSomeFull).isEqualTo( @@ -209,12 +203,6 @@ public final class CachedAppOptimizerTest { assertThat(CachedAppOptimizer.DEFAULT_USE_COMPACTION).isTrue(); DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, CachedAppOptimizer.KEY_USE_COMPACTION, "true", false); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - CachedAppOptimizer.KEY_COMPACT_ACTION_1, - Integer.toString((CachedAppOptimizer.DEFAULT_COMPACT_ACTION_1 + 1 % 4) + 1), false); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - CachedAppOptimizer.KEY_COMPACT_ACTION_2, - Integer.toString((CachedAppOptimizer.DEFAULT_COMPACT_ACTION_2 + 1 % 4) + 1), false); DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, CachedAppOptimizer.KEY_COMPACT_THROTTLE_1, Long.toString(CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_1 + 1), false); @@ -266,12 +254,6 @@ public final class CachedAppOptimizerTest { assertThat(mCachedAppOptimizerUnderTest.useCompaction()).isTrue(); assertThat(mCachedAppOptimizerUnderTest.mCachedAppOptimizerThread.isAlive()).isTrue(); - assertThat(mCachedAppOptimizerUnderTest.mCompactActionSome) - .isEqualTo(compactActionIntToAction( - (CachedAppOptimizer.DEFAULT_COMPACT_ACTION_1 + 1 % 4) + 1)); - assertThat(mCachedAppOptimizerUnderTest.mCompactActionFull) - .isEqualTo(compactActionIntToAction( - (CachedAppOptimizer.DEFAULT_COMPACT_ACTION_2 + 1 % 4) + 1)); assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleSomeSome).isEqualTo( CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_1 + 1); assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleSomeFull).isEqualTo( @@ -403,72 +385,6 @@ public final class CachedAppOptimizerTest { assertThat(mCachedAppOptimizerUnderTest.useFreezer()).isFalse(); } - @Test - public void compactAction_listensToDeviceConfigChanges() throws InterruptedException { - mCachedAppOptimizerUnderTest.init(); - - // When we override new values for the compaction action with reasonable values... - - // There are four possible values for compactAction[Some|Full]. - for (int i = 1; i < 5; i++) { - mCountDown = new CountDownLatch(2); - int expectedSome = (CachedAppOptimizer.DEFAULT_COMPACT_ACTION_1 + i) % 4 + 1; - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - CachedAppOptimizer.KEY_COMPACT_ACTION_1, Integer.toString(expectedSome), false); - int expectedFull = (CachedAppOptimizer.DEFAULT_COMPACT_ACTION_2 + i) % 4 + 1; - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - CachedAppOptimizer.KEY_COMPACT_ACTION_2, Integer.toString(expectedFull), false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - - // Then the updates are reflected in the flags. - synchronized (mCachedAppOptimizerUnderTest.mPhenotypeFlagLock) { - assertThat(mCachedAppOptimizerUnderTest.mCompactActionSome) - .isEqualTo(compactActionIntToAction(expectedSome)); - assertThat(mCachedAppOptimizerUnderTest.mCompactActionFull) - .isEqualTo(compactActionIntToAction(expectedFull)); - } - } - } - - @Test - public void compactAction_listensToDeviceConfigChangesBadValues() throws InterruptedException { - mCachedAppOptimizerUnderTest.init(); - - // When we override new values for the compaction action with bad values ... - mCountDown = new CountDownLatch(2); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - CachedAppOptimizer.KEY_COMPACT_ACTION_1, "foo", false); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - CachedAppOptimizer.KEY_COMPACT_ACTION_2, "foo", false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - - synchronized (mCachedAppOptimizerUnderTest.mPhenotypeFlagLock) { - // Then the default values are reflected in the flag - assertThat(mCachedAppOptimizerUnderTest.mCompactActionSome) - .isEqualTo( - compactActionIntToAction(CachedAppOptimizer.DEFAULT_COMPACT_ACTION_1)); - assertThat(mCachedAppOptimizerUnderTest.mCompactActionFull) - .isEqualTo( - compactActionIntToAction(CachedAppOptimizer.DEFAULT_COMPACT_ACTION_2)); - } - - mCountDown = new CountDownLatch(2); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - CachedAppOptimizer.KEY_COMPACT_ACTION_1, "", false); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - CachedAppOptimizer.KEY_COMPACT_ACTION_2, "", false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - - synchronized (mCachedAppOptimizerUnderTest.mPhenotypeFlagLock) { - assertThat(mCachedAppOptimizerUnderTest.mCompactActionSome) - .isEqualTo( - compactActionIntToAction(CachedAppOptimizer.DEFAULT_COMPACT_ACTION_1)); - assertThat(mCachedAppOptimizerUnderTest.mCompactActionFull) - .isEqualTo( - compactActionIntToAction(CachedAppOptimizer.DEFAULT_COMPACT_ACTION_2)); - } - } - @Test public void compactThrottle_listensToDeviceConfigChanges() throws InterruptedException { mCachedAppOptimizerUnderTest.init(); -- cgit v1.2.3-59-g8ed1b From 29a79cf724e6d3fd27dd092bc02952537e56757b Mon Sep 17 00:00:00 2001 From: Edgar Arriaga Date: Fri, 13 Jan 2023 22:24:33 +0000 Subject: Disable file compaction by default At present time kernel does not support shared pages to be swapped using file compaction which uses MADV_COLD and most of the file pages in a process are actually shared mappings causing us to waste a lot of cycles scanning through a lot of unreclaimable pages, this patch disables file compaction which will be reenabled until a solution is implemented on upstream kernel that allows reclaiming shared pages, thus making it worth to scan all of those pages again. Test: am compact file Bug: 265473345 (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:30b069612a9d35b02cc6c2656c18326e8cffeec6) Merged-In: I4c819058da229c00d1eafea636f89784718adc5f Change-Id: I4c819058da229c00d1eafea636f89784718adc5f --- .../com/android/server/am/CachedAppOptimizer.java | 75 +++++++++++++--------- .../android/server/am/CachedAppOptimizerTest.java | 22 ++++--- 2 files changed, 58 insertions(+), 39 deletions(-) diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index c0c235b2c1c4..28b1fc0610d4 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -106,6 +106,8 @@ public final class CachedAppOptimizer { private static final int FREEZE_BINDER_TIMEOUT_MS = 100; + @VisibleForTesting static final boolean ENABLE_FILE_COMPACT = false; + // Defaults for phenotype flags. @VisibleForTesting static final Boolean DEFAULT_USE_COMPACTION = true; @VisibleForTesting static final Boolean DEFAULT_USE_FREEZER = true; @@ -143,24 +145,17 @@ public final class CachedAppOptimizer { @VisibleForTesting interface ProcessDependencies { long[] getRss(int pid); - void performCompaction(CompactAction action, int pid) throws IOException; + void performCompaction(CompactProfile action, int pid) throws IOException; } // This indicates the compaction we want to perform public enum CompactProfile { + NONE, // No compaction SOME, // File compaction + ANON, // Anon compaction FULL // File+anon compaction } - // Low level actions that can be performed for compaction - // currently determined by the compaction profile - public enum CompactAction { - NONE, // No compaction - FILE, // File+anon compaction - ANON, - ALL - } - // This indicates the process OOM memory state that initiated the compaction request public enum CompactSource { APP, PERSISTENT, BFGS } @@ -1415,8 +1410,10 @@ public final class CachedAppOptimizer { if (oldAdj <= ProcessList.PERCEPTIBLE_APP_ADJ && (newAdj == ProcessList.PREVIOUS_APP_ADJ || newAdj == ProcessList.HOME_APP_ADJ)) { - // Perform a minor compaction when a perceptible app becomes the prev/home app - compactApp(app, CompactProfile.SOME, CompactSource.APP, false); + if (ENABLE_FILE_COMPACT) { + // Perform a minor compaction when a perceptible app becomes the prev/home app + compactApp(app, CompactProfile.SOME, CompactSource.APP, false); + } } else if (oldAdj < ProcessList.CACHED_APP_MIN_ADJ && newAdj >= ProcessList.CACHED_APP_MIN_ADJ && newAdj <= ProcessList.CACHED_APP_MAX_ADJ) { @@ -1426,23 +1423,37 @@ public final class CachedAppOptimizer { } /** - * Applies a compaction downgrade when swap is low. + * Computes the final compaction profile to be used which depends on compaction + * features enabled and swap usage. */ - CompactProfile downgradeCompactionIfRequired(CompactProfile profile) { - // Downgrade compaction under swap memory pressure + CompactProfile resolveCompactionProfile(CompactProfile profile) { if (profile == CompactProfile.FULL) { double swapFreePercent = getFreeSwapPercent(); + // Downgrade compaction under swap memory pressure if (swapFreePercent < COMPACT_DOWNGRADE_FREE_SWAP_THRESHOLD) { profile = CompactProfile.SOME; + ++mTotalCompactionDowngrades; if (DEBUG_COMPACTION) { Slog.d(TAG_AM, - "Downgraded compaction to file only due to low swap." + "Downgraded compaction to "+ profile +" due to low swap." + " Swap Free% " + swapFreePercent); } } } + if (!ENABLE_FILE_COMPACT) { + if (profile == CompactProfile.SOME) { + profile = CompactProfile.NONE; + } else if (profile == CompactProfile.FULL) { + profile = CompactProfile.ANON; + } + if (DEBUG_COMPACTION) { + Slog.d(TAG_AM, + "Final compaction profile "+ profile +" due to file compact disabled"); + } + } + return profile; } @@ -1673,7 +1684,6 @@ public final class CachedAppOptimizer { ProcessRecord proc; final ProcessCachedOptimizerRecord opt; int pid; - CompactAction resolvedAction; final String name; CompactProfile lastCompactProfile; long lastCompactTime; @@ -1751,17 +1761,24 @@ public final class CachedAppOptimizer { } CompactProfile resolvedProfile = - downgradeCompactionIfRequired(requestedProfile); - resolvedAction = resolveCompactActionForProfile(resolvedProfile); + resolveCompactionProfile(requestedProfile); + if (resolvedProfile == CompactProfile.NONE) { + // No point on issuing compaction call as we don't want to compact. + if (DEBUG_COMPACTION) { + Slog.d(TAG_AM, "Resolved no compaction for "+ name + + " requested profile="+requestedProfile); + } + return; + } try { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, - "Compact " + resolvedAction.name() + ": " + name + "Compact " + resolvedProfile.name() + ": " + name + " lastOomAdjReason: " + oomAdjReason + " source: " + compactSource.name()); long zramUsedKbBefore = getUsedZramMemory(); long startCpuTime = threadCpuTimeNs(); - mProcessDependencies.performCompaction(resolvedAction, pid); + mProcessDependencies.performCompaction(resolvedProfile, pid); long endCpuTime = threadCpuTimeNs(); long[] rssAfter = mProcessDependencies.getRss(pid); long end = SystemClock.uptimeMillis(); @@ -1817,7 +1834,7 @@ public final class CachedAppOptimizer { return; } EventLog.writeEvent(EventLogTags.AM_COMPACT, pid, name, - resolvedAction.name(), rssBefore[RSS_TOTAL_INDEX], + resolvedProfile.name(), rssBefore[RSS_TOTAL_INDEX], rssBefore[RSS_FILE_INDEX], rssBefore[RSS_ANON_INDEX], rssBefore[RSS_SWAP_INDEX], deltaTotalRss, deltaFileRss, deltaAnonRss, deltaSwapRss, time, lastCompactProfile.name(), @@ -2110,14 +2127,14 @@ public final class CachedAppOptimizer { // Compact process. @Override - public void performCompaction(CompactAction action, int pid) throws IOException { + public void performCompaction(CompactProfile profile, int pid) throws IOException { mPidCompacting = pid; - if (action == CompactAction.ALL) { - compactProcess(pid, COMPACT_ACTION_FILE_FLAG | COMPACT_ACTION_ANON_FLAG); - } else if (action == CompactAction.FILE) { - compactProcess(pid, COMPACT_ACTION_FILE_FLAG); - } else if (action == CompactAction.ANON) { - compactProcess(pid, COMPACT_ACTION_ANON_FLAG); + if (profile == CompactProfile.FULL) { + compactProcess(pid, COMPACT_ACTION_FILE_FLAG | COMPACT_ACTION_ANON_FLAG); + } else if (profile == CompactProfile.SOME) { + compactProcess(pid, COMPACT_ACTION_FILE_FLAG); + } else if (profile == CompactProfile.ANON) { + compactProcess(pid, COMPACT_ACTION_ANON_FLAG); } mPidCompacting = -1; } diff --git a/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java b/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java index b38ca627be80..1fbb8dd5ac9d 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java @@ -19,7 +19,6 @@ package com.android.server.am; import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; import static com.android.server.am.ActivityManagerService.Injector; -import static com.android.server.am.CachedAppOptimizer.compactActionIntToAction; import static com.google.common.truth.Truth.assertThat; @@ -1024,14 +1023,17 @@ public final class CachedAppOptimizerTest { mCachedAppOptimizerUnderTest.mLastCompactionStats.clear(); - // We force a some compaction - mCachedAppOptimizerUnderTest.compactApp(processRecord, - CachedAppOptimizer.CompactProfile.SOME, CachedAppOptimizer.CompactSource.APP, true); - waitForHandler(); - // then process is compacted. - CachedAppOptimizer.CompactProfile executedCompactProfile = - processRecord.mOptRecord.getLastCompactProfile(); - assertThat(executedCompactProfile).isEqualTo(CachedAppOptimizer.CompactProfile.SOME); + if (CachedAppOptimizer.ENABLE_FILE_COMPACT) { + // We force a some compaction + mCachedAppOptimizerUnderTest.compactApp(processRecord, + CachedAppOptimizer.CompactProfile.SOME, CachedAppOptimizer.CompactSource.APP, + true); + waitForHandler(); + // then process is compacted. + CachedAppOptimizer.CompactProfile executedCompactProfile = + processRecord.mOptRecord.getLastCompactProfile(); + assertThat(executedCompactProfile).isEqualTo(CachedAppOptimizer.CompactProfile.SOME); + } } private void setFlag(String key, String value, boolean defaultValue) throws Exception { @@ -1108,7 +1110,7 @@ public final class CachedAppOptimizerTest { } @Override - public void performCompaction(CachedAppOptimizer.CompactAction action, int pid) + public void performCompaction(CachedAppOptimizer.CompactProfile profile, int pid) throws IOException { mRss = mRssAfterCompaction; } -- cgit v1.2.3-59-g8ed1b From 6cc5e383940da055003ea8256fc1afc1126b1c6c Mon Sep 17 00:00:00 2001 From: Edgar Arriaga Date: Tue, 13 Dec 2022 23:00:29 +0000 Subject: Simplify debug command to force compactions This removes the need to specify the UID as part of the command Bug: 262442634 Test: am compact full (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:94ea572a57d4d5328d2e4b53582a7ea692a39a79) Merged-In: I3fa2d9bcc14e4ce31e8825d5a029f5768553f4fc Change-Id: I3fa2d9bcc14e4ce31e8825d5a029f5768553f4fc --- .../android/server/am/ActivityManagerShellCommand.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index 94d08bf7b59d..86f709b804fa 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -1066,16 +1066,26 @@ final class ActivityManagerShellCommand extends ShellCommand { } @NeverCompile - int runCompact(PrintWriter pw) { + int runCompact(PrintWriter pw) throws RemoteException { ProcessRecord app; String op = getNextArgRequired(); boolean isFullCompact = op.equals("full"); boolean isSomeCompact = op.equals("some"); if (isFullCompact || isSomeCompact) { String processName = getNextArgRequired(); - String uid = getNextArgRequired(); synchronized (mInternal.mProcLock) { - app = mInternal.getProcessRecordLocked(processName, Integer.parseInt(uid)); + // Default to current user + int userId = mInterface.getCurrentUserId(); + String userOpt = getNextOption(); + if (userOpt != null && "--user".equals(userOpt)) { + int inputUserId = UserHandle.parseUserArg(getNextArgRequired()); + if (inputUserId != UserHandle.USER_CURRENT) { + userId = inputUserId; + } + } + final int uid = + mInternal.getPackageManagerInternal().getPackageUid(processName, 0, userId); + app = mInternal.getProcessRecordLocked(processName, uid); } pw.println("Process record found pid: " + app.mPid); if (isFullCompact) { @@ -4018,7 +4028,7 @@ final class ActivityManagerShellCommand extends ShellCommand { pw.println(" --allow-background-activity-starts: The receiver may start activities"); pw.println(" even if in the background."); pw.println(" --async: Send without waiting for the completion of the receiver."); - pw.println(" compact [some|full|system] "); + pw.println(" compact [some|full|system] [--user ]"); pw.println(" Force process compaction."); pw.println(" some: execute file compaction."); pw.println(" full: execute anon + file compaction."); -- cgit v1.2.3-59-g8ed1b From de9b3c9a4fa26b11aaf9cb1ec1ddb044a2f5dab6 Mon Sep 17 00:00:00 2001 From: Edgar Arriaga Date: Thu, 26 Jan 2023 00:32:30 +0000 Subject: Add debug support for native compactions This allows for performing compactions using shell command which is useful for testing and debugging compaction locally automated tests to allow compacting applications not managed by ActivityManager such as purely native binaries. Test: am compact native full Bug: 267188919 (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:5fa297d3c198ed2e93c788b332c3a79ff8efb8d3) Merged-In: I355bd4c55c96ada392d81cf89381870b9dc79c17 Change-Id: I355bd4c55c96ada392d81cf89381870b9dc79c17 --- .../server/am/ActivityManagerShellCommand.java | 32 ++++++++++++++++++++-- .../com/android/server/am/CachedAppOptimizer.java | 21 ++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index 86f709b804fa..72e17d8764aa 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -1111,6 +1111,28 @@ final class ActivityManagerShellCommand extends ShellCommand { mInternal.mOomAdjuster.mCachedAppOptimizer.compactAllSystem(); } pw.println("Finished system compaction"); + } else if (op.equals("native")) { + op = getNextArgRequired(); + isFullCompact = op.equals("full"); + isSomeCompact = op.equals("some"); + int pid; + String pidStr = getNextArgRequired(); + try { + pid = Integer.parseInt(pidStr); + } catch (Exception e) { + getErrPrintWriter().println("Error: failed to parse '" + pidStr + "' as a PID"); + return -1; + } + if (isFullCompact) { + mInternal.mOomAdjuster.mCachedAppOptimizer.compactNative( + CachedAppOptimizer.CompactProfile.FULL, pid); + } else if (isSomeCompact) { + mInternal.mOomAdjuster.mCachedAppOptimizer.compactNative( + CachedAppOptimizer.CompactProfile.SOME, pid); + } else { + getErrPrintWriter().println("Error: unknown compaction type '" + op + "'"); + return -1; + } } else { getErrPrintWriter().println("Error: unknown compact command '" + op + "'"); return -1; @@ -4028,11 +4050,17 @@ final class ActivityManagerShellCommand extends ShellCommand { pw.println(" --allow-background-activity-starts: The receiver may start activities"); pw.println(" even if in the background."); pw.println(" --async: Send without waiting for the completion of the receiver."); - pw.println(" compact [some|full|system] [--user ]"); - pw.println(" Force process compaction."); + pw.println(" compact [some|full] [--user ]"); + pw.println(" Perform a single process compaction."); pw.println(" some: execute file compaction."); pw.println(" full: execute anon + file compaction."); pw.println(" system: system compaction."); + pw.println(" compact system"); + pw.println(" Perform a full system compaction."); + pw.println(" compact native [some|full] "); + pw.println(" Perform a native compaction for process with ."); + pw.println(" some: execute file compaction."); + pw.println(" full: execute anon + file compaction."); pw.println(" instrument [-r] [-e ] [-p ] [-w]"); pw.println(" [--user | current]"); pw.println(" [--no-hidden-api-checks [--no-test-api-access]]"); diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index 28b1fc0610d4..8675bfd9b2cc 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -169,6 +169,7 @@ public final class CachedAppOptimizer { static final int COMPACT_SYSTEM_MSG = 2; static final int SET_FROZEN_PROCESS_MSG = 3; static final int REPORT_UNFREEZE_MSG = 4; + static final int COMPACT_NATIVE_MSG = 5; // When free swap falls below this percentage threshold any full (file + anon) // compactions will be downgraded to file only compactions to reduce pressure @@ -731,6 +732,11 @@ public final class CachedAppOptimizer { return false; } + void compactNative(CompactProfile compactProfile, int pid) { + mCompactionHandler.sendMessage(mCompactionHandler.obtainMessage( + COMPACT_NATIVE_MSG, pid, compactProfile.ordinal())); + } + private AggregatedProcessCompactionStats getPerProcessAggregatedCompactStat( String processName) { if (processName == null) { @@ -1864,6 +1870,21 @@ public final class CachedAppOptimizer { Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; } + case COMPACT_NATIVE_MSG: { + int pid = msg.arg1; + CompactProfile compactProfile = CompactProfile.values()[msg.arg2]; + Slog.d(TAG_AM, + "Performing native compaction for pid=" + pid + + " type=" + compactProfile.name()); + Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "compactSystem"); + try { + mProcessDependencies.performCompaction(compactProfile, pid); + } catch (Exception e) { + Slog.d(TAG_AM, "Failed compacting native pid= " + pid); + } + Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); + break; + } } } } -- cgit v1.2.3-59-g8ed1b