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

Commit 0671d4e8 authored by Jing Ji's avatar Jing Ji
Browse files

Clear the process record nodes' fields during reset

When resetting the linked list for the process records,
individual node's prev/next fields should be cleared too.

Also, link/unlink process record nodes correctly

The new oom adjuster implementation maintains a set of linked lists
where the nodes are basically the process records. These records
are added/remove from this list along with the process lifecycle.
However, there are cases where the process hasn't been fully started
but the oom adjuster has started computations on these new records.
In these case, we should put them into the list as long as we're
creating these process records, or otherwise we'll be hitting
NPE issue.

Bug: 312498619
Test: atest CtsAppTestCases
Test: atest FrameworksMockingServicesTests:MockingOomAdjusterTests
Test: atest FrameworksMockingServicesTests:BroadcastQueueTest
Test: atest FrameworksMockingServicesTests:BroadcastQueueModernImplTest
Test: atest FrameworksMockingServicesTests:AsyncProcessStartTest
Change-Id: I9232514b81bca433b66f0895e5a652198dd60d16
parent e68ec558
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -2085,7 +2085,6 @@ public class ActivityManagerService extends IActivityManager.Stub
                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
                app.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_SYSTEM);
                addPidLocked(app);
                mOomAdjuster.onProcessBeginLocked(app);
                updateLruProcessLocked(app, false, null);
                updateOomAdjLocked(OOM_ADJ_REASON_SYSTEM_INIT);
            }
@@ -4624,7 +4623,6 @@ public class ActivityManagerService extends IActivityManager.Stub
        EventLogTags.writeAmProcBound(app.userId, pid, app.processName);
        synchronized (mProcLock) {
            mOomAdjuster.onProcessBeginLocked(app);
            mOomAdjuster.setAttachingProcessStatesLSP(app);
            clearProcessForegroundLocked(app);
            app.setDebugging(false);
@@ -7104,7 +7102,6 @@ public class ActivityManagerService extends IActivityManager.Stub
                    sdkSandboxClientAppPackage,
                    new HostingRecord(HostingRecord.HOSTING_TYPE_ADDED_APPLICATION,
                            customProcess != null ? customProcess : info.processName));
            mOomAdjuster.onProcessBeginLocked(app);
            updateLruProcessLocked(app, false, null);
            updateOomAdjLocked(app, OOM_ADJ_REASON_PROCESS_BEGIN);
        }
+2 −8
Original line number Diff line number Diff line
@@ -41,7 +41,6 @@ import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT_UI;
import static android.app.ActivityManager.PROCESS_STATE_SERVICE;
import static android.app.ActivityManager.PROCESS_STATE_TOP;
import static android.app.ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
import static android.app.ActivityManager.PROCESS_STATE_UNKNOWN;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_ACTIVITY;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_ALLOWLIST;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_BACKUP;
@@ -3494,8 +3493,8 @@ public class OomAdjuster {
        int initialCapability =  PROCESS_CAPABILITY_NONE;
        boolean initialCached = true;
        final ProcessStateRecord state = app.mState;
        final int prevProcState = PROCESS_STATE_UNKNOWN;
        final int prevAdj = UNKNOWN_ADJ;
        final int prevProcState = state.getCurRawProcState();
        final int prevAdj = state.getCurRawAdj();
        // If the process has been marked as foreground, it is starting as the top app (with
        // Zygote#START_AS_TOP_APP_ARG), so boost the thread priority of its default UI thread.
        if (state.hasForegroundActivities()) {
@@ -3781,11 +3780,6 @@ public class OomAdjuster {
        processes.clear();
    }

    @GuardedBy("mService")
    void onProcessBeginLocked(@NonNull ProcessRecord app) {
        // Empty, the OomAdjusterModernImpl will have an implementation.
    }

    @GuardedBy("mService")
    void onProcessEndLocked(@NonNull ProcessRecord app) {
        // Empty, the OomAdjusterModernImpl will have an implementation.
+10 −17
Original line number Diff line number Diff line
@@ -331,9 +331,9 @@ public class OomAdjusterModernImpl extends OomAdjuster {
                if (mLastNode[prevSlot] == node) {
                    mLastNode[prevSlot] = node.mPrev;
                }
                node.unlink();
            }
            mProcessRecordNodes[newSlot].append(node);
            // node will be firstly unlinked in the append.
            append(node, newSlot);
        }

        void moveAllNodesTo(int fromSlot, int toSlot) {
@@ -389,7 +389,11 @@ public class OomAdjusterModernImpl extends OomAdjuster {
        }

        void append(@NonNull ProcessRecord app, int targetSlot) {
            final ProcessRecordNode node = app.mLinkedNodes[mType];
            append(app.mLinkedNodes[mType], targetSlot);
        }

        void append(@NonNull ProcessRecordNode node, int targetSlot) {
            node.unlink();
            mProcessRecordNodes[targetSlot].append(node);
        }

@@ -452,6 +456,9 @@ public class OomAdjusterModernImpl extends OomAdjuster {

            @VisibleForTesting
            void reset() {
                if (HEAD.mNext != TAIL) {
                    HEAD.mNext.mPrev = TAIL.mPrev.mNext = null;
                }
                HEAD.mNext = TAIL;
                TAIL.mPrev = HEAD;
            }
@@ -556,20 +563,6 @@ public class OomAdjusterModernImpl extends OomAdjuster {
        mProcessRecordAdjNodes.reset();
    }

    @GuardedBy("mService")
    @Override
    void onProcessBeginLocked(@NonNull ProcessRecord app) {
        // Check one type should be good enough.
        if (app.mLinkedNodes[ProcessRecordNode.NODE_TYPE_PROC_STATE] == null) {
            for (int i = 0; i < app.mLinkedNodes.length; i++) {
                app.mLinkedNodes[i] = new ProcessRecordNode(app);
            }
        }
        if (!app.mLinkedNodes[ProcessRecordNode.NODE_TYPE_PROC_STATE].isLinked()) {
            linkProcessRecordToList(app);
        }
    }

    @GuardedBy("mService")
    @Override
    void onProcessEndLocked(@NonNull ProcessRecord app) {
+2 −0
Original line number Diff line number Diff line
@@ -2153,6 +2153,7 @@ public final class ProcessList {
                    mService.forceStopPackageLocked(app.info.packageName,
                            UserHandle.getAppId(app.uid),
                            false, false, true, false, false, false, app.userId, "start failure");
                    app.doEarlyCleanupIfNecessaryLocked();
                }
            }
        };
@@ -2782,6 +2783,7 @@ public final class ProcessList {
            }
            noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
                    ApplicationExitInfo.SUBREASON_INVALID_START, reason);
            app.doEarlyCleanupIfNecessaryLocked();
            return false;
        }
        mService.mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
+28 −0
Original line number Diff line number Diff line
@@ -621,6 +621,34 @@ class ProcessRecord implements WindowProcessListener {
        mWindowProcessController = new WindowProcessController(
                mService.mActivityTaskManager, info, processName, uid, userId, this, this);
        mPkgList.put(_info.packageName, new ProcessStats.ProcessStateHolder(_info.longVersionCode));
        updateProcessRecordNodes(this);
    }

    /**
     * Helper function to let test cases update the pointers.
     */
    @VisibleForTesting
    static void updateProcessRecordNodes(@NonNull ProcessRecord app) {
        if (app.mService.mConstants.ENABLE_NEW_OOMADJ) {
            for (int i = 0; i < app.mLinkedNodes.length; i++) {
                app.mLinkedNodes[i] = new ProcessRecordNode(app);
            }
        }
    }

    /**
     * Perform cleanups if the process record is going to be discarded in an early
     * stage of the process lifecycle, specifically when the process has not even
     * attached itself to the system_server.
     */
    @GuardedBy("mService")
    void doEarlyCleanupIfNecessaryLocked() {
        if (getThread() == null) {
            // It's not even attached, make sure we unlink its process nodes.
            mService.mOomAdjuster.onProcessEndLocked(this);
        } else {
            // Let the binder died callback handle the cleanup.
        }
    }

    void resetCrashingOnRestart() {
Loading