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

Commit e3f2406b authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Boost Zygote to fifo for top-app forks when using fifo ui" into main

parents 02c6ddcd 67a4b1b2
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -373,9 +373,11 @@ public final class Zygote {
            boolean bindMountSyspropOverrides) {
        ZygoteHooks.preFork();

        boolean useFifoUi = SystemProperties.getInt("sys.use_fifo_ui", 0) == 1;
        int pid = nativeForkAndSpecialize(
                uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
                fdsToIgnore, startChildZygote, instructionSet, appDataDir, isTopApp,
                com.android.internal.os.Flags.zygoteEarlyFifoBoost() ? useFifoUi : false,
                pkgDataInfoList, allowlistedDataInfoList, bindMountAppDataDirs,
                bindMountAppStorageDirs, bindMountSyspropOverrides);
        if (pid == 0) {
@@ -398,7 +400,7 @@ public final class Zygote {
    private static native int nativeForkAndSpecialize(int uid, int gid, int[] gids,
            int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName,
            int[] fdsToClose, int[] fdsToIgnore, boolean startChildZygote, String instructionSet,
            String appDataDir, boolean isTopApp, String[] pkgDataInfoList,
            String appDataDir, boolean isTopApp, boolean useFifoUi, String[] pkgDataInfoList,
            String[] allowlistedDataInfoList, boolean bindMountAppDataDirs,
            boolean bindMountAppStorageDirs, boolean bindMountSyspropOverrides);

@@ -730,9 +732,11 @@ public final class Zygote {
                                             @NonNull FileDescriptor zygoteSocket,
                                             int expectedUid,
                                             int minUid,
                                             @Nullable String firstNiceName) {
                                             @Nullable String firstNiceName,
                                             boolean isTopApp) {
        boolean in_child =
                argBuffer.forkRepeatedly(zygoteSocket, expectedUid, minUid, firstNiceName);
                argBuffer.forkRepeatedly(zygoteSocket, expectedUid, minUid, firstNiceName,
                        isTopApp);
        if (in_child) {
            return childMain(argBuffer, /*usapPoolSocket=*/null, /*writePipe=*/null);
        } else {
+8 −3
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.internal.os;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.net.LocalSocket;
import android.os.SystemProperties;

import java.io.FileDescriptor;
import java.lang.ref.Reference;  // For reachabilityFence.
@@ -164,10 +165,12 @@ class ZygoteCommandBuffer implements AutoCloseable {
     * at the beginning of a command that still needs to be processed.
     */
    boolean forkRepeatedly(FileDescriptor zygoteSocket, int expectedUid, int minUid,
                       String firstNiceName) {
                       String firstNiceName, boolean isTopApp) {
        try {
            boolean useFifoUi = SystemProperties.getInt("sys.use_fifo_ui", 0) == 1;
            return nativeForkRepeatedly(mNativeBuffer, zygoteSocket.getInt$(),
                    expectedUid, minUid, firstNiceName);
                    expectedUid, minUid, firstNiceName, isTopApp,
                    com.android.internal.os.Flags.zygoteEarlyFifoBoost() ? useFifoUi : false);
        } finally {
            Reference.reachabilityFence(mSocket);
            Reference.reachabilityFence(zygoteSocket);
@@ -182,6 +185,8 @@ class ZygoteCommandBuffer implements AutoCloseable {
                                                   int zygoteSocketRawFd,
                                                   int expectedUid,
                                                   int minUid,
                                                   String firstNiceName);
                                                   String firstNiceName,
                                                   boolean isTopApp,
                                                   boolean useFifoUi);

}
+2 −1
Original line number Diff line number Diff line
@@ -284,7 +284,8 @@ class ZygoteConnection {
                    ZygoteHooks.preFork();
                    Runnable result = Zygote.forkSimpleApps(argBuffer,
                            zygoteServer.getZygoteSocketFileDescriptor(),
                            peer.getUid(), Zygote.minChildUid(peer), parsedArgs.mNiceName);
                            peer.getUid(), Zygote.minChildUid(peer), parsedArgs.mNiceName,
                            parsedArgs.mIsTopApp);
                    if (result == null) {
                        // parent; we finished some number of forks. Result is Boolean.
                        // We already did the equivalent of handleParentProc().
+8 −0
Original line number Diff line number Diff line
@@ -60,3 +60,11 @@ flag {
        purpose: PURPOSE_BUGFIX
    }
}

flag {
    name: "zygote_early_fifo_boost"
    namespace: "watch_software_performance"
    description: "Enables zygote boosting to fifo priority for top-app launches when fifo_ui is enabled"
    bug: "397918406"
    is_fixed_read_only: true
}
+59 −12
Original line number Diff line number Diff line
@@ -2432,9 +2432,30 @@ pid_t zygote::ForkCommon(JNIEnv* env, bool is_system_server,
                         const std::vector<int>& fds_to_close,
                         const std::vector<int>& fds_to_ignore,
                         bool is_priority_fork,
                         bool is_top_app,
                         bool use_fifo_ui,
                         bool purge) {
  ATRACE_CALL();
  if (is_priority_fork) {
  /*
  * Number of processors configured on the device.
  */
  static int number_of_processors = sysconf(_SC_NPROCESSORS_CONF);

  if (is_top_app && use_fifo_ui) {
    // Set SCHED_FIFO for top-app fork where FIFO UI is enabled.
    struct sched_param rt_param;
    rt_param.sched_priority = 1; // 98 prio

    if (number_of_processors == 1) {
      RuntimeAbort(env, __LINE__, "Cannot set SCHED_FIFO on single-core devices.");
    }

    if (sched_setscheduler(0, SCHED_FIFO, &rt_param) != 0) {
      ALOGE("Failed to set SCHED_FIFO: %s", strerror(errno));
    } else {
      ALOGW("Setting SCHED_FIFO for top-app fork");
    }
  } else if (is_priority_fork) {
    setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MAX);
  }

@@ -2485,9 +2506,22 @@ pid_t zygote::ForkCommon(JNIEnv* env, bool is_system_server,
  pid_t pid = fork();

  if (pid == 0) {
    if (is_priority_fork) {
    if (is_top_app && use_fifo_ui) {
      // Explicitly set SCHED_FIFO | SCHED_RESET_ON_FORK for child's main thread to avoid other
      // threads inheriting the main thread's FIFO scheduling policy.
      // Empirically, SCHED_RESET_ON_FORK also applies to newly created threads.
      // An app shall have no more than the main and render threads running at
      // FIFO priority, thus not saturating the device with SCHED_FIFO tasks.
      struct sched_param child_rt_param = {0};
      child_rt_param.sched_priority = 1; // 98 prio
      if (sched_setscheduler(0, SCHED_FIFO | SCHED_RESET_ON_FORK, &child_rt_param) != 0) {
        ALOGE("Failed to set SCHED_FIFO | SCHED_RESET_ON_FORK: %s", strerror(errno));
        RuntimeAbort(env, __LINE__, "Failed to set SCHED_FIFO | SCHED_RESET_ON_FORK in child");
      }
    } else if (is_priority_fork) {
        setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MAX);
      } else {
        // TODO: Revisit this.
        setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MIN);
      }

@@ -2523,7 +2557,17 @@ pid_t zygote::ForkCommon(JNIEnv* env, bool is_system_server,
  // We blocked SIGCHLD prior to a fork, we unblock it here.
  UnblockSignal(SIGCHLD, fail_fn);

  if (is_priority_fork && pid != 0) {
  if (is_top_app && use_fifo_ui && pid != 0) {
    // Reset the scheduler to SCHED_OTHER for the Zygote process.
    struct sched_param zero_param = {0};
    if (sched_setscheduler(0, SCHED_OTHER, &zero_param) != 0) {
      ALOGE("Failed to reset scheduler: %s", strerror(errno));
      RuntimeAbort(env, __LINE__, "Failed to reset scheduler");
    } else {
      ALOGD("Reset scheduler to SCHED_OTHER");
    }
    setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_DEFAULT);
  } else if (is_priority_fork && pid != 0) {
    setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_DEFAULT);
  }

@@ -2539,7 +2583,7 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
        JNIEnv* env, jclass, jint uid, jint gid, jintArray gids, jint runtime_flags,
        jobjectArray rlimits, jint mount_external, jstring se_info, jstring nice_name,
        jintArray managed_fds_to_close, jintArray managed_fds_to_ignore, jboolean is_child_zygote,
        jstring instruction_set, jstring app_data_dir, jboolean is_top_app,
        jstring instruction_set, jstring app_data_dir, jboolean is_top_app, jboolean use_fifo_ui,
        jobjectArray pkg_data_info_list, jobjectArray allowlisted_data_info_list,
        jboolean mount_data_dirs, jboolean mount_storage_dirs, jboolean mount_sysprop_overrides) {
    jlong capabilities = CalculateCapabilities(env, uid, gid, gids, is_child_zygote);
@@ -2578,7 +2622,7 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
    }

    pid_t pid = zygote::ForkCommon(env, /* is_system_server= */ false, fds_to_close, fds_to_ignore,
                                   true);
                                   true, is_top_app == JNI_TRUE, use_fifo_ui == JNI_TRUE);

    if (pid == 0) {
        SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, capabilities, capabilities,
@@ -2668,7 +2712,8 @@ static jint com_android_internal_os_Zygote_nativeForkApp(JNIEnv* env,
      ExtractJIntArray(env, "USAP", nullptr, managed_session_socket_fds)
          .value_or(std::vector<int>());
  return zygote::forkApp(env, read_pipe_fd, write_pipe_fd, session_socket_fds,
                            args_known == JNI_TRUE, is_priority_fork == JNI_TRUE, true);
                            args_known == JNI_TRUE, is_priority_fork == JNI_TRUE,
                            false, false, true);
}

NO_STACK_PROTECTOR
@@ -2678,6 +2723,8 @@ int zygote::forkApp(JNIEnv* env,
                    const std::vector<int>& session_socket_fds,
                    bool args_known,
                    bool is_priority_fork,
                    bool is_top_app,
                    bool use_fifo_ui,
                    bool purge) {
  ATRACE_CALL();

@@ -2718,7 +2765,7 @@ int zygote::forkApp(JNIEnv* env,
  }

  return zygote::ForkCommon(env, /* is_system_server= */ false, fds_to_close,
                            fds_to_ignore, is_priority_fork == JNI_TRUE, purge);
                            fds_to_ignore, is_priority_fork, is_top_app, use_fifo_ui, purge);
}

static void com_android_internal_os_Zygote_nativeAllowFileAcrossFork(
@@ -3055,7 +3102,7 @@ static void com_android_internal_os_Zygote_nativeAllowFilesOpenedByPreload(JNIEn
static const JNINativeMethod gMethods[] = {
        {"nativeForkAndSpecialize",
         "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/"
         "String;Z[Ljava/lang/String;[Ljava/lang/String;ZZZ)I",
         "String;ZZ[Ljava/lang/String;[Ljava/lang/String;ZZZ)I",
         (void*)com_android_internal_os_Zygote_nativeForkAndSpecialize},
        {"nativeForkSystemServer", "(II[II[[IJJ)I",
         (void*)com_android_internal_os_Zygote_nativeForkSystemServer},
Loading