summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Christopher Tate <ctate@google.com> 2019-06-14 11:09:26 -0700
committer Christopher Tate <ctate@google.com> 2019-06-25 17:38:47 -0700
commitc2c19c9a65b479a23f0cf6ef23f72b311f1b8374 (patch)
treed47c61d63d2257fc19149d65d7059ef892ef5948
parent15f4e21d0e756b89ad821e29a5db0845a2768227 (diff)
Defer PSS collection while an activity is starting
Make sure not to process any requested PSS collections for a brief time after an activity start is initiated, to reduce resource contention during the launch. Device config atom to configure: ActivityManager/activity_start_pss_defer Milliseconds; defaults to zero (PSS deferral policy disabled) Bug: 133433769 Test: manual Change-Id: Icf5cf2e3dde0bd5fd3ab9c4a85adfb1f3382057f
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java131
1 files changed, 130 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f451a094e007..4222fc142fa4 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -272,6 +272,7 @@ import android.os.storage.IStorageManager;
import android.os.storage.StorageManager;
import android.provider.DeviceConfig;
import android.provider.Settings;
+import android.provider.DeviceConfig.Properties;
import android.server.ServerProtoEnums;
import android.sysprop.VoldProperties;
import android.text.TextUtils;
@@ -356,6 +357,7 @@ import com.android.server.uri.UriGrantsManagerInternal;
import com.android.server.utils.PriorityDump;
import com.android.server.utils.TimingsTraceAndSlog;
import com.android.server.vr.VrManagerInternal;
+import com.android.server.wm.ActivityMetricsLaunchObserver;
import com.android.server.wm.ActivityServiceConnectionsHolder;
import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.ActivityTaskManagerService;
@@ -392,6 +394,7 @@ import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.BiFunction;
@@ -861,6 +864,51 @@ public class ActivityManagerService extends IActivityManager.Stub
*/
final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
+ /**
+ * Depth of overlapping activity-start PSS deferral notes
+ */
+ private final AtomicInteger mActivityStartingNesting = new AtomicInteger(0);
+
+ private final ActivityMetricsLaunchObserver mActivityLaunchObserver =
+ new ActivityMetricsLaunchObserver() {
+ @Override
+ public void onActivityLaunched(byte[] activity, int temperature) {
+ // This is safe to force to the head of the queue because it relies only
+ // on refcounting to track begin/end of deferrals, not on actual
+ // message ordering. We don't care *what* activity is being
+ // launched; only that we're doing so.
+ if (mPssDeferralTime > 0) {
+ final Message msg = mBgHandler.obtainMessage(DEFER_PSS_MSG);
+ mBgHandler.sendMessageAtFrontOfQueue(msg);
+ }
+ }
+
+ // The other observer methods are unused
+ @Override
+ public void onIntentStarted(Intent intent) {
+ }
+
+ @Override
+ public void onIntentFailed() {
+ }
+
+ @Override
+ public void onActivityLaunchCancelled(byte[] abortingActivity) {
+ }
+
+ @Override
+ public void onActivityLaunchFinished(byte[] finalActivity) {
+ }
+ };
+
+ /**
+ * How long we defer PSS gathering while activities are starting, in milliseconds.
+ * This is adjustable via DeviceConfig. If it is zero or negative, no PSS deferral
+ * is done.
+ */
+ private volatile long mPssDeferralTime = 0;
+ private static final String ACTIVITY_START_PSS_DEFER_CONFIG = "activity_start_pss_defer";
+
private boolean mBinderTransactionTrackingEnabled = false;
/**
@@ -874,6 +922,20 @@ public class ActivityManagerService extends IActivityManager.Stub
*/
boolean mFullPssPending = false;
+ /**
+ * Observe DeviceConfig changes to the PSS calculation interval
+ */
+ private final DeviceConfig.OnPropertiesChangedListener mPssDelayConfigListener =
+ new DeviceConfig.OnPropertiesChangedListener() {
+ @Override
+ public void onPropertiesChanged(Properties properties) {
+ mPssDeferralTime = properties.getLong(ACTIVITY_START_PSS_DEFER_CONFIG, 0);
+ if (DEBUG_PSS) {
+ Slog.d(TAG_PSS, "Activity-start PSS delay now "
+ + mPssDeferralTime + " ms");
+ }
+ }
+ };
/**
* This is for verifying the UID report flow.
@@ -1838,6 +1900,8 @@ public class ActivityManagerService extends IActivityManager.Stub
}
static final int COLLECT_PSS_BG_MSG = 1;
+ static final int DEFER_PSS_MSG = 2;
+ static final int STOP_DEFERRING_PSS_MSG = 3;
final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
@Override
@@ -1945,6 +2009,30 @@ public class ActivityManagerService extends IActivityManager.Stub
}
} while (true);
}
+
+ case DEFER_PSS_MSG: {
+ deferPssForActivityStart();
+ } break;
+
+ case STOP_DEFERRING_PSS_MSG: {
+ final int nesting = mActivityStartingNesting.decrementAndGet();
+ if (nesting <= 0) {
+ if (DEBUG_PSS) {
+ Slog.d(TAG_PSS, "PSS activity start deferral interval ended; now "
+ + nesting);
+ }
+ if (nesting < 0) {
+ Slog.wtf(TAG, "Activity start nesting undercount!");
+ mActivityStartingNesting.incrementAndGet();
+ }
+ } else {
+ if (DEBUG_PSS) {
+ Slog.d(TAG_PSS, "Still deferring PSS, nesting=" + nesting);
+ }
+ }
+ }
+ break;
+
}
}
};
@@ -8832,6 +8920,12 @@ public class ActivityManagerService extends IActivityManager.Stub
NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
mHiddenApiBlacklist.registerObserver();
+ final long pssDeferralMs = DeviceConfig.getLong(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ ACTIVITY_START_PSS_DEFER_CONFIG, 0L);
+ DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ ActivityThread.currentApplication().getMainExecutor(),
+ mPssDelayConfigListener);
+
synchronized (this) {
mDebugApp = mOrigDebugApp = debugApp;
mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
@@ -8848,6 +8942,7 @@ public class ActivityManagerService extends IActivityManager.Stub
com.android.internal.R.bool.config_multiuserDelayUserDataLocking);
mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
+ mPssDeferralTime = pssDeferralMs;
}
}
@@ -8921,6 +9016,10 @@ public class ActivityManagerService extends IActivityManager.Stub
mAtmInternal.updateTopComponentForFactoryTest();
t.traceEnd();
+ t.traceBegin("registerActivityLaunchObserver");
+ mAtmInternal.getLaunchObserverRegistry().registerLaunchObserver(mActivityLaunchObserver);
+ t.traceEnd();
+
t.traceBegin("watchDeviceProvisioning");
watchDeviceProvisioning(mContext);
t.traceEnd();
@@ -16177,7 +16276,13 @@ public class ActivityManagerService extends IActivityManager.Stub
return false;
}
if (mPendingPssProcesses.size() == 0) {
- mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
+ final long deferral = (mPssDeferralTime > 0 && mActivityStartingNesting.get() > 0)
+ ? mPssDeferralTime : 0;
+ if (DEBUG_PSS && deferral > 0) {
+ Slog.d(TAG_PSS, "requestPssLocked() deferring PSS request by "
+ + deferral + " ms");
+ }
+ mBgHandler.sendEmptyMessageDelayed(COLLECT_PSS_BG_MSG, deferral);
}
if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of: " + proc);
proc.pssProcState = procState;
@@ -16187,6 +16292,30 @@ public class ActivityManagerService extends IActivityManager.Stub
}
/**
+ * Re-defer a posted PSS collection pass, if one exists. Assumes deferral is
+ * currently active policy when called.
+ */
+ private void deferPssIfNeededLocked() {
+ if (mPendingPssProcesses.size() > 0) {
+ mBgHandler.removeMessages(COLLECT_PSS_BG_MSG);
+ mBgHandler.sendEmptyMessageDelayed(COLLECT_PSS_BG_MSG, mPssDeferralTime);
+ }
+ }
+
+ private void deferPssForActivityStart() {
+ synchronized (ActivityManagerService.this) {
+ if (mPssDeferralTime > 0) {
+ if (DEBUG_PSS) {
+ Slog.d(TAG_PSS, "Deferring PSS collection for activity start");
+ }
+ deferPssIfNeededLocked();
+ mActivityStartingNesting.getAndIncrement();
+ mBgHandler.sendEmptyMessageDelayed(STOP_DEFERRING_PSS_MSG, mPssDeferralTime);
+ }
+ }
+ }
+
+ /**
* Schedule PSS collection of all processes.
*/
void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {