diff --git a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp index 8664c38af816c..1ff5002568a36 100644 --- a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp +++ b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp @@ -74,10 +74,12 @@ using android::base::unique_fd; // limit, it has to be a page aligned value, otherwise, compaction would fail. #define MAX_BYTES_PER_COMPACTION MAX_RW_COUNT +// Selected a high enough number to avoid clashing with linux errno codes +#define ERROR_COMPACTION_CANCELLED -1000 + namespace android { -static bool cancelRunningCompaction; -static bool compactionInProgress; +static std::atomic cancelRunningCompaction; // Legacy method for compacting processes, any new code should // use compactProcess instead. @@ -103,8 +105,6 @@ static int64_t compactMemory(const std::vector& vmas, int pid, int madviseT // Skip compaction if failed to open pidfd with any error return -errno; } - compactionInProgress = true; - cancelRunningCompaction = false; int64_t totalBytesProcessed = 0; @@ -113,14 +113,14 @@ static int64_t compactMemory(const std::vector& vmas, int pid, int madviseT uint64_t bytesSentToCompact = 0; int iVec = 0; while (iVec < MAX_VMAS_PER_COMPACTION && iVma < vmas.size()) { - if (CC_UNLIKELY(cancelRunningCompaction)) { + if (CC_UNLIKELY(cancelRunningCompaction.load())) { // There could be a significant delay between when a compaction // is requested and when it is handled during this time our // OOM adjust could have improved. LOG(DEBUG) << "Cancelled running compaction for " << pid; ATRACE_INSTANT_FOR_TRACK(ATRACE_COMPACTION_TRACK, StringPrintf("Cancelled compaction for %d", pid).c_str()); - break; + return ERROR_COMPACTION_CANCELLED; } uint64_t vmaStart = vmas[iVma].start + vmaOffset; @@ -150,11 +150,6 @@ static int64_t compactMemory(const std::vector& vmas, int pid, int madviseT ++iVma; } - if (cancelRunningCompaction) { - cancelRunningCompaction = false; - break; - } - ATRACE_BEGIN(StringPrintf("Compact %d VMAs", iVec).c_str()); auto bytesProcessed = process_madvise(pidfd, vmasToKernel, iVec, madviseType, 0); ATRACE_END(); @@ -166,14 +161,12 @@ static int64_t compactMemory(const std::vector& vmas, int pid, int madviseT continue; } else { // Forward irrecoverable errors and bail out compaction - compactionInProgress = false; return -errno; } } totalBytesProcessed += bytesProcessed; } - compactionInProgress = false; return totalBytesProcessed; } @@ -202,9 +195,12 @@ static int getAnyPageAdvice(const Vma& vma) { // // Currently supported behaviors are MADV_COLD and MADV_PAGEOUT. // -// Returns the total number of bytes compacted or forwards an -// process_madvise error. +// Returns the total number of bytes compacted on success. On error +// returns process_madvise errno code or if compaction was cancelled +// it returns ERROR_COMPACTION_CANCELLED. static int64_t compactProcess(int pid, VmaToAdviseFunc vmaToAdviseFunc) { + cancelRunningCompaction.store(false); + ProcMemInfo meminfo(pid); std::vector pageoutVmas, coldVmas; auto vmaCollectorCb = [&coldVmas,&pageoutVmas,&vmaToAdviseFunc](const Vma& vma) { @@ -223,12 +219,14 @@ static int64_t compactProcess(int pid, VmaToAdviseFunc vmaToAdviseFunc) { int64_t pageoutBytes = compactMemory(pageoutVmas, pid, MADV_PAGEOUT); if (pageoutBytes < 0) { // Error, just forward it. + cancelRunningCompaction.store(false); return pageoutBytes; } int64_t coldBytes = compactMemory(coldVmas, pid, MADV_COLD); if (coldBytes < 0) { // Error, just forward it. + cancelRunningCompaction.store(false); return coldBytes; } @@ -308,10 +306,8 @@ static void com_android_server_am_CachedAppOptimizer_compactSystem(JNIEnv *, job } static void com_android_server_am_CachedAppOptimizer_cancelCompaction(JNIEnv*, jobject) { - if (compactionInProgress) { - cancelRunningCompaction = true; - ATRACE_INSTANT_FOR_TRACK(ATRACE_COMPACTION_TRACK, "Cancel compaction"); - } + cancelRunningCompaction.store(true); + ATRACE_INSTANT_FOR_TRACK(ATRACE_COMPACTION_TRACK, "Cancel compaction"); } static jdouble com_android_server_am_CachedAppOptimizer_getFreeSwapPercent(JNIEnv*, jobject) {