Merge "Cancel compaction if the process improves its OOM ranking while compaction is running" into sc-v2-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
0199f07a27
@@ -523,6 +523,8 @@ public final class CachedAppOptimizer {
|
|||||||
*/
|
*/
|
||||||
static private native void compactProcess(int pid, int compactionFlags);
|
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
|
* Reads the flag value from DeviceConfig to determine whether app compaction
|
||||||
* should be enabled, and starts the freeze/compaction thread if needed.
|
* should be enabled, and starts the freeze/compaction thread if needed.
|
||||||
@@ -1026,6 +1028,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
|
@VisibleForTesting
|
||||||
static final class LastCompactionStats {
|
static final class LastCompactionStats {
|
||||||
private final long[] mRssAfterCompaction;
|
private final long[] mRssAfterCompaction;
|
||||||
@@ -1068,6 +1090,13 @@ public final class CachedAppOptimizer {
|
|||||||
name = proc.processName;
|
name = proc.processName;
|
||||||
opt.setHasPendingCompact(false);
|
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
|
// don't compact if the process has returned to perceptible
|
||||||
// and this is only a cached/home/prev compaction
|
// and this is only a cached/home/prev compaction
|
||||||
if ((pendingAction == COMPACT_PROCESS_SOME
|
if ((pendingAction == COMPACT_PROCESS_SOME
|
||||||
@@ -1477,6 +1506,8 @@ public final class CachedAppOptimizer {
|
|||||||
* Default implementation for ProcessDependencies, public vor visibility to OomAdjuster class.
|
* Default implementation for ProcessDependencies, public vor visibility to OomAdjuster class.
|
||||||
*/
|
*/
|
||||||
private static final class DefaultProcessDependencies implements ProcessDependencies {
|
private static final class DefaultProcessDependencies implements ProcessDependencies {
|
||||||
|
public static int mPidCompacting = -1;
|
||||||
|
|
||||||
// Get memory RSS from process.
|
// Get memory RSS from process.
|
||||||
@Override
|
@Override
|
||||||
public long[] getRss(int pid) {
|
public long[] getRss(int pid) {
|
||||||
@@ -1486,6 +1517,7 @@ public final class CachedAppOptimizer {
|
|||||||
// Compact process.
|
// Compact process.
|
||||||
@Override
|
@Override
|
||||||
public void performCompaction(String action, int pid) throws IOException {
|
public void performCompaction(String action, int pid) throws IOException {
|
||||||
|
mPidCompacting = pid;
|
||||||
if (action.equals(COMPACT_ACTION_STRING[COMPACT_ACTION_FULL])) {
|
if (action.equals(COMPACT_ACTION_STRING[COMPACT_ACTION_FULL])) {
|
||||||
compactProcess(pid, COMPACT_ACTION_FILE_FLAG | COMPACT_ACTION_ANON_FLAG);
|
compactProcess(pid, COMPACT_ACTION_FILE_FLAG | COMPACT_ACTION_ANON_FLAG);
|
||||||
} else if (action.equals(COMPACT_ACTION_STRING[COMPACT_ACTION_FILE])) {
|
} else if (action.equals(COMPACT_ACTION_STRING[COMPACT_ACTION_FILE])) {
|
||||||
@@ -1493,6 +1525,7 @@ public final class CachedAppOptimizer {
|
|||||||
} else if (action.equals(COMPACT_ACTION_STRING[COMPACT_ACTION_ANON])) {
|
} else if (action.equals(COMPACT_ACTION_STRING[COMPACT_ACTION_ANON])) {
|
||||||
compactProcess(pid, COMPACT_ACTION_ANON_FLAG);
|
compactProcess(pid, COMPACT_ACTION_ANON_FLAG);
|
||||||
}
|
}
|
||||||
|
mPidCompacting = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2606,18 +2606,9 @@ public class OomAdjuster {
|
|||||||
// don't compact during bootup
|
// don't compact during bootup
|
||||||
if (mCachedAppOptimizer.useCompaction() && mService.mBooted) {
|
if (mCachedAppOptimizer.useCompaction() && mService.mBooted) {
|
||||||
// Cached and prev/home compaction
|
// Cached and prev/home compaction
|
||||||
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
|
// reminder: here, setAdj is previous state, curAdj is upcoming state
|
||||||
if (state.getSetAdj() <= ProcessList.PERCEPTIBLE_APP_ADJ
|
if (state.getCurAdj() != state.getSetAdj()) {
|
||||||
&& (state.getCurAdj() == ProcessList.PREVIOUS_APP_ADJ
|
mCachedAppOptimizer.onOomAdjustChanged(state.getSetAdj(), state.getCurAdj(), app);
|
||||||
|| 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);
|
|
||||||
}
|
|
||||||
} else if (mService.mWakefulness.get() != PowerManagerInternal.WAKEFULNESS_AWAKE
|
} else if (mService.mWakefulness.get() != PowerManagerInternal.WAKEFULNESS_AWAKE
|
||||||
&& state.getSetAdj() < ProcessList.FOREGROUND_APP_ADJ
|
&& state.getSetAdj() < ProcessList.FOREGROUND_APP_ADJ
|
||||||
// Because these can fire independent of oom_adj/procstate changes, we need
|
// Because these can fire independent of oom_adj/procstate changes, we need
|
||||||
|
|||||||
@@ -59,6 +59,9 @@ using android::base::unique_fd;
|
|||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
|
static bool cancelRunningCompaction;
|
||||||
|
static bool compactionInProgress;
|
||||||
|
|
||||||
// Legacy method for compacting processes, any new code should
|
// Legacy method for compacting processes, any new code should
|
||||||
// use compactProcess instead.
|
// use compactProcess instead.
|
||||||
static inline void compactProcessProcfs(int pid, const std::string& compactionType) {
|
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
|
// Skip compaction if failed to open pidfd with any error
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
compactionInProgress = true;
|
||||||
|
cancelRunningCompaction = false;
|
||||||
|
|
||||||
int64_t totalBytesCompacted = 0;
|
int64_t totalBytesCompacted = 0;
|
||||||
for (int iBase = 0; iBase < vmas.size(); iBase += UIO_MAXIOV) {
|
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));
|
int totalVmasToKernel = std::min(UIO_MAXIOV, (int)(vmas.size() - iBase));
|
||||||
for (int iVec = 0, iVma = iBase; iVec < totalVmasToKernel; ++iVec, ++iVma) {
|
for (int iVec = 0, iVma = iBase; iVec < totalVmasToKernel; ++iVec, ++iVma) {
|
||||||
vmasToKernel[iVec].iov_base = (void*)vmas[iVma].start;
|
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 =
|
auto bytesCompacted =
|
||||||
process_madvise(pidfd, vmasToKernel, totalVmasToKernel, madviseType, 0);
|
process_madvise(pidfd, vmasToKernel, totalVmasToKernel, madviseType, 0);
|
||||||
if (CC_UNLIKELY(bytesCompacted == -1)) {
|
if (CC_UNLIKELY(bytesCompacted == -1)) {
|
||||||
|
compactionInProgress = false;
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
totalBytesCompacted += bytesCompacted;
|
totalBytesCompacted += bytesCompacted;
|
||||||
}
|
}
|
||||||
|
compactionInProgress = false;
|
||||||
|
|
||||||
return totalBytesCompacted;
|
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,
|
static void com_android_server_am_CachedAppOptimizer_compactProcess(JNIEnv*, jobject, jint pid,
|
||||||
jint compactionFlags) {
|
jint compactionFlags) {
|
||||||
compactProcessOrFallback(pid, compactionFlags);
|
compactProcessOrFallback(pid, compactionFlags);
|
||||||
@@ -279,6 +299,8 @@ static jstring com_android_server_am_CachedAppOptimizer_getFreezerCheckPath(JNIE
|
|||||||
|
|
||||||
static const JNINativeMethod sMethods[] = {
|
static const JNINativeMethod sMethods[] = {
|
||||||
/* name, signature, funcPtr */
|
/* name, signature, funcPtr */
|
||||||
|
{"cancelCompaction", "()V",
|
||||||
|
(void*)com_android_server_am_CachedAppOptimizer_cancelCompaction},
|
||||||
{"compactSystem", "()V", (void*)com_android_server_am_CachedAppOptimizer_compactSystem},
|
{"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_compactProcess},
|
||||||
{"freezeBinder", "(IZ)I", (void*)com_android_server_am_CachedAppOptimizer_freezeBinder},
|
{"freezeBinder", "(IZ)I", (void*)com_android_server_am_CachedAppOptimizer_freezeBinder},
|
||||||
|
|||||||
Reference in New Issue
Block a user