Loading services/core/java/com/android/server/am/ActivityManagerService.java +9 −0 Original line number Diff line number Diff line Loading @@ -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 services/core/java/com/android/server/am/CachedAppOptimizer.java +40 −4 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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()) { Loading Loading @@ -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. */ Loading Loading @@ -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 Loading Loading
services/core/java/com/android/server/am/ActivityManagerService.java +9 −0 Original line number Diff line number Diff line Loading @@ -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
services/core/java/com/android/server/am/CachedAppOptimizer.java +40 −4 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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()) { Loading Loading @@ -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. */ Loading Loading @@ -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 Loading