Merge "Cancel compaction if the process improves its OOM ranking while compaction is running" into sc-v2-dev am: 0199f07a27
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16616583 Change-Id: Id9ebb68d11ad9ac0c78af0ebece7ff59bf80eed7
This commit is contained in:
@@ -523,6 +523,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.
|
||||
@@ -1030,6 +1032,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;
|
||||
@@ -1072,6 +1094,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
|
||||
@@ -1481,6 +1510,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) {
|
||||
@@ -1490,6 +1521,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])) {
|
||||
@@ -1497,6 +1529,7 @@ public final class CachedAppOptimizer {
|
||||
} else if (action.equals(COMPACT_ACTION_STRING[COMPACT_ACTION_ANON])) {
|
||||
compactProcess(pid, COMPACT_ACTION_ANON_FLAG);
|
||||
}
|
||||
mPidCompacting = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2606,18 +2606,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
|
||||
|
||||
@@ -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},
|
||||
|
||||
Reference in New Issue
Block a user