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

Commit 00e1ddb3 authored by Shadman Shadid's avatar Shadman Shadid Committed by Android (Google) Code Review
Browse files

Merge "CachedAppOptimizer: Use memcg reclaim for compaction" into main

parents b3477a65 f587cb2c
Loading
Loading
Loading
Loading
+60 −5
Original line number Diff line number Diff line
@@ -317,7 +317,9 @@ public class CachedAppOptimizer {
    @VisibleForTesting
    interface ProcessDependencies {
        long[] getRss(int pid);
        void performCompaction(CompactProfile action, int pid) throws IOException;
        void performCompaction(CompactProfile action, int pid) throws IOException; // deprecated
        void performMemcgCompaction(CompactProfile action, int uid, int pid) throws IOException;
        void performNativeCompaction(CompactProfile action, int pid) throws IOException;
    }

    // This indicates the compaction we want to perform
@@ -750,7 +752,9 @@ public class CachedAppOptimizer {
     * @param compactionFlags selects the compaction type as defined by COMPACT_ACTION_{TYPE}_FLAG
     *         constants
     */
    static private native void compactProcess(int pid, int compactionFlags);
    private static native void compactProcess(int pid, int compactionFlags);
    private static native void performNativeMemcgCompaction(int uid, int pid, int compactionFlags);
    private static native void compactNativeProcess(int pid, int compactionFlags);

    static private native void cancelCompaction();

@@ -1674,6 +1678,7 @@ public class CachedAppOptimizer {
                    long start = SystemClock.uptimeMillis();
                    ProcessRecord proc;
                    final ProcessCachedOptimizerRecord opt;
                    int uid;
                    int pid;
                    final String name;
                    CompactProfile lastCompactProfile;
@@ -1695,6 +1700,7 @@ public class CachedAppOptimizer {
                        opt = proc.mOptRecord;
                        forceCompaction = opt.isForceCompact();
                        opt.setForceCompact(false); // since this is a one-shot operation
                        uid = proc.uid;
                        pid = proc.getPid();
                        name = proc.processName;
                        opt.setHasPendingCompact(false);
@@ -1769,7 +1775,13 @@ public class CachedAppOptimizer {
                                        + " source: " + compactSource.name());
                        long zramUsedKbBefore = getUsedZramMemory();
                        long startCpuTime = threadCpuTimeNs();

                        if (Flags.useMemcgForCompaction()) {
                            mProcessDependencies.performMemcgCompaction(resolvedProfile, uid, pid);
                        } else {
                            mProcessDependencies.performCompaction(resolvedProfile, pid);
                        }

                        long endCpuTime = threadCpuTimeNs();
                        long[] rssAfter = mProcessDependencies.getRss(pid);
                        long end = SystemClock.uptimeMillis();
@@ -1842,7 +1854,11 @@ public class CachedAppOptimizer {
                                    + " type=" + compactProfile.name());
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "compactNative");
                    try {
                        if (Flags.useMemcgForCompaction()) {
                            mProcessDependencies.performNativeCompaction(compactProfile, pid);
                        } else {
                            mProcessDependencies.performCompaction(compactProfile, pid);
                        }
                    } catch (Exception e) {
                        Slog.d(TAG_AM, "Failed compacting native pid= " + pid);
                    }
@@ -2184,7 +2200,7 @@ public class CachedAppOptimizer {
    }

    /**
     * Default implementation for ProcessDependencies, public vor visibility to OomAdjuster class.
     * Default implementation for ProcessDependencies, public for visibility to OomAdjuster class.
     */
    private static final class DefaultProcessDependencies implements ProcessDependencies {
        public static volatile int mPidCompacting = -1;
@@ -2208,6 +2224,45 @@ public class CachedAppOptimizer {
            }
            mPidCompacting = -1;
        }

        @Override
        public void performMemcgCompaction(CompactProfile profile, int uid, int pid)
                throws IOException {
            int compactionFlags = getCompactionFlags(profile);
            mPidCompacting = pid;
            performNativeMemcgCompaction(uid, pid, compactionFlags);
            mPidCompacting = -1;
        }

        // Compaction normally requires the UID to identify the correct cgroup path for the process
        // so that we can use memory cgroup reclaim without looking up its cgroup placement. Most
        // of the time the (real/effective/saved) UID of the process matches its UID cgroup
        // placement, but that is not true for native processes launched under adb shells which have
        // UIDs of 2000 but live under the adbd cgroup in uid_0 as a child or grandchild of adbd.
        // Both the UID and the PID would cause the generated cgroup path to be incorrect for shell
        // processes in this case. So here we do not attempt to use cgroup reclaim, and always scan
        // all VMAs and madvise the individual process.
        // An alternative would be to reclaim the adbd cgroup, but this would compact *all* shells
        // (and any running commands under them) which could be more than just the specified pid.
        @Override
        public void performNativeCompaction(CompactProfile profile, int pid)
                throws IOException {
            int compactionFlags = getCompactionFlags(profile);
            mPidCompacting = pid;
            compactNativeProcess(pid, compactionFlags);
            mPidCompacting = -1;
        }

        private static int getCompactionFlags(CompactProfile profile) {
            if (profile == CompactProfile.FULL) {
                return COMPACT_ACTION_FILE_FLAG | COMPACT_ACTION_ANON_FLAG;
            } else if (profile == CompactProfile.SOME) {
                return COMPACT_ACTION_FILE_FLAG;
            } else if (profile == CompactProfile.ANON) {
                return COMPACT_ACTION_ANON_FLAG;
            }
            return 0;
        }
    }

    static int getUnfreezeReasonCodeFromOomAdjReason(@OomAdjReason int oomAdjReason) {
+7 −0
Original line number Diff line number Diff line
@@ -251,3 +251,10 @@ flag {
    description: "If a connection has flag BIND_SCHEDULE_LIKE_TOP_APP but the host process has not set the corresponding flag, do not skip the connection recompute."
    bug: "417720000"
}

flag {
    name: "use_memcg_for_compaction"
    namespace: "system_performance"
    description: "Update CachedAppOptimizer to use memcg reclaim for compaction"
    bug: "377479218"
}
+35 −4
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
#include <meminfo/procmeminfo.h>
#include <meminfo/sysmeminfo.h>
#include <nativehelper/JNIHelp.h>
#include <processgroup/processgroup.h>
#include <stddef.h>
#include <stdio.h>
#include <sys/mman.h>
@@ -428,6 +429,24 @@ static void compactProcess(int pid, int compactionFlags) {
    compactProcess(pid, vmaToAdviseFunc);
}

static void compactMemcg(int uid, int pid, int compactionFlags) {
    const bool compactAnon = compactionFlags & COMPACT_ACTION_ANON_FLAG;
    const bool compactFile = compactionFlags & COMPACT_ACTION_FILE_FLAG;

    if (!compactAnon && !compactFile) return;
    std::string profile;
    if (compactAnon && compactFile)
        profile = "CompactFull";
    else if (compactAnon)
        profile = "CompactAnon";
    else if (compactFile)
        profile = "CompactFile";

    if (isProfileValidForProcess(profile, uid, pid)) {
        SetProcessProfiles(uid, pid, {profile});
    }
}

// This performs per-process reclaim on all processes belonging to non-app UIDs.
// For the most part, these are non-zygote processes like Treble HALs, but it
// also includes zygote-derived processes that run in system UIDs, like bluetooth
@@ -463,7 +482,7 @@ static void com_android_server_am_CachedAppOptimizer_compactSystem(JNIEnv *, job

        int pid = atoi(current->d_name);

        compactProcess(pid, COMPACT_ACTION_ANON_FLAG | COMPACT_ACTION_FILE_FLAG);
        compactMemcg(status_info.st_uid, pid, COMPACT_ACTION_ANON_FLAG | COMPACT_ACTION_FILE_FLAG);
    }
}

@@ -498,7 +517,14 @@ static jlong com_android_server_am_CachedAppOptimizer_getMemoryFreedCompaction()
    return sysmeminfo.mem_compacted_kb("/sys/block/zram0/");
}

static void com_android_server_am_CachedAppOptimizer_compactProcess(JNIEnv*, jobject, jint pid,
static void com_android_server_am_CachedAppOptimizer_compactProcessWithMemcg(JNIEnv*, jobject,
                                                                             jint uid, jint pid,
                                                                             jint compactionFlags) {
    compactMemcg(uid, pid, compactionFlags);
}

static void com_android_server_am_CachedAppOptimizer_compactNativeProcess(JNIEnv*, jobject,
                                                                          jint pid,
                                                                          jint compactionFlags) {
    compactProcess(pid, compactionFlags);
}
@@ -515,7 +541,12 @@ static const JNINativeMethod sMethods[] = {
        {"getMemoryFreedCompaction", "()J",
         (void*)com_android_server_am_CachedAppOptimizer_getMemoryFreedCompaction},
        {"compactSystem", "()V", (void*)com_android_server_am_CachedAppOptimizer_compactSystem},
        {"compactProcess", "(II)V", (void*)com_android_server_am_CachedAppOptimizer_compactProcess},
        {"compactProcess", "(II)V",
         (void*)com_android_server_am_CachedAppOptimizer_compactNativeProcess},
        {"performNativeMemcgCompaction", "(III)V",
         (void*)com_android_server_am_CachedAppOptimizer_compactProcessWithMemcg},
        {"compactNativeProcess", "(II)V",
         (void*)com_android_server_am_CachedAppOptimizer_compactNativeProcess},
};

int register_android_server_am_CachedAppOptimizer(JNIEnv* env)
+13 −0
Original line number Diff line number Diff line
@@ -1145,6 +1145,19 @@ public final class CachedAppOptimizerTest {
            mRss = mRssAfterCompaction;
        }

        @Override
        public void performMemcgCompaction(
                CachedAppOptimizer.CompactProfile profile, int uid, int pid
        ) throws IOException {
            mRss = mRssAfterCompaction;
        }

        @Override
        public void performNativeCompaction(CachedAppOptimizer.CompactProfile profile, int pid)
                throws IOException {
            mRss = mRssAfterCompaction;
        }

        public void setRss(long[] newValues) {
            mRss = newValues;
        }
+13 −2
Original line number Diff line number Diff line
@@ -137,6 +137,7 @@ import org.junit.Test;
import org.mockito.ArgumentCaptor;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
@@ -4307,8 +4308,18 @@ public class MockingOomAdjusterTests {
        }

        @Override
        public void performCompaction(CachedAppOptimizer.CompactProfile action, int pid) {
        }
        public void performCompaction(CachedAppOptimizer.CompactProfile action, int pid)
                throws IOException {}

        @Override
        public void performMemcgCompaction(
                CachedAppOptimizer.CompactProfile action, int uid, int pid
        )
                throws IOException {}

        @Override
        public void performNativeCompaction(CachedAppOptimizer.CompactProfile action, int pid)
                throws IOException {}
    }

    private static class TestCachedAppOptimizer extends CachedAppOptimizer {