diff options
| author | 2020-09-18 17:42:40 +0000 | |
|---|---|---|
| committer | 2020-09-18 17:42:40 +0000 | |
| commit | ca43ae658aa475ba4c83e543bf5cef08325cff14 (patch) | |
| tree | df0b7ea4b54c126deb66904a816e2514cfe94bd9 | |
| parent | ab2b198295c0e44d53213f8eba59e95d8302a495 (diff) | |
| parent | 00523e6c273c582588b40e5020301c58bca0a364 (diff) | |
Merge "ActivityManager: kill frozen processes receiving sync transactions" into rvc-qpr-dev am: acd04189d9 am: 00523e6c27
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/12568351
Change-Id: Ic904787a426b3ebf10f037544aa8a706529b3ab9
| -rw-r--r-- | services/core/java/com/android/server/am/CachedAppOptimizer.java | 55 | ||||
| -rw-r--r-- | services/core/jni/com_android_server_am_CachedAppOptimizer.cpp | 30 |
2 files changed, 81 insertions, 4 deletions
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index 966038986791..8112bb854b71 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -22,6 +22,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import android.app.ActivityManager; import android.app.ActivityThread; +import android.app.ApplicationExitInfo; import android.os.Debug; import android.os.Handler; import android.os.Message; @@ -132,11 +133,15 @@ public final class CachedAppOptimizer { static final int REPORT_UNFREEZE_MSG = 4; //TODO:change this static definition into a configurable flag. - static final int FREEZE_TIMEOUT_MS = 500; + static final int FREEZE_TIMEOUT_MS = 10000; static final int DO_FREEZE = 1; static final int REPORT_UNFREEZE = 2; + // Bitfield values for sync/async transactions reveived by frozen processes + static final int SYNC_RECEIVED_WHILE_FROZEN = 1; + static final int ASYNC_RECEIVED_WHILE_FROZEN = 2; + /** * This thread must be moved to the system background cpuset. * If that doesn't happen, it's probably going to draw a lot of power. @@ -494,6 +499,15 @@ public final class CachedAppOptimizer { private static native void freezeBinder(int pid, boolean freeze); /** + * Retrieves binder freeze info about a process. + * @param pid the pid for which binder freeze info is to be retrieved. + * + * @throws RuntimeException if the operation could not complete successfully. + * @return a bit field reporting the binder freeze info for the process. + */ + private static native int getBinderFreezeInfo(int pid); + + /** * Determines whether the freezer is supported by this system */ public static boolean isFreezerSupported() { @@ -729,6 +743,37 @@ public final class CachedAppOptimizer { return; } + boolean processKilled = false; + + try { + int freezeInfo = getBinderFreezeInfo(app.pid); + + if ((freezeInfo & SYNC_RECEIVED_WHILE_FROZEN) != 0) { + Slog.d(TAG_AM, "pid " + app.pid + " " + app.processName + " " + + " received sync transactions while frozen, killing"); + app.kill("Sync transaction while in frozen state", + ApplicationExitInfo.REASON_OTHER, + ApplicationExitInfo.SUBREASON_INVALID_STATE, true); + processKilled = true; + } + + if ((freezeInfo & ASYNC_RECEIVED_WHILE_FROZEN) != 0) { + Slog.d(TAG_AM, "pid " + app.pid + " " + app.processName + " " + + " received async transactions while frozen"); + } + } catch (Exception e) { + Slog.d(TAG_AM, "Unable to query binder frozen info for pid " + app.pid + " " + + app.processName + ". Killing it. Exception: " + e); + app.kill("Unable to query binder frozen stats", + ApplicationExitInfo.REASON_OTHER, + ApplicationExitInfo.SUBREASON_INVALID_STATE, true); + processKilled = true; + } + + if (processKilled) { + return; + } + long freezeTime = app.freezeUnfreezeTime; try { @@ -745,8 +790,12 @@ public final class CachedAppOptimizer { try { freezeBinder(app.pid, false); } catch (RuntimeException e) { - // TODO: it might be preferable to kill the target pid in this case - Slog.e(TAG_AM, "Unable to unfreeze binder for " + app.pid + " " + app.processName); + Slog.e(TAG_AM, "Unable to unfreeze binder for " + app.pid + " " + app.processName + + ". Killing it"); + app.kill("Unable to unfreeze", + ApplicationExitInfo.REASON_OTHER, + ApplicationExitInfo.SUBREASON_INVALID_STATE, true); + return; } if (DEBUG_FREEZER) { diff --git a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp index 95d4ba7c199a..678308af34ea 100644 --- a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp +++ b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp @@ -36,6 +36,9 @@ using android::base::StringPrintf; using android::base::WriteStringToFile; +#define SYNC_RECEIVED_WHILE_FROZEN (1) +#define ASYNC_RECEIVED_WHILE_FROZEN (2) + namespace android { // This performs per-process reclaim on all processes belonging to non-app UIDs. @@ -99,12 +102,37 @@ static void com_android_server_am_CachedAppOptimizer_freezeBinder( } } +static jint com_android_server_am_CachedAppOptimizer_getBinderFreezeInfo(JNIEnv *env, + jobject clazz, jint pid) { + bool syncReceived = false, asyncReceived = false; + + int error = IPCThreadState::getProcessFreezeInfo(pid, &syncReceived, &asyncReceived); + + if (error < 0) { + jniThrowException(env, "java/lang/RuntimeException", strerror(error)); + } + + jint retVal = 0; + + if(syncReceived) { + retVal |= SYNC_RECEIVED_WHILE_FROZEN;; + } + + if(asyncReceived) { + retVal |= ASYNC_RECEIVED_WHILE_FROZEN; + } + + return retVal; +} + static const JNINativeMethod sMethods[] = { /* name, signature, funcPtr */ {"compactSystem", "()V", (void*)com_android_server_am_CachedAppOptimizer_compactSystem}, {"enableFreezerInternal", "(Z)V", (void*)com_android_server_am_CachedAppOptimizer_enableFreezerInternal}, - {"freezeBinder", "(IZ)V", (void*)com_android_server_am_CachedAppOptimizer_freezeBinder} + {"freezeBinder", "(IZ)V", (void*)com_android_server_am_CachedAppOptimizer_freezeBinder}, + {"getBinderFreezeInfo", "(I)I", + (void*)com_android_server_am_CachedAppOptimizer_getBinderFreezeInfo} }; int register_android_server_am_CachedAppOptimizer(JNIEnv* env) |