Merge "ActivityManager: kill frozen processes receiving sync transactions" into rvc-qpr-dev

This commit is contained in:
TreeHugger Robot
2020-09-18 16:27:16 +00:00
committed by Android (Google) Code Review
2 changed files with 81 additions and 4 deletions

View File

@@ -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.
@@ -493,6 +498,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
*/
@@ -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) {

View File

@@ -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)