From 9778046548772c8d94b8aa2dbdf6529b693aad45 Mon Sep 17 00:00:00 2001 From: Narayan Kamath Date: Mon, 6 Feb 2017 20:24:08 +0000 Subject: [PATCH] Zygote: Explicitly preload secondary zygote resources. We now turn on lazy preloading (see companion change 73c7df1bda76a0) and explicitly preload zygote resources. To provide the most benefit : - We start the preload in the system_server, which means the system_server starts quicker since it has one less preload to wait for. Morever, the 64 bit zygote also starts quicker because it has one less high priority process to contend with for CPU and I/O. - We start the preload after the core system services start up, since we know no 32 bit zygote processes will be requested before that point. - We start the preload ~1s before the webview factory preparation, to ensure that it completes before the 32 bit relro process is forked from the zygote. In the event that it takes too long, the webview RELRO process will block, but it will do so without holding any locks. I have not observed this happening in > 200 runs on marlin / sailfish devices. This change saves about 500ms in boot times, and sometimes even more. AFTER: successive-online : 16970.0,16668.0,16391.0,16498.0,17601.0,16736.0,16609.0,16820.0,16310.0,17557.0, successive-online_avg : 16816.0 successive-boot : 28750.0,29520.0,29372.0,28424.0,30683.0,28523.0,29766.0,29779.0,29304.0,31607.0, successive-boot_avg : 29572.8 BEFORE: successive-online : 16678.0,18105.0,17197.0,16744.0,17453.0,16946.0,18068.0,16719.0,17453.0,16942.0, successive-online_avg : 17230.5 successive-boot : 30855.0,32069.0,31223.0,30918.0,30284.0,29750.0,31036.0,30778.0,30310.0,30908.0, successive-boot_avg : 30813.1 Note that successive-online is a little faster, as expected since we do less work in the 32 bit zygote. Test: manual, timings from tradefed. Bug: 34810190 Change-Id: I90207a2706afda163b8134ff2af31f6917f3841b --- .../java/com/android/server/SystemServer.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 83e209dd5bbac..31c8261d0becd 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -35,6 +35,7 @@ import android.os.FileUtils; import android.os.IIncidentManager; import android.os.Looper; import android.os.PowerManager; +import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.StrictMode; @@ -236,6 +237,8 @@ public final class SystemServer { private static final String START_SENSOR_SERVICE = "StartSensorService"; private Future mSensorServiceStart; + private Future mZygotePreload; + /** * Start the sensor service. This is a blocking call and can take time. @@ -688,6 +691,26 @@ public final class SystemServer { } try { + final String SECONDARY_ZYGOTE_PRELOAD = "SecondaryZygotePreload"; + // We start the preload ~1s before the webview factory preparation, to + // ensure that it completes before the 32 bit relro process is forked + // from the zygote. In the event that it takes too long, the webview + // RELRO process will block, but it will do so without holding any locks. + mZygotePreload = SystemServerInitThreadPool.get().submit(() -> { + try { + Slog.i(TAG, SECONDARY_ZYGOTE_PRELOAD); + BootTimingsTraceLog traceLog = new BootTimingsTraceLog( + SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER); + traceLog.traceBegin(SECONDARY_ZYGOTE_PRELOAD); + if (!Process.zygoteProcess.preloadDefault(Build.SUPPORTED_32_BIT_ABIS[0])) { + Slog.e(TAG, "Unable to preload default resources"); + } + traceLog.traceEnd(); + } catch (Exception ex) { + Slog.e(TAG, "Exception preloading default resources", ex); + } + }, SECONDARY_ZYGOTE_PRELOAD); + traceBeginAndSlog("StartKeyAttestationApplicationIdProviderService"); ServiceManager.addService("sec_key_att_app_id_provider", new KeyAttestationApplicationIdProviderService(context)); @@ -1615,6 +1638,8 @@ public final class SystemServer { BootTimingsTraceLog traceLog = new BootTimingsTraceLog( SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER); traceLog.traceBegin(WEBVIEW_PREPARATION); + ConcurrentUtils.waitForFutureNoInterrupt(mZygotePreload, "Zygote preload"); + mZygotePreload = null; mWebViewUpdateService.prepareWebViewInSystemServer(); traceLog.traceEnd(); }, WEBVIEW_PREPARATION);