Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 29a79cf7 authored by Edgar Arriaga's avatar Edgar Arriaga Committed by Cherrypicker Worker
Browse files

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 <processname> <uid>
Bug: 265473345
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:30b069612a9d35b02cc6c2656c18326e8cffeec6)
Merged-In: I4c819058da229c00d1eafea636f89784718adc5f
Change-Id: I4c819058da229c00d1eafea636f89784718adc5f
parent 3d961ed7
Loading
Loading
Loading
Loading
+46 −29
Original line number Diff line number Diff line
@@ -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)) {
            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,13 +2127,13 @@ 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) {
            if (profile == CompactProfile.FULL) {
                compactProcess(pid, COMPACT_ACTION_FILE_FLAG | COMPACT_ACTION_ANON_FLAG);
            } else if (action == CompactAction.FILE) {
            } else if (profile == CompactProfile.SOME) {
                compactProcess(pid, COMPACT_ACTION_FILE_FLAG);
            } else if (action == CompactAction.ANON) {
            } else if (profile == CompactProfile.ANON) {
                compactProcess(pid, COMPACT_ACTION_ANON_FLAG);
            }
            mPidCompacting = -1;
+12 −10
Original line number Diff line number Diff line
@@ -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,15 +1023,18 @@ public final class CachedAppOptimizerTest {

        mCachedAppOptimizerUnderTest.mLastCompactionStats.clear();

        if (CachedAppOptimizer.ENABLE_FILE_COMPACT) {
            // We force a some compaction
            mCachedAppOptimizerUnderTest.compactApp(processRecord,
                CachedAppOptimizer.CompactProfile.SOME, CachedAppOptimizer.CompactSource.APP, true);
                    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 {
        mCountDown = new CountDownLatch(1);
@@ -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;
        }