Merge "Fix race between WM launching app and AMS freezer" into tm-dev am: 5d4c24ad33

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17087322

Change-Id: I140727d52a0ebce4cbbfba6e7a851448016c90bf
This commit is contained in:
Li Li
2022-03-07 22:56:45 +00:00
committed by Automerger Merge Worker
2 changed files with 49 additions and 4 deletions

View File

@@ -16999,6 +16999,15 @@ public class ActivityManagerService extends IActivityManager.Stub
@Override
public void addPendingTopUid(int uid, int pid) {
mPendingStartActivityUids.add(uid, pid);
// If the next top activity is in cached and frozen mode, WM should raise its priority
// to unfreeze it. This is done by calling AMS.updateOomAdj that will lower its oom adj.
// However, WM cannot hold the AMS clock here so the updateOomAdj operation is performed
// in a separate thread asynchronously. Therefore WM can't guarantee AMS will unfreeze
// next top activity on time. This race will fail the following binder transactions WM
// sends to the activity. After this race issue between WM/ATMS and AMS is solved, this
// workaround can be removed. (b/213288355)
mOomAdjuster.mCachedAppOptimizer.unfreezeProcess(pid);
}
@Override

View File

@@ -183,6 +183,8 @@ public final class CachedAppOptimizer {
private final ActivityManagerGlobalLock mProcLock;
private final Object mFreezerLock = new Object();
private final OnPropertiesChangedListener mOnFlagsChangedListener =
new OnPropertiesChangedListener() {
@Override
@@ -949,8 +951,8 @@ public final class CachedAppOptimizer {
}
}
@GuardedBy({"mAm", "mProcLock"})
void unfreezeAppLSP(ProcessRecord app) {
@GuardedBy({"mAm", "mProcLock", "mFreezerLock"})
void unfreezeAppInternalLSP(ProcessRecord app) {
final int pid = app.getPid();
final ProcessCachedOptimizerRecord opt = app.mOptRecord;
if (opt.isPendingFreeze()) {
@@ -1035,6 +1037,42 @@ public final class CachedAppOptimizer {
}
}
@GuardedBy({"mAm", "mProcLock"})
void unfreezeAppLSP(ProcessRecord app) {
synchronized (mFreezerLock) {
unfreezeAppInternalLSP(app);
}
}
/**
* This quick function works around the race condition between WM/ATMS and AMS, allowing
* the former to directly unfreeze a frozen process before the latter runs updateOomAdj.
* After the race issue is solved, this workaround can be removed. (b/213288355)
* @param pid pid of the process to be unfrozen
*/
@GuardedBy({"mFreezerLock"})
void unfreezeProcess(int pid) {
synchronized (mFreezerLock) {
ProcessRecord app = mFrozenProcesses.get(pid);
if (app == null) {
return;
}
Slog.i(TAG_AM, "quick sync unfreeze " + pid);
try {
freezeBinder(pid, false);
} catch (RuntimeException e) {
Slog.e(TAG_AM, "Unable to quick unfreeze binder for " + pid);
return;
}
try {
Process.setProcessFrozen(pid, app.uid, false);
} catch (Exception e) {
Slog.e(TAG_AM, "Unable to quick unfreeze " + pid);
}
}
}
/**
* To be called when the given app is killed.
*/
@@ -1464,8 +1502,6 @@ public final class CachedAppOptimizer {
return;
}
Slog.d(TAG_AM, "froze " + pid + " " + name);
EventLog.writeEvent(EventLogTags.AM_FREEZE, pid, name);
// See above for why we're not taking mPhenotypeFlagLock here