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

Commit 6c4c4a59 authored by T.J. Mercier's avatar T.J. Mercier
Browse files

Don't wait after SIGKILL when freeze-killing

When freeze-killing (for package force-stops) we attempt to wait until all
processes have 1) Received the kill signal AND 2) have actually exited and been
cleaned up AND 3) the associated cgroup(s) have been removed. The second and
third parts can take a long time, which can lead to lock contention in
ActivityManagerService when many kills are attempted simultaneously. For
freeze-kills with SIGKILL we do not need to wait to prevent app-restart
exploits. Now we send these processes a SIGKILL after freezing, but
do not wait until they are actually dead before returning.

Bug: 274646058
Test: Force-stop of chrome with 15 tabs completes ~500ms faster
Test: Full Play store update causes no ANR
Change-Id: Ib4cc2e31190338b565e4a89acce64d9ae52b19c9
parent b0e7c738
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -1485,6 +1485,15 @@ public class Process {
     */
    public static final native int killProcessGroup(int uid, int pid);

    /**
     * Send a signal to all processes in a group under the given PID, but do not wait for the
     * processes to be fully cleaned up, or for the cgroup to be removed before returning.
     * Callers should also ensure that killProcessGroup is called later to ensure the cgroup is
     * fully removed, otherwise system resources may leak.
     * @hide
     */
    public static final native int sendSignalToProcessGroup(int uid, int pid, int signal);

    /**
      * Freeze the cgroup for the given UID.
      * This cgroup may contain child cgroups which will also be frozen. If this cgroup or its
+6 −0
Original line number Diff line number Diff line
@@ -1238,6 +1238,11 @@ jint android_os_Process_killProcessGroup(JNIEnv* env, jobject clazz, jint uid, j
    return killProcessGroup(uid, pid, SIGKILL);
}

jint android_os_Process_sendSignalToProcessGroup(JNIEnv* env, jobject clazz, jint uid, jint pid,
                                                 jint signal) {
    return sendSignalToProcessGroup(uid, pid, signal);
}

void android_os_Process_removeAllProcessGroups(JNIEnv* env, jobject clazz)
{
    return removeAllProcessGroups();
@@ -1305,6 +1310,7 @@ static const JNINativeMethod methods[] = {
        //{"setApplicationObject", "(Landroid/os/IBinder;)V",
        //(void*)android_os_Process_setApplicationObject},
        {"killProcessGroup", "(II)I", (void*)android_os_Process_killProcessGroup},
        {"sendSignalToProcessGroup", "(III)I", (void*)android_os_Process_sendSignalToProcessGroup},
        {"removeAllProcessGroups", "()V", (void*)android_os_Process_removeAllProcessGroups},
        {"nativePidFdOpen", "(II)I", (void*)android_os_Process_nativePidFdOpen},
        {"freezeCgroupUid", "(IZ)V", (void*)android_os_Process_freezeCgroupUID},
+3 −2
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import android.os.SystemClock;
import android.os.Trace;
import android.os.UserHandle;
import android.server.ServerProtoEnums;
import android.system.OsConstants;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.DebugUtils;
@@ -1182,8 +1183,8 @@ class ProcessRecord implements WindowProcessListener {
                EventLog.writeEvent(EventLogTags.AM_KILL,
                        userId, mPid, processName, mState.getSetAdj(), reason);
                Process.killProcessQuiet(mPid);
                if (asyncKPG) ProcessList.killProcessGroup(uid, mPid);
                else Process.killProcessGroup(uid, mPid);
                if (!asyncKPG) Process.sendSignalToProcessGroup(uid, mPid, OsConstants.SIGKILL);
                ProcessList.killProcessGroup(uid, mPid);
            } else {
                mPendingStart = false;
            }