Merge "ActivityManager: kill frozen processes receiving sync transactions" into rvc-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
acd04189d9
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user