Merge "Cancel compaction if the process improves its OOM ranking while compaction is running"

This commit is contained in:
Edgar Arriaga García
2022-01-11 23:10:20 +00:00
committed by Android (Google) Code Review
3 changed files with 57 additions and 11 deletions

View File

@@ -539,6 +539,8 @@ public final class CachedAppOptimizer {
*/
static private native void compactProcess(int pid, int compactionFlags);
static private native void cancelCompaction();
/**
* Reads the flag value from DeviceConfig to determine whether app compaction
* should be enabled, and starts the freeze/compaction thread if needed.
@@ -1049,6 +1051,26 @@ public final class CachedAppOptimizer {
}
}
@GuardedBy({"mService", "mProcLock"})
void onOomAdjustChanged(int oldAdj, int newAdj, ProcessRecord app) {
// Cancel any currently executing compactions
// if the process moved out of cached state
if (DefaultProcessDependencies.mPidCompacting == app.mPid && newAdj < oldAdj
&& newAdj < ProcessList.CACHED_APP_MIN_ADJ) {
cancelCompaction();
}
// Perform a minor compaction when a perceptible app becomes the prev/home app
// Perform a major compaction when any app enters cached
if (oldAdj <= ProcessList.PERCEPTIBLE_APP_ADJ
&& (newAdj == ProcessList.PREVIOUS_APP_ADJ || newAdj == ProcessList.HOME_APP_ADJ)) {
compactAppSome(app);
} else if (newAdj >= ProcessList.CACHED_APP_MIN_ADJ
&& newAdj <= ProcessList.CACHED_APP_MAX_ADJ) {
compactAppFull(app);
}
}
@VisibleForTesting
static final class LastCompactionStats {
private final long[] mRssAfterCompaction;
@@ -1091,6 +1113,13 @@ public final class CachedAppOptimizer {
name = proc.processName;
opt.setHasPendingCompact(false);
if (mAm.mInternal.isPendingTopUid(proc.uid)) {
// In case the OOM Adjust has not yet been propagated we see if this is
// pending on becoming top app in which case we should not compact.
Slog.e(TAG_AM, "Skip compaction since UID is active for " + name);
return;
}
// don't compact if the process has returned to perceptible
// and this is only a cached/home/prev compaction
if ((pendingAction == COMPACT_PROCESS_SOME
@@ -1500,6 +1529,8 @@ public final class CachedAppOptimizer {
* Default implementation for ProcessDependencies, public vor visibility to OomAdjuster class.
*/
private static final class DefaultProcessDependencies implements ProcessDependencies {
public static int mPidCompacting = -1;
// Get memory RSS from process.
@Override
public long[] getRss(int pid) {
@@ -1509,6 +1540,7 @@ public final class CachedAppOptimizer {
// Compact process.
@Override
public void performCompaction(String action, int pid) throws IOException {
mPidCompacting = pid;
if (action.equals(COMPACT_ACTION_STRING[COMPACT_ACTION_FULL])) {
compactProcess(pid, COMPACT_ACTION_FILE_FLAG | COMPACT_ACTION_ANON_FLAG);
} else if (action.equals(COMPACT_ACTION_STRING[COMPACT_ACTION_FILE])) {
@@ -1516,6 +1548,7 @@ public final class CachedAppOptimizer {
} else if (action.equals(COMPACT_ACTION_STRING[COMPACT_ACTION_ANON])) {
compactProcess(pid, COMPACT_ACTION_ANON_FLAG);
}
mPidCompacting = -1;
}
}
}

View File

@@ -2486,18 +2486,9 @@ public class OomAdjuster {
// don't compact during bootup
if (mCachedAppOptimizer.useCompaction() && mService.mBooted) {
// Cached and prev/home compaction
// reminder: here, setAdj is previous state, curAdj is upcoming state
if (state.getCurAdj() != state.getSetAdj()) {
// Perform a minor compaction when a perceptible app becomes the prev/home app
// Perform a major compaction when any app enters cached
// reminder: here, setAdj is previous state, curAdj is upcoming state
if (state.getSetAdj() <= ProcessList.PERCEPTIBLE_APP_ADJ
&& (state.getCurAdj() == ProcessList.PREVIOUS_APP_ADJ
|| state.getCurAdj() == ProcessList.HOME_APP_ADJ)) {
mCachedAppOptimizer.compactAppSome(app);
} else if (state.getCurAdj() >= ProcessList.CACHED_APP_MIN_ADJ
&& state.getCurAdj() <= ProcessList.CACHED_APP_MAX_ADJ) {
mCachedAppOptimizer.compactAppFull(app);
}
mCachedAppOptimizer.onOomAdjustChanged(state.getSetAdj(), state.getCurAdj(), app);
} else if (mService.mWakefulness.get() != PowerManagerInternal.WAKEFULNESS_AWAKE
&& state.getSetAdj() < ProcessList.FOREGROUND_APP_ADJ
// Because these can fire independent of oom_adj/procstate changes, we need

View File

@@ -59,6 +59,9 @@ using android::base::unique_fd;
namespace android {
static bool cancelRunningCompaction;
static bool compactionInProgress;
// Legacy method for compacting processes, any new code should
// use compactProcess instead.
static inline void compactProcessProcfs(int pid, const std::string& compactionType) {
@@ -83,9 +86,18 @@ static int64_t compactMemory(const std::vector<Vma>& vmas, int pid, int madviseT
// Skip compaction if failed to open pidfd with any error
return -errno;
}
compactionInProgress = true;
cancelRunningCompaction = false;
int64_t totalBytesCompacted = 0;
for (int iBase = 0; iBase < vmas.size(); iBase += UIO_MAXIOV) {
if (CC_UNLIKELY(cancelRunningCompaction)) {
// There could be a significant delay betweenwhen a compaction
// is requested and when it is handled during this time
// our OOM adjust could have improved.
cancelRunningCompaction = false;
break;
}
int totalVmasToKernel = std::min(UIO_MAXIOV, (int)(vmas.size() - iBase));
for (int iVec = 0, iVma = iBase; iVec < totalVmasToKernel; ++iVec, ++iVma) {
vmasToKernel[iVec].iov_base = (void*)vmas[iVma].start;
@@ -95,11 +107,13 @@ static int64_t compactMemory(const std::vector<Vma>& vmas, int pid, int madviseT
auto bytesCompacted =
process_madvise(pidfd, vmasToKernel, totalVmasToKernel, madviseType, 0);
if (CC_UNLIKELY(bytesCompacted == -1)) {
compactionInProgress = false;
return -errno;
}
totalBytesCompacted += bytesCompacted;
}
compactionInProgress = false;
return totalBytesCompacted;
}
@@ -228,6 +242,12 @@ static void com_android_server_am_CachedAppOptimizer_compactSystem(JNIEnv *, job
}
}
static void com_android_server_am_CachedAppOptimizer_cancelCompaction(JNIEnv*, jobject) {
if (compactionInProgress) {
cancelRunningCompaction = true;
}
}
static void com_android_server_am_CachedAppOptimizer_compactProcess(JNIEnv*, jobject, jint pid,
jint compactionFlags) {
compactProcessOrFallback(pid, compactionFlags);
@@ -279,6 +299,8 @@ static jstring com_android_server_am_CachedAppOptimizer_getFreezerCheckPath(JNIE
static const JNINativeMethod sMethods[] = {
/* name, signature, funcPtr */
{"cancelCompaction", "()V",
(void*)com_android_server_am_CachedAppOptimizer_cancelCompaction},
{"compactSystem", "()V", (void*)com_android_server_am_CachedAppOptimizer_compactSystem},
{"compactProcess", "(II)V", (void*)com_android_server_am_CachedAppOptimizer_compactProcess},
{"freezeBinder", "(IZ)I", (void*)com_android_server_am_CachedAppOptimizer_freezeBinder},