From 05f4679d035b8ff8023e75f58b576518b8c3f064 Mon Sep 17 00:00:00 2001 From: Tim Murray Date: Tue, 7 Mar 2017 09:31:09 -0800 Subject: [PATCH] binder: remove cgroup interactions [ DO NOT MERGE ] Having binder change cgroups on the fly is too expensive in the common case to be useful. Test: builds bug 34825105 Change-Id: Ia692c9d2ab261d852cb2fac8f27d6779d0e2b057 --- include/binder/IPCThreadState.h | 1 - libs/binder/IPCThreadState.cpp | 162 ++++++++++++++++------------------------ 2 files changed, 64 insertions(+), 99 deletions(-) diff --git a/include/binder/IPCThreadState.h b/include/binder/IPCThreadState.h index 1853cff235..7b826d6dcd 100644 --- a/include/binder/IPCThreadState.h +++ b/include/binder/IPCThreadState.h @@ -115,7 +115,6 @@ private: void* cookie); const sp mProcess; - const pid_t mMyThreadId; Vector mPendingStrongDerefs; Vector mPendingWeakDerefs; diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp index d90798f51e..eccc400c09 100644 --- a/libs/binder/IPCThreadState.cpp +++ b/libs/binder/IPCThreadState.cpp @@ -46,6 +46,7 @@ #define IF_LOG_COMMANDS() if (false) #define LOG_REMOTEREFS(...) #define IF_LOG_REMOTEREFS() if (false) + #define LOG_THREADPOOL(...) #define LOG_ONEWAY(...) @@ -152,7 +153,7 @@ static const void* printReturnCommand(TextOutput& out, const void* _cmd) return cmd; } out << kReturnStrings[cmdIndex]; - + switch (code) { case BR_TRANSACTION: case BR_REPLY: { @@ -160,12 +161,12 @@ static const void* printReturnCommand(TextOutput& out, const void* _cmd) cmd = (const int32_t *)printBinderTransactionData(out, cmd); out << dedent; } break; - + case BR_ACQUIRE_RESULT: { const int32_t res = *cmd++; out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)"); } break; - + case BR_INCREFS: case BR_ACQUIRE: case BR_RELEASE: @@ -174,7 +175,7 @@ static const void* printReturnCommand(TextOutput& out, const void* _cmd) const int32_t c = *cmd++; out << ": target=" << (void*)(long)b << " (cookie " << (void*)(long)c << ")"; } break; - + case BR_ATTEMPT_ACQUIRE: { const int32_t p = *cmd++; const int32_t b = *cmd++; @@ -194,7 +195,7 @@ static const void* printReturnCommand(TextOutput& out, const void* _cmd) // BR_TRANSACTION_COMPLETE, BR_FINISHED break; } - + out << endl; return cmd; } @@ -219,17 +220,17 @@ static const void* printCommand(TextOutput& out, const void* _cmd) cmd = (const int32_t *)printBinderTransactionData(out, cmd); out << dedent; } break; - + case BC_ACQUIRE_RESULT: { const int32_t res = *cmd++; out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)"); } break; - + case BC_FREE_BUFFER: { const int32_t buf = *cmd++; out << ": buffer=" << (void*)(long)buf; } break; - + case BC_INCREFS: case BC_ACQUIRE: case BC_RELEASE: @@ -237,20 +238,20 @@ static const void* printCommand(TextOutput& out, const void* _cmd) const int32_t d = *cmd++; out << ": desc=" << d; } break; - + case BC_INCREFS_DONE: case BC_ACQUIRE_DONE: { const int32_t b = *cmd++; const int32_t c = *cmd++; out << ": target=" << (void*)(long)b << " (cookie " << (void*)(long)c << ")"; } break; - + case BC_ATTEMPT_ACQUIRE: { const int32_t p = *cmd++; const int32_t d = *cmd++; out << ": desc=" << d << ", pri=" << p; } break; - + case BC_REQUEST_DEATH_NOTIFICATION: case BC_CLEAR_DEATH_NOTIFICATION: { const int32_t h = *cmd++; @@ -268,7 +269,7 @@ static const void* printCommand(TextOutput& out, const void* _cmd) // BC_EXIT_LOOPER break; } - + out << endl; return cmd; } @@ -288,12 +289,12 @@ restart: if (st) return st; return new IPCThreadState; } - + if (gShutdown) { ALOGW("Calling IPCThreadState::self() during shutdown is dangerous, expect a crash.\n"); return NULL; } - + pthread_mutex_lock(&gTLSMutex); if (!gHaveTLS) { int key_create_value = pthread_key_create(&gTLS, threadDestructor); @@ -322,7 +323,7 @@ IPCThreadState* IPCThreadState::selfOrNull() void IPCThreadState::shutdown() { gShutdown = true; - + if (gHaveTLS) { // XXX Need to wait for all thread pool threads to exit! IPCThreadState* st = (IPCThreadState*)pthread_getspecific(gTLS); @@ -457,15 +458,6 @@ status_t IPCThreadState::getAndExecuteCommand() } pthread_cond_broadcast(&mProcess->mThreadCountDecrement); pthread_mutex_unlock(&mProcess->mThreadCountLock); - - // After executing the command, ensure that the thread is returned to the - // foreground cgroup before rejoining the pool. The driver takes care of - // restoring the priority, but doesn't do anything with cgroups so we - // need to take care of that here in userspace. Note that we do make - // sure to go in the foreground after executing a transaction, but - // there are other callbacks into user code that could have changed - // our group so we want to make absolutely sure it is put back. - set_sched_policy(mMyThreadId, SP_FOREGROUND); } return result; @@ -500,12 +492,7 @@ void IPCThreadState::joinThreadPool(bool isMain) LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid()); mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER); - - // This thread may have been spawned by a thread that was in the background - // scheduling group, so first we will make sure it is in the foreground - // one to avoid performing an initial transaction in the background. - set_sched_policy(mMyThreadId, SP_FOREGROUND); - + status_t result; do { processPendingDerefs(); @@ -517,7 +504,7 @@ void IPCThreadState::joinThreadPool(bool isMain) mProcess->mDriverFD, result); abort(); } - + // Let this thread exit the thread pool if it is no longer // needed and it is not the main process thread. if(result == TIMED_OUT && !isMain) { @@ -580,18 +567,18 @@ status_t IPCThreadState::transact(int32_t handle, << handle << " / code " << TypeCode(code) << ": " << indent << data << dedent << endl; } - + if (err == NO_ERROR) { LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(), (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY"); err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL); } - + if (err != NO_ERROR) { if (reply) reply->setError(err); return (mLastError = err); } - + if ((flags & TF_ONE_WAY) == 0) { #if 0 if (code == 4) { // relayout @@ -613,7 +600,7 @@ status_t IPCThreadState::transact(int32_t handle, ALOGI("<<<<<< RETURNING transaction %d", code); } #endif - + IF_LOG_TRANSACTIONS() { TextOutput::Bundle _b(alog); alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand " @@ -624,7 +611,7 @@ status_t IPCThreadState::transact(int32_t handle, } else { err = waitForResponse(NULL, NULL); } - + return err; } @@ -664,14 +651,14 @@ status_t IPCThreadState::attemptIncStrongHandle(int32_t handle) mOut.writeInt32(0); // xxx was thread priority mOut.writeInt32(handle); status_t result = UNKNOWN_ERROR; - + waitForResponse(NULL, &result); - + #if LOG_REFCOUNTS printf("IPCThreadState::attemptIncStrongHandle(%ld) = %s\n", handle, result == NO_ERROR ? "SUCCESS" : "FAILURE"); #endif - + return result; #else (void)handle; @@ -706,7 +693,6 @@ status_t IPCThreadState::clearDeathNotification(int32_t handle, BpBinder* proxy) IPCThreadState::IPCThreadState() : mProcess(ProcessState::self()), - mMyThreadId(gettid()), mStrictModePolicy(0), mLastTransactionBinderFlags(0) { @@ -726,7 +712,7 @@ status_t IPCThreadState::sendReply(const Parcel& reply, uint32_t flags) status_t statusBuffer; err = writeTransactionData(BC_REPLY, flags, -1, 0, reply, &statusBuffer); if (err < NO_ERROR) return err; - + return waitForResponse(NULL, NULL); } @@ -740,9 +726,9 @@ status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult) err = mIn.errorCheck(); if (err < NO_ERROR) break; if (mIn.dataAvail() == 0) continue; - + cmd = (uint32_t)mIn.readInt32(); - + IF_LOG_COMMANDS() { alog << "Processing waitForResponse Command: " << getReturnString(cmd) << endl; @@ -752,7 +738,7 @@ status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult) case BR_TRANSACTION_COMPLETE: if (!reply && !acquireResult) goto finish; break; - + case BR_DEAD_REPLY: err = DEAD_OBJECT; goto finish; @@ -760,7 +746,7 @@ status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult) case BR_FAILED_REPLY: err = FAILED_TRANSACTION; goto finish; - + case BR_ACQUIRE_RESULT: { ALOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT"); @@ -769,7 +755,7 @@ status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult) *acquireResult = result ? NO_ERROR : INVALID_OPERATION; } goto finish; - + case BR_REPLY: { binder_transaction_data tr; @@ -817,7 +803,7 @@ finish: if (reply) reply->setError(err); mLastError = err; } - + return err; } @@ -826,17 +812,17 @@ status_t IPCThreadState::talkWithDriver(bool doReceive) if (mProcess->mDriverFD <= 0) { return -EBADF; } - + binder_write_read bwr; - + // Is the read buffer empty? const bool needRead = mIn.dataPosition() >= mIn.dataSize(); - + // We don't want to write anything if we are still reading // from data left in the input buffer and the caller // has requested to read the next data. const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0; - + bwr.write_size = outAvail; bwr.write_buffer = (uintptr_t)mOut.data(); @@ -862,7 +848,7 @@ status_t IPCThreadState::talkWithDriver(bool doReceive) alog << "Size of receive buffer: " << bwr.read_size << ", needRead: " << needRead << ", doReceive: " << doReceive << endl; } - + // Return immediately if there is nothing to do. if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR; @@ -918,7 +904,7 @@ status_t IPCThreadState::talkWithDriver(bool doReceive) } return NO_ERROR; } - + return err; } @@ -934,7 +920,7 @@ status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags, tr.cookie = 0; tr.sender_pid = 0; tr.sender_euid = 0; - + const status_t err = data.errorCheck(); if (err == NO_ERROR) { tr.data_size = data.ipcDataSize(); @@ -951,10 +937,10 @@ status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags, } else { return (mLastError = err); } - + mOut.writeInt32(cmd); mOut.write(&tr, sizeof(tr)); - + return NO_ERROR; } @@ -970,15 +956,15 @@ status_t IPCThreadState::executeCommand(int32_t cmd) BBinder* obj; RefBase::weakref_type* refs; status_t result = NO_ERROR; - + switch ((uint32_t)cmd) { case BR_ERROR: result = mIn.readInt32(); break; - + case BR_OK: break; - + case BR_ACQUIRE: refs = (RefBase::weakref_type*)mIn.readPointer(); obj = (BBinder*)mIn.readPointer(); @@ -994,7 +980,7 @@ status_t IPCThreadState::executeCommand(int32_t cmd) mOut.writePointer((uintptr_t)refs); mOut.writePointer((uintptr_t)obj); break; - + case BR_RELEASE: refs = (RefBase::weakref_type*)mIn.readPointer(); obj = (BBinder*)mIn.readPointer(); @@ -1007,7 +993,7 @@ status_t IPCThreadState::executeCommand(int32_t cmd) } mPendingStrongDerefs.push(obj); break; - + case BR_INCREFS: refs = (RefBase::weakref_type*)mIn.readPointer(); obj = (BBinder*)mIn.readPointer(); @@ -1016,7 +1002,7 @@ status_t IPCThreadState::executeCommand(int32_t cmd) mOut.writePointer((uintptr_t)refs); mOut.writePointer((uintptr_t)obj); break; - + case BR_DECREFS: refs = (RefBase::weakref_type*)mIn.readPointer(); obj = (BBinder*)mIn.readPointer(); @@ -1028,22 +1014,22 @@ status_t IPCThreadState::executeCommand(int32_t cmd) // refs, obj, refs->refBase()); mPendingWeakDerefs.push(refs); break; - + case BR_ATTEMPT_ACQUIRE: refs = (RefBase::weakref_type*)mIn.readPointer(); obj = (BBinder*)mIn.readPointer(); - + { const bool success = refs->attemptIncStrong(mProcess.get()); ALOG_ASSERT(success && refs->refBase() == obj, "BR_ATTEMPT_ACQUIRE: object %p does not match cookie %p (expected %p)", refs, obj, refs->refBase()); - + mOut.writeInt32(BC_ACQUIRE_RESULT); mOut.writeInt32((int32_t)success); } break; - + case BR_TRANSACTION: { binder_transaction_data tr; @@ -1051,14 +1037,14 @@ status_t IPCThreadState::executeCommand(int32_t cmd) ALOG_ASSERT(result == NO_ERROR, "Not enough command data for brTRANSACTION"); if (result != NO_ERROR) break; - + Parcel buffer; buffer.ipcSetDataReference( reinterpret_cast(tr.data.ptr.buffer), tr.data_size, reinterpret_cast(tr.data.ptr.offsets), tr.offsets_size/sizeof(binder_size_t), freeBuffer, this); - + const pid_t origPid = mCallingPid; const uid_t origUid = mCallingUid; const int32_t origStrictModePolicy = mStrictModePolicy; @@ -1068,26 +1054,6 @@ status_t IPCThreadState::executeCommand(int32_t cmd) mCallingUid = tr.sender_euid; mLastTransactionBinderFlags = tr.flags; - 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. - set_sched_policy(mMyThreadId, SP_BACKGROUND); - } - } - //ALOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid); Parcel reply; @@ -1121,7 +1087,7 @@ status_t IPCThreadState::executeCommand(int32_t cmd) //ALOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n", // mCallingPid, origPid, origUid); - + if ((tr.flags & TF_ONE_WAY) == 0) { LOG_ONEWAY("Sending reply to %d!", mCallingPid); if (error < NO_ERROR) reply.setError(error); @@ -1129,7 +1095,7 @@ status_t IPCThreadState::executeCommand(int32_t cmd) } else { LOG_ONEWAY("NOT sending reply to %d!", mCallingPid); } - + mCallingPid = origPid; mCallingUid = origUid; mStrictModePolicy = origStrictModePolicy; @@ -1140,10 +1106,10 @@ status_t IPCThreadState::executeCommand(int32_t cmd) alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj " << tr.target.ptr << ": " << indent << reply << dedent << endl; } - + } break; - + case BR_DEAD_BINDER: { BpBinder *proxy = (BpBinder*)mIn.readPointer(); @@ -1151,24 +1117,24 @@ status_t IPCThreadState::executeCommand(int32_t cmd) mOut.writeInt32(BC_DEAD_BINDER_DONE); mOut.writePointer((uintptr_t)proxy); } break; - + case BR_CLEAR_DEATH_NOTIFICATION_DONE: { BpBinder *proxy = (BpBinder*)mIn.readPointer(); proxy->getWeakRefs()->decWeak(proxy); } break; - + case BR_FINISHED: result = TIMED_OUT; break; - + case BR_NOOP: break; - + case BR_SPAWN_LOOPER: mProcess->spawnPooledThread(false); break; - + default: printf("*** BAD COMMAND %d received from Binder driver\n", cmd); result = UNKNOWN_ERROR; @@ -1178,7 +1144,7 @@ status_t IPCThreadState::executeCommand(int32_t cmd) if (result != NO_ERROR) { mLastError = result; } - + return result; } -- 2.11.0