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

Commit 463a08b2 authored by Edgar Arriaga's avatar Edgar Arriaga
Browse files

Fix for compaction partially bailing out compaction upon cancellation

When compaction if a cancel signal is received such as when unlocking
the phone, if the system was doing an anon compaction it will bail out
but then continue with the file compaction since it was not fully
bailing out from compaction computation.

Test: Manual
Bug: 227060330

Change-Id: I46bb784c1170808d9aa15757a108900e54175987
parent 8a054c32
Loading
Loading
Loading
Loading
+15 −19
Original line number Diff line number Diff line
@@ -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<bool> cancelRunningCompaction;

// Legacy method for compacting processes, any new code should
// use compactProcess instead.
@@ -103,8 +105,6 @@ 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 totalBytesProcessed = 0;

@@ -113,14 +113,14 @@ static int64_t compactMemory(const std::vector<Vma>& 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<Vma>& 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<Vma>& 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<Vma> 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,11 +306,9 @@ static void com_android_server_am_CachedAppOptimizer_compactSystem(JNIEnv *, job
}

static void com_android_server_am_CachedAppOptimizer_cancelCompaction(JNIEnv*, jobject) {
    if (compactionInProgress) {
        cancelRunningCompaction = true;
    cancelRunningCompaction.store(true);
    ATRACE_INSTANT_FOR_TRACK(ATRACE_COMPACTION_TRACK, "Cancel compaction");
}
}

static jdouble com_android_server_am_CachedAppOptimizer_getFreeSwapPercent(JNIEnv*, jobject) {
    struct sysinfo memoryInfo;