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.ActivityManager;
|
||||||
import android.app.ActivityThread;
|
import android.app.ActivityThread;
|
||||||
|
import android.app.ApplicationExitInfo;
|
||||||
import android.os.Debug;
|
import android.os.Debug;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
@@ -132,11 +133,15 @@ public final class CachedAppOptimizer {
|
|||||||
static final int REPORT_UNFREEZE_MSG = 4;
|
static final int REPORT_UNFREEZE_MSG = 4;
|
||||||
|
|
||||||
//TODO:change this static definition into a configurable flag.
|
//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 DO_FREEZE = 1;
|
||||||
static final int REPORT_UNFREEZE = 2;
|
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.
|
* 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.
|
* 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);
|
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
|
* Determines whether the freezer is supported by this system
|
||||||
*/
|
*/
|
||||||
@@ -729,6 +743,37 @@ public final class CachedAppOptimizer {
|
|||||||
return;
|
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;
|
long freezeTime = app.freezeUnfreezeTime;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -745,8 +790,12 @@ public final class CachedAppOptimizer {
|
|||||||
try {
|
try {
|
||||||
freezeBinder(app.pid, false);
|
freezeBinder(app.pid, false);
|
||||||
} catch (RuntimeException e) {
|
} 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) {
|
if (DEBUG_FREEZER) {
|
||||||
|
|||||||
@@ -36,6 +36,9 @@
|
|||||||
using android::base::StringPrintf;
|
using android::base::StringPrintf;
|
||||||
using android::base::WriteStringToFile;
|
using android::base::WriteStringToFile;
|
||||||
|
|
||||||
|
#define SYNC_RECEIVED_WHILE_FROZEN (1)
|
||||||
|
#define ASYNC_RECEIVED_WHILE_FROZEN (2)
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
// This performs per-process reclaim on all processes belonging to non-app UIDs.
|
// 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[] = {
|
static const JNINativeMethod sMethods[] = {
|
||||||
/* name, signature, funcPtr */
|
/* name, signature, funcPtr */
|
||||||
{"compactSystem", "()V", (void*)com_android_server_am_CachedAppOptimizer_compactSystem},
|
{"compactSystem", "()V", (void*)com_android_server_am_CachedAppOptimizer_compactSystem},
|
||||||
{"enableFreezerInternal", "(Z)V",
|
{"enableFreezerInternal", "(Z)V",
|
||||||
(void*)com_android_server_am_CachedAppOptimizer_enableFreezerInternal},
|
(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)
|
int register_android_server_am_CachedAppOptimizer(JNIEnv* env)
|
||||||
|
|||||||
Reference in New Issue
Block a user