summaryrefslogtreecommitdiffstats
path: root/libs/binder
diff options
context:
space:
mode:
authorChristopher Tate <ctate@google.com>2010-03-18 17:55:03 -0700
committerChristopher Tate <ctate@google.com>2010-03-18 18:13:57 -0700
commit7182ef360498b7f45cc5253c167bd9975cfc5335 (patch)
tree0cfd720f759df1398bdabe6d4a02811b0e5fe70d /libs/binder
parente5bdecea289a09070f0ea2a1067ae2a8f498098a (diff)
downloadframeworks_base-7182ef360498b7f45cc5253c167bd9975cfc5335.zip
frameworks_base-7182ef360498b7f45cc5253c167bd9975cfc5335.tar.gz
frameworks_base-7182ef360498b7f45cc5253c167bd9975cfc5335.tar.bz2
Ensure that binder incalls to the system process keep the fg cgroup
On binder incalls, the handler thread is given the caller's priority by the driver, but not the caller's cgroup. We have explicit code that sets the handler's cgroup to match the caller's, *except* that the system process explicitly disables this behavior. This led to a siuation in which we were running binder incalls to the system process at nice=10 but cgroup=fg. That's fine as far as it goes, except that if a GC happened in the handler thread, it would be promoted to foreground priority and cgroup both, to avoid having the GC take forever. Then, when GC finished, the original priority is reset, and the cgroup set *based on that priority*. This would push the handler thread into nice=10 cgroup=bg_non_interactive -- which matches the caller, but is supposed to be impossible in the system process. The end result of this was that we could be running "lengthy" operations in the system process in the background. Unfortunately, some of the operations that wound up like this would hold important global system locks for up to twenty seconds as a result, making the entire device unresponsive to input for that period. This CL fixes the binder incall setup to ensure that within the system process, a binder incall is always begun from the normal foreground priority as well as cgroup. In practice now the device still becomes laggy/sluggish when the offending lock-holding time-consuming incall occurs, but since it still runs as a foreground task it is able to proceed to completion within a short time rather than taking 20 seconds. Fixes bug #2403717 Change-Id: Id046aeabd0e80c48eef94accc37842835eab308d
Diffstat (limited to 'libs/binder')
-rw-r--r--libs/binder/IPCThreadState.cpp39
1 files changed, 21 insertions, 18 deletions
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 473f580..0016503 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -935,17 +935,27 @@ status_t IPCThreadState::executeCommand(int32_t cmd)
mCallingPid = tr.sender_pid;
mCallingUid = tr.sender_euid;
- bool doBackground = !gDisableBackgroundScheduling &&
- getpriority(PRIO_PROCESS, mMyThreadId)
- >= ANDROID_PRIORITY_BACKGROUND;
- if (doBackground) {
- // We have inherited a background priority from the caller.
- // Ensure this thread is in the background scheduling class,
- // since the driver won't modify scheduling classes for us.
- androidSetThreadSchedulingGroup(mMyThreadId,
- ANDROID_TGROUP_BG_NONINTERACT);
+ int curPrio = getpriority(PRIO_PROCESS, mMyThreadId);
+ if (gDisableBackgroundScheduling) {
+ if (curPrio > ANDROID_PRIORITY_NORMAL) {
+ // We have inherited a reduced priority from the caller, but do not
+ // want to run in that state in this process. The driver set our
+ // priority already (though not our scheduling class), so bounce
+ // it back to the default before invoking the transaction.
+ setpriority(PRIO_PROCESS, mMyThreadId, ANDROID_PRIORITY_NORMAL);
+ }
+ } else {
+ if (curPrio >= ANDROID_PRIORITY_BACKGROUND) {
+ // We want to use the inherited priority from the caller.
+ // Ensure this thread is in the background scheduling class,
+ // since the driver won't modify scheduling classes for us.
+ // The scheduling group is reset to default by the caller
+ // once this method returns after the transaction is complete.
+ androidSetThreadSchedulingGroup(mMyThreadId,
+ ANDROID_TGROUP_BG_NONINTERACT);
+ }
}
-
+
//LOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
Parcel reply;
@@ -982,14 +992,7 @@ status_t IPCThreadState::executeCommand(int32_t cmd)
mCallingPid = origPid;
mCallingUid = origUid;
-
- if (doBackground) {
- // We moved to the background scheduling group to execute
- // this transaction, so now that we are done go back in the
- // foreground.
- androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);
- }
-
+
IF_LOG_TRANSACTIONS() {
TextOutput::Bundle _b(alog);
alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "