1*77b80299SAndroid Build Coastguard Worker /*
2*77b80299SAndroid Build Coastguard Worker * Copyright (C) 2005 The Android Open Source Project
3*77b80299SAndroid Build Coastguard Worker *
4*77b80299SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*77b80299SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*77b80299SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*77b80299SAndroid Build Coastguard Worker *
8*77b80299SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*77b80299SAndroid Build Coastguard Worker *
10*77b80299SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*77b80299SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*77b80299SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*77b80299SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*77b80299SAndroid Build Coastguard Worker * limitations under the License.
15*77b80299SAndroid Build Coastguard Worker */
16*77b80299SAndroid Build Coastguard Worker
17*77b80299SAndroid Build Coastguard Worker #define LOG_TAG "hw-ProcessState"
18*77b80299SAndroid Build Coastguard Worker
19*77b80299SAndroid Build Coastguard Worker #include <hwbinder/ProcessState.h>
20*77b80299SAndroid Build Coastguard Worker
21*77b80299SAndroid Build Coastguard Worker #include <cutils/atomic.h>
22*77b80299SAndroid Build Coastguard Worker #include <hwbinder/HidlSupport.h>
23*77b80299SAndroid Build Coastguard Worker #include <hwbinder/BpHwBinder.h>
24*77b80299SAndroid Build Coastguard Worker #include <hwbinder/IPCThreadState.h>
25*77b80299SAndroid Build Coastguard Worker #include <utils/Log.h>
26*77b80299SAndroid Build Coastguard Worker #include <utils/String8.h>
27*77b80299SAndroid Build Coastguard Worker #include <utils/threads.h>
28*77b80299SAndroid Build Coastguard Worker
29*77b80299SAndroid Build Coastguard Worker #include "binder_kernel.h"
30*77b80299SAndroid Build Coastguard Worker #include <hwbinder/Static.h>
31*77b80299SAndroid Build Coastguard Worker
32*77b80299SAndroid Build Coastguard Worker #include <errno.h>
33*77b80299SAndroid Build Coastguard Worker #include <fcntl.h>
34*77b80299SAndroid Build Coastguard Worker #include <stdio.h>
35*77b80299SAndroid Build Coastguard Worker #include <stdlib.h>
36*77b80299SAndroid Build Coastguard Worker #include <unistd.h>
37*77b80299SAndroid Build Coastguard Worker #include <sys/ioctl.h>
38*77b80299SAndroid Build Coastguard Worker #include <sys/mman.h>
39*77b80299SAndroid Build Coastguard Worker #include <sys/stat.h>
40*77b80299SAndroid Build Coastguard Worker #include <sys/types.h>
41*77b80299SAndroid Build Coastguard Worker
42*77b80299SAndroid Build Coastguard Worker #include <mutex>
43*77b80299SAndroid Build Coastguard Worker
44*77b80299SAndroid Build Coastguard Worker #define DEFAULT_BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2)
45*77b80299SAndroid Build Coastguard Worker #define DEFAULT_MAX_BINDER_THREADS 0
46*77b80299SAndroid Build Coastguard Worker #define DEFAULT_ENABLE_ONEWAY_SPAM_DETECTION 1
47*77b80299SAndroid Build Coastguard Worker
48*77b80299SAndroid Build Coastguard Worker // -------------------------------------------------------------------------
49*77b80299SAndroid Build Coastguard Worker
50*77b80299SAndroid Build Coastguard Worker namespace android {
51*77b80299SAndroid Build Coastguard Worker namespace hardware {
52*77b80299SAndroid Build Coastguard Worker
53*77b80299SAndroid Build Coastguard Worker class PoolThread : public Thread
54*77b80299SAndroid Build Coastguard Worker {
55*77b80299SAndroid Build Coastguard Worker public:
PoolThread(bool isMain)56*77b80299SAndroid Build Coastguard Worker explicit PoolThread(bool isMain)
57*77b80299SAndroid Build Coastguard Worker : mIsMain(isMain)
58*77b80299SAndroid Build Coastguard Worker {
59*77b80299SAndroid Build Coastguard Worker }
60*77b80299SAndroid Build Coastguard Worker
61*77b80299SAndroid Build Coastguard Worker protected:
threadLoop()62*77b80299SAndroid Build Coastguard Worker virtual bool threadLoop()
63*77b80299SAndroid Build Coastguard Worker {
64*77b80299SAndroid Build Coastguard Worker IPCThreadState::self()->joinThreadPool(mIsMain);
65*77b80299SAndroid Build Coastguard Worker return false;
66*77b80299SAndroid Build Coastguard Worker }
67*77b80299SAndroid Build Coastguard Worker
68*77b80299SAndroid Build Coastguard Worker const bool mIsMain;
69*77b80299SAndroid Build Coastguard Worker };
70*77b80299SAndroid Build Coastguard Worker
self()71*77b80299SAndroid Build Coastguard Worker sp<ProcessState> ProcessState::self()
72*77b80299SAndroid Build Coastguard Worker {
73*77b80299SAndroid Build Coastguard Worker return init(DEFAULT_BINDER_VM_SIZE, false /*requireMmapSize*/);
74*77b80299SAndroid Build Coastguard Worker }
75*77b80299SAndroid Build Coastguard Worker
selfOrNull()76*77b80299SAndroid Build Coastguard Worker sp<ProcessState> ProcessState::selfOrNull() {
77*77b80299SAndroid Build Coastguard Worker return init(0, false /*requireMmapSize*/);
78*77b80299SAndroid Build Coastguard Worker }
79*77b80299SAndroid Build Coastguard Worker
initWithMmapSize(size_t mmapSize)80*77b80299SAndroid Build Coastguard Worker sp<ProcessState> ProcessState::initWithMmapSize(size_t mmapSize) {
81*77b80299SAndroid Build Coastguard Worker return init(mmapSize, true /*requireMmapSize*/);
82*77b80299SAndroid Build Coastguard Worker }
83*77b80299SAndroid Build Coastguard Worker
init(size_t mmapSize,bool requireMmapSize)84*77b80299SAndroid Build Coastguard Worker sp<ProcessState> ProcessState::init(size_t mmapSize, bool requireMmapSize) {
85*77b80299SAndroid Build Coastguard Worker [[clang::no_destroy]] static sp<ProcessState> gProcess;
86*77b80299SAndroid Build Coastguard Worker [[clang::no_destroy]] static std::mutex gProcessMutex;
87*77b80299SAndroid Build Coastguard Worker
88*77b80299SAndroid Build Coastguard Worker if (mmapSize == 0) {
89*77b80299SAndroid Build Coastguard Worker std::lock_guard<std::mutex> l(gProcessMutex);
90*77b80299SAndroid Build Coastguard Worker return gProcess;
91*77b80299SAndroid Build Coastguard Worker }
92*77b80299SAndroid Build Coastguard Worker
93*77b80299SAndroid Build Coastguard Worker [[clang::no_destroy]] static std::once_flag gProcessOnce;
94*77b80299SAndroid Build Coastguard Worker std::call_once(gProcessOnce, [&](){
95*77b80299SAndroid Build Coastguard Worker std::lock_guard<std::mutex> l(gProcessMutex);
96*77b80299SAndroid Build Coastguard Worker gProcess = new ProcessState(mmapSize);
97*77b80299SAndroid Build Coastguard Worker });
98*77b80299SAndroid Build Coastguard Worker
99*77b80299SAndroid Build Coastguard Worker if (requireMmapSize) {
100*77b80299SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(mmapSize != gProcess->getMmapSize(),
101*77b80299SAndroid Build Coastguard Worker "ProcessState already initialized with a different mmap size.");
102*77b80299SAndroid Build Coastguard Worker }
103*77b80299SAndroid Build Coastguard Worker
104*77b80299SAndroid Build Coastguard Worker return gProcess;
105*77b80299SAndroid Build Coastguard Worker }
106*77b80299SAndroid Build Coastguard Worker
startThreadPool()107*77b80299SAndroid Build Coastguard Worker void ProcessState::startThreadPool()
108*77b80299SAndroid Build Coastguard Worker {
109*77b80299SAndroid Build Coastguard Worker if (!isHwbinderSupportedBlocking()) {
110*77b80299SAndroid Build Coastguard Worker ALOGW("HwBinder is not supported on this device but this process is calling startThreadPool");
111*77b80299SAndroid Build Coastguard Worker }
112*77b80299SAndroid Build Coastguard Worker AutoMutex _l(mLock);
113*77b80299SAndroid Build Coastguard Worker if (!mThreadPoolStarted) {
114*77b80299SAndroid Build Coastguard Worker mThreadPoolStarted = true;
115*77b80299SAndroid Build Coastguard Worker if (mSpawnThreadOnStart) {
116*77b80299SAndroid Build Coastguard Worker spawnPooledThread(true);
117*77b80299SAndroid Build Coastguard Worker }
118*77b80299SAndroid Build Coastguard Worker }
119*77b80299SAndroid Build Coastguard Worker }
120*77b80299SAndroid Build Coastguard Worker
getContextObject(const sp<IBinder> &)121*77b80299SAndroid Build Coastguard Worker sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
122*77b80299SAndroid Build Coastguard Worker {
123*77b80299SAndroid Build Coastguard Worker return getStrongProxyForHandle(0);
124*77b80299SAndroid Build Coastguard Worker }
125*77b80299SAndroid Build Coastguard Worker
becomeContextManager()126*77b80299SAndroid Build Coastguard Worker void ProcessState::becomeContextManager()
127*77b80299SAndroid Build Coastguard Worker {
128*77b80299SAndroid Build Coastguard Worker AutoMutex _l(mLock);
129*77b80299SAndroid Build Coastguard Worker
130*77b80299SAndroid Build Coastguard Worker flat_binder_object obj {
131*77b80299SAndroid Build Coastguard Worker .flags = FLAT_BINDER_FLAG_TXN_SECURITY_CTX,
132*77b80299SAndroid Build Coastguard Worker };
133*77b80299SAndroid Build Coastguard Worker
134*77b80299SAndroid Build Coastguard Worker status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR_EXT, &obj);
135*77b80299SAndroid Build Coastguard Worker
136*77b80299SAndroid Build Coastguard Worker // fallback to original method
137*77b80299SAndroid Build Coastguard Worker if (result != 0) {
138*77b80299SAndroid Build Coastguard Worker android_errorWriteLog(0x534e4554, "121035042");
139*77b80299SAndroid Build Coastguard Worker
140*77b80299SAndroid Build Coastguard Worker int unused = 0;
141*77b80299SAndroid Build Coastguard Worker result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &unused);
142*77b80299SAndroid Build Coastguard Worker }
143*77b80299SAndroid Build Coastguard Worker
144*77b80299SAndroid Build Coastguard Worker if (result == -1) {
145*77b80299SAndroid Build Coastguard Worker ALOGE("Binder ioctl to become context manager failed: %s\n", strerror(errno));
146*77b80299SAndroid Build Coastguard Worker }
147*77b80299SAndroid Build Coastguard Worker }
148*77b80299SAndroid Build Coastguard Worker
149*77b80299SAndroid Build Coastguard Worker // Get references to userspace objects held by the kernel binder driver
150*77b80299SAndroid Build Coastguard Worker // Writes up to count elements into buf, and returns the total number
151*77b80299SAndroid Build Coastguard Worker // of references the kernel has, which may be larger than count.
152*77b80299SAndroid Build Coastguard Worker // buf may be NULL if count is 0. The pointers returned by this method
153*77b80299SAndroid Build Coastguard Worker // should only be used for debugging and not dereferenced, they may
154*77b80299SAndroid Build Coastguard Worker // already be invalid.
getKernelReferences(size_t buf_count,uintptr_t * buf)155*77b80299SAndroid Build Coastguard Worker ssize_t ProcessState::getKernelReferences(size_t buf_count, uintptr_t* buf) {
156*77b80299SAndroid Build Coastguard Worker binder_node_debug_info info = {};
157*77b80299SAndroid Build Coastguard Worker
158*77b80299SAndroid Build Coastguard Worker uintptr_t* end = buf ? buf + buf_count : nullptr;
159*77b80299SAndroid Build Coastguard Worker size_t count = 0;
160*77b80299SAndroid Build Coastguard Worker
161*77b80299SAndroid Build Coastguard Worker do {
162*77b80299SAndroid Build Coastguard Worker status_t result = ioctl(mDriverFD, BINDER_GET_NODE_DEBUG_INFO, &info);
163*77b80299SAndroid Build Coastguard Worker if (result < 0) {
164*77b80299SAndroid Build Coastguard Worker return -1;
165*77b80299SAndroid Build Coastguard Worker }
166*77b80299SAndroid Build Coastguard Worker if (info.ptr != 0) {
167*77b80299SAndroid Build Coastguard Worker if (buf && buf < end) *buf++ = info.ptr;
168*77b80299SAndroid Build Coastguard Worker count++;
169*77b80299SAndroid Build Coastguard Worker if (buf && buf < end) *buf++ = info.cookie;
170*77b80299SAndroid Build Coastguard Worker count++;
171*77b80299SAndroid Build Coastguard Worker }
172*77b80299SAndroid Build Coastguard Worker } while (info.ptr != 0);
173*77b80299SAndroid Build Coastguard Worker
174*77b80299SAndroid Build Coastguard Worker return count;
175*77b80299SAndroid Build Coastguard Worker }
176*77b80299SAndroid Build Coastguard Worker
177*77b80299SAndroid Build Coastguard Worker // Queries the driver for the current strong reference count of the node
178*77b80299SAndroid Build Coastguard Worker // that the handle points to. Can only be used by the servicemanager.
179*77b80299SAndroid Build Coastguard Worker //
180*77b80299SAndroid Build Coastguard Worker // Returns -1 in case of failure, otherwise the strong reference count.
getStrongRefCountForNodeByHandle(int32_t handle)181*77b80299SAndroid Build Coastguard Worker ssize_t ProcessState::getStrongRefCountForNodeByHandle(int32_t handle) {
182*77b80299SAndroid Build Coastguard Worker binder_node_info_for_ref info;
183*77b80299SAndroid Build Coastguard Worker memset(&info, 0, sizeof(binder_node_info_for_ref));
184*77b80299SAndroid Build Coastguard Worker
185*77b80299SAndroid Build Coastguard Worker info.handle = handle;
186*77b80299SAndroid Build Coastguard Worker
187*77b80299SAndroid Build Coastguard Worker status_t result = ioctl(mDriverFD, BINDER_GET_NODE_INFO_FOR_REF, &info);
188*77b80299SAndroid Build Coastguard Worker
189*77b80299SAndroid Build Coastguard Worker if (result != OK) {
190*77b80299SAndroid Build Coastguard Worker static bool logged = false;
191*77b80299SAndroid Build Coastguard Worker if (!logged) {
192*77b80299SAndroid Build Coastguard Worker ALOGW("Kernel does not support BINDER_GET_NODE_INFO_FOR_REF.");
193*77b80299SAndroid Build Coastguard Worker logged = true;
194*77b80299SAndroid Build Coastguard Worker }
195*77b80299SAndroid Build Coastguard Worker return -1;
196*77b80299SAndroid Build Coastguard Worker }
197*77b80299SAndroid Build Coastguard Worker
198*77b80299SAndroid Build Coastguard Worker return info.strong_count;
199*77b80299SAndroid Build Coastguard Worker }
200*77b80299SAndroid Build Coastguard Worker
getMmapSize()201*77b80299SAndroid Build Coastguard Worker size_t ProcessState::getMmapSize() {
202*77b80299SAndroid Build Coastguard Worker return mMmapSize;
203*77b80299SAndroid Build Coastguard Worker }
204*77b80299SAndroid Build Coastguard Worker
setCallRestriction(CallRestriction restriction)205*77b80299SAndroid Build Coastguard Worker void ProcessState::setCallRestriction(CallRestriction restriction) {
206*77b80299SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(IPCThreadState::selfOrNull() != nullptr,
207*77b80299SAndroid Build Coastguard Worker "Call restrictions must be set before the threadpool is started.");
208*77b80299SAndroid Build Coastguard Worker
209*77b80299SAndroid Build Coastguard Worker mCallRestriction = restriction;
210*77b80299SAndroid Build Coastguard Worker }
211*77b80299SAndroid Build Coastguard Worker
lookupHandleLocked(int32_t handle)212*77b80299SAndroid Build Coastguard Worker ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
213*77b80299SAndroid Build Coastguard Worker {
214*77b80299SAndroid Build Coastguard Worker const size_t N=mHandleToObject.size();
215*77b80299SAndroid Build Coastguard Worker if (N <= (size_t)handle) {
216*77b80299SAndroid Build Coastguard Worker handle_entry e;
217*77b80299SAndroid Build Coastguard Worker e.binder = nullptr;
218*77b80299SAndroid Build Coastguard Worker e.refs = nullptr;
219*77b80299SAndroid Build Coastguard Worker status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
220*77b80299SAndroid Build Coastguard Worker if (err < NO_ERROR) return nullptr;
221*77b80299SAndroid Build Coastguard Worker }
222*77b80299SAndroid Build Coastguard Worker return &mHandleToObject.editItemAt(handle);
223*77b80299SAndroid Build Coastguard Worker }
224*77b80299SAndroid Build Coastguard Worker
getStrongProxyForHandle(int32_t handle)225*77b80299SAndroid Build Coastguard Worker sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
226*77b80299SAndroid Build Coastguard Worker {
227*77b80299SAndroid Build Coastguard Worker sp<IBinder> result;
228*77b80299SAndroid Build Coastguard Worker
229*77b80299SAndroid Build Coastguard Worker AutoMutex _l(mLock);
230*77b80299SAndroid Build Coastguard Worker
231*77b80299SAndroid Build Coastguard Worker handle_entry* e = lookupHandleLocked(handle);
232*77b80299SAndroid Build Coastguard Worker
233*77b80299SAndroid Build Coastguard Worker if (e != nullptr) {
234*77b80299SAndroid Build Coastguard Worker // We need to create a new BpHwBinder if there isn't currently one, OR we
235*77b80299SAndroid Build Coastguard Worker // are unable to acquire a weak reference on this current one. See comment
236*77b80299SAndroid Build Coastguard Worker // in getWeakProxyForHandle() for more info about this.
237*77b80299SAndroid Build Coastguard Worker IBinder* b = e->binder;
238*77b80299SAndroid Build Coastguard Worker if (b == nullptr || !e->refs->attemptIncWeak(this)) {
239*77b80299SAndroid Build Coastguard Worker b = new BpHwBinder(handle);
240*77b80299SAndroid Build Coastguard Worker e->binder = b;
241*77b80299SAndroid Build Coastguard Worker if (b) e->refs = b->getWeakRefs();
242*77b80299SAndroid Build Coastguard Worker result = b;
243*77b80299SAndroid Build Coastguard Worker } else {
244*77b80299SAndroid Build Coastguard Worker // This little bit of nastyness is to allow us to add a primary
245*77b80299SAndroid Build Coastguard Worker // reference to the remote proxy when this team doesn't have one
246*77b80299SAndroid Build Coastguard Worker // but another team is sending the handle to us.
247*77b80299SAndroid Build Coastguard Worker result.force_set(b);
248*77b80299SAndroid Build Coastguard Worker e->refs->decWeak(this);
249*77b80299SAndroid Build Coastguard Worker }
250*77b80299SAndroid Build Coastguard Worker }
251*77b80299SAndroid Build Coastguard Worker
252*77b80299SAndroid Build Coastguard Worker return result;
253*77b80299SAndroid Build Coastguard Worker }
254*77b80299SAndroid Build Coastguard Worker
getWeakProxyForHandle(int32_t handle)255*77b80299SAndroid Build Coastguard Worker wp<IBinder> ProcessState::getWeakProxyForHandle(int32_t handle)
256*77b80299SAndroid Build Coastguard Worker {
257*77b80299SAndroid Build Coastguard Worker wp<IBinder> result;
258*77b80299SAndroid Build Coastguard Worker
259*77b80299SAndroid Build Coastguard Worker AutoMutex _l(mLock);
260*77b80299SAndroid Build Coastguard Worker
261*77b80299SAndroid Build Coastguard Worker handle_entry* e = lookupHandleLocked(handle);
262*77b80299SAndroid Build Coastguard Worker
263*77b80299SAndroid Build Coastguard Worker if (e != nullptr) {
264*77b80299SAndroid Build Coastguard Worker // We need to create a new BpHwBinder if there isn't currently one, OR we
265*77b80299SAndroid Build Coastguard Worker // are unable to acquire a weak reference on this current one. The
266*77b80299SAndroid Build Coastguard Worker // attemptIncWeak() is safe because we know the BpHwBinder destructor will always
267*77b80299SAndroid Build Coastguard Worker // call expungeHandle(), which acquires the same lock we are holding now.
268*77b80299SAndroid Build Coastguard Worker // We need to do this because there is a race condition between someone
269*77b80299SAndroid Build Coastguard Worker // releasing a reference on this BpHwBinder, and a new reference on its handle
270*77b80299SAndroid Build Coastguard Worker // arriving from the driver.
271*77b80299SAndroid Build Coastguard Worker IBinder* b = e->binder;
272*77b80299SAndroid Build Coastguard Worker if (b == nullptr || !e->refs->attemptIncWeak(this)) {
273*77b80299SAndroid Build Coastguard Worker b = new BpHwBinder(handle);
274*77b80299SAndroid Build Coastguard Worker result = b;
275*77b80299SAndroid Build Coastguard Worker e->binder = b;
276*77b80299SAndroid Build Coastguard Worker if (b) e->refs = b->getWeakRefs();
277*77b80299SAndroid Build Coastguard Worker } else {
278*77b80299SAndroid Build Coastguard Worker result = b;
279*77b80299SAndroid Build Coastguard Worker e->refs->decWeak(this);
280*77b80299SAndroid Build Coastguard Worker }
281*77b80299SAndroid Build Coastguard Worker }
282*77b80299SAndroid Build Coastguard Worker
283*77b80299SAndroid Build Coastguard Worker return result;
284*77b80299SAndroid Build Coastguard Worker }
285*77b80299SAndroid Build Coastguard Worker
expungeHandle(int32_t handle,IBinder * binder)286*77b80299SAndroid Build Coastguard Worker void ProcessState::expungeHandle(int32_t handle, IBinder* binder)
287*77b80299SAndroid Build Coastguard Worker {
288*77b80299SAndroid Build Coastguard Worker AutoMutex _l(mLock);
289*77b80299SAndroid Build Coastguard Worker
290*77b80299SAndroid Build Coastguard Worker handle_entry* e = lookupHandleLocked(handle);
291*77b80299SAndroid Build Coastguard Worker
292*77b80299SAndroid Build Coastguard Worker // This handle may have already been replaced with a new BpHwBinder
293*77b80299SAndroid Build Coastguard Worker // (if someone failed the AttemptIncWeak() above); we don't want
294*77b80299SAndroid Build Coastguard Worker // to overwrite it.
295*77b80299SAndroid Build Coastguard Worker if (e && e->binder == binder) e->binder = nullptr;
296*77b80299SAndroid Build Coastguard Worker }
297*77b80299SAndroid Build Coastguard Worker
makeBinderThreadName()298*77b80299SAndroid Build Coastguard Worker String8 ProcessState::makeBinderThreadName() {
299*77b80299SAndroid Build Coastguard Worker int32_t s = android_atomic_add(1, &mThreadPoolSeq);
300*77b80299SAndroid Build Coastguard Worker pid_t pid = getpid();
301*77b80299SAndroid Build Coastguard Worker String8 name;
302*77b80299SAndroid Build Coastguard Worker name.appendFormat("HwBinder:%d_%X", pid, s);
303*77b80299SAndroid Build Coastguard Worker return name;
304*77b80299SAndroid Build Coastguard Worker }
305*77b80299SAndroid Build Coastguard Worker
spawnPooledThread(bool isMain)306*77b80299SAndroid Build Coastguard Worker void ProcessState::spawnPooledThread(bool isMain)
307*77b80299SAndroid Build Coastguard Worker {
308*77b80299SAndroid Build Coastguard Worker if (mThreadPoolStarted) {
309*77b80299SAndroid Build Coastguard Worker String8 name = makeBinderThreadName();
310*77b80299SAndroid Build Coastguard Worker ALOGV("Spawning new pooled thread, name=%s\n", name.c_str());
311*77b80299SAndroid Build Coastguard Worker sp<Thread> t = new PoolThread(isMain);
312*77b80299SAndroid Build Coastguard Worker t->run(name.c_str());
313*77b80299SAndroid Build Coastguard Worker }
314*77b80299SAndroid Build Coastguard Worker }
315*77b80299SAndroid Build Coastguard Worker
setThreadPoolConfiguration(size_t maxThreads,bool callerJoinsPool)316*77b80299SAndroid Build Coastguard Worker status_t ProcessState::setThreadPoolConfiguration(size_t maxThreads, bool callerJoinsPool) {
317*77b80299SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(mThreadPoolStarted && maxThreads < mMaxThreads,
318*77b80299SAndroid Build Coastguard Worker "Binder threadpool cannot be shrunk after starting");
319*77b80299SAndroid Build Coastguard Worker
320*77b80299SAndroid Build Coastguard Worker // if the caller joins the pool, then there will be one thread which is impossible.
321*77b80299SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(maxThreads == 0 && callerJoinsPool,
322*77b80299SAndroid Build Coastguard Worker "Binder threadpool must have a minimum of one thread if caller joins pool.");
323*77b80299SAndroid Build Coastguard Worker
324*77b80299SAndroid Build Coastguard Worker if (!isHwbinderSupportedBlocking()) {
325*77b80299SAndroid Build Coastguard Worker ALOGW("HwBinder is not supported on this device but this process is calling setThreadPoolConfiguration");
326*77b80299SAndroid Build Coastguard Worker }
327*77b80299SAndroid Build Coastguard Worker
328*77b80299SAndroid Build Coastguard Worker size_t threadsToAllocate = maxThreads;
329*77b80299SAndroid Build Coastguard Worker
330*77b80299SAndroid Build Coastguard Worker // If the caller is going to join the pool it will contribute one thread to the threadpool.
331*77b80299SAndroid Build Coastguard Worker // This is part of the API's contract.
332*77b80299SAndroid Build Coastguard Worker if (callerJoinsPool) threadsToAllocate--;
333*77b80299SAndroid Build Coastguard Worker
334*77b80299SAndroid Build Coastguard Worker // If we can, spawn one thread from userspace when the threadpool is started. This ensures
335*77b80299SAndroid Build Coastguard Worker // that there is always a thread available to start more threads as soon as the threadpool
336*77b80299SAndroid Build Coastguard Worker // is started.
337*77b80299SAndroid Build Coastguard Worker bool spawnThreadOnStart = threadsToAllocate > 0;
338*77b80299SAndroid Build Coastguard Worker if (spawnThreadOnStart) threadsToAllocate--;
339*77b80299SAndroid Build Coastguard Worker
340*77b80299SAndroid Build Coastguard Worker // the BINDER_SET_MAX_THREADS ioctl really tells the kernel how many threads
341*77b80299SAndroid Build Coastguard Worker // it's allowed to spawn, *in addition* to any threads we may have already
342*77b80299SAndroid Build Coastguard Worker // spawned locally.
343*77b80299SAndroid Build Coastguard Worker size_t kernelMaxThreads = threadsToAllocate;
344*77b80299SAndroid Build Coastguard Worker
345*77b80299SAndroid Build Coastguard Worker AutoMutex _l(mLock);
346*77b80299SAndroid Build Coastguard Worker if (ioctl(mDriverFD, BINDER_SET_MAX_THREADS, &kernelMaxThreads) == -1) {
347*77b80299SAndroid Build Coastguard Worker ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
348*77b80299SAndroid Build Coastguard Worker return -errno;
349*77b80299SAndroid Build Coastguard Worker }
350*77b80299SAndroid Build Coastguard Worker
351*77b80299SAndroid Build Coastguard Worker mMaxThreads = maxThreads;
352*77b80299SAndroid Build Coastguard Worker mSpawnThreadOnStart = spawnThreadOnStart;
353*77b80299SAndroid Build Coastguard Worker
354*77b80299SAndroid Build Coastguard Worker return NO_ERROR;
355*77b80299SAndroid Build Coastguard Worker }
356*77b80299SAndroid Build Coastguard Worker
enableOnewaySpamDetection(bool enable)357*77b80299SAndroid Build Coastguard Worker status_t ProcessState::enableOnewaySpamDetection(bool enable) {
358*77b80299SAndroid Build Coastguard Worker uint32_t enableDetection = enable ? 1 : 0;
359*77b80299SAndroid Build Coastguard Worker if (ioctl(mDriverFD, BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enableDetection) == -1) {
360*77b80299SAndroid Build Coastguard Worker ALOGI("Binder ioctl to enable oneway spam detection failed: %s", strerror(errno));
361*77b80299SAndroid Build Coastguard Worker return -errno;
362*77b80299SAndroid Build Coastguard Worker }
363*77b80299SAndroid Build Coastguard Worker return NO_ERROR;
364*77b80299SAndroid Build Coastguard Worker }
365*77b80299SAndroid Build Coastguard Worker
getMaxThreads()366*77b80299SAndroid Build Coastguard Worker size_t ProcessState::getMaxThreads() {
367*77b80299SAndroid Build Coastguard Worker return mMaxThreads;
368*77b80299SAndroid Build Coastguard Worker }
369*77b80299SAndroid Build Coastguard Worker
giveThreadPoolName()370*77b80299SAndroid Build Coastguard Worker void ProcessState::giveThreadPoolName() {
371*77b80299SAndroid Build Coastguard Worker androidSetThreadName( makeBinderThreadName().c_str() );
372*77b80299SAndroid Build Coastguard Worker }
373*77b80299SAndroid Build Coastguard Worker
open_driver()374*77b80299SAndroid Build Coastguard Worker static int open_driver()
375*77b80299SAndroid Build Coastguard Worker {
376*77b80299SAndroid Build Coastguard Worker int fd = open("/dev/hwbinder", O_RDWR | O_CLOEXEC);
377*77b80299SAndroid Build Coastguard Worker if (fd >= 0) {
378*77b80299SAndroid Build Coastguard Worker int vers = 0;
379*77b80299SAndroid Build Coastguard Worker status_t result = ioctl(fd, BINDER_VERSION, &vers);
380*77b80299SAndroid Build Coastguard Worker if (result == -1) {
381*77b80299SAndroid Build Coastguard Worker ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
382*77b80299SAndroid Build Coastguard Worker close(fd);
383*77b80299SAndroid Build Coastguard Worker fd = -1;
384*77b80299SAndroid Build Coastguard Worker }
385*77b80299SAndroid Build Coastguard Worker if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
386*77b80299SAndroid Build Coastguard Worker ALOGE("Binder driver protocol(%d) does not match user space protocol(%d)!", vers, BINDER_CURRENT_PROTOCOL_VERSION);
387*77b80299SAndroid Build Coastguard Worker close(fd);
388*77b80299SAndroid Build Coastguard Worker fd = -1;
389*77b80299SAndroid Build Coastguard Worker }
390*77b80299SAndroid Build Coastguard Worker size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
391*77b80299SAndroid Build Coastguard Worker result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
392*77b80299SAndroid Build Coastguard Worker if (result == -1) {
393*77b80299SAndroid Build Coastguard Worker ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
394*77b80299SAndroid Build Coastguard Worker }
395*77b80299SAndroid Build Coastguard Worker uint32_t enable = DEFAULT_ENABLE_ONEWAY_SPAM_DETECTION;
396*77b80299SAndroid Build Coastguard Worker result = ioctl(fd, BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enable);
397*77b80299SAndroid Build Coastguard Worker if (result == -1) {
398*77b80299SAndroid Build Coastguard Worker ALOGV("Binder ioctl to enable oneway spam detection failed: %s", strerror(errno));
399*77b80299SAndroid Build Coastguard Worker }
400*77b80299SAndroid Build Coastguard Worker } else {
401*77b80299SAndroid Build Coastguard Worker ALOGW("Opening '/dev/hwbinder' failed: %s\n", strerror(errno));
402*77b80299SAndroid Build Coastguard Worker }
403*77b80299SAndroid Build Coastguard Worker return fd;
404*77b80299SAndroid Build Coastguard Worker }
405*77b80299SAndroid Build Coastguard Worker
ProcessState(size_t mmapSize)406*77b80299SAndroid Build Coastguard Worker ProcessState::ProcessState(size_t mmapSize)
407*77b80299SAndroid Build Coastguard Worker : mDriverFD(open_driver())
408*77b80299SAndroid Build Coastguard Worker , mVMStart(MAP_FAILED)
409*77b80299SAndroid Build Coastguard Worker , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
410*77b80299SAndroid Build Coastguard Worker , mExecutingThreadsCount(0)
411*77b80299SAndroid Build Coastguard Worker , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
412*77b80299SAndroid Build Coastguard Worker , mStarvationStartTimeMs(0)
413*77b80299SAndroid Build Coastguard Worker , mThreadPoolStarted(false)
414*77b80299SAndroid Build Coastguard Worker , mSpawnThreadOnStart(true)
415*77b80299SAndroid Build Coastguard Worker , mThreadPoolSeq(1)
416*77b80299SAndroid Build Coastguard Worker , mMmapSize(mmapSize)
417*77b80299SAndroid Build Coastguard Worker , mCallRestriction(CallRestriction::NONE)
418*77b80299SAndroid Build Coastguard Worker {
419*77b80299SAndroid Build Coastguard Worker if (mDriverFD >= 0) {
420*77b80299SAndroid Build Coastguard Worker // mmap the binder, providing a chunk of virtual address space to receive transactions.
421*77b80299SAndroid Build Coastguard Worker mVMStart = mmap(nullptr, mMmapSize, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
422*77b80299SAndroid Build Coastguard Worker if (mVMStart == MAP_FAILED) {
423*77b80299SAndroid Build Coastguard Worker // *sigh*
424*77b80299SAndroid Build Coastguard Worker ALOGE("Mmapping /dev/hwbinder failed: %s\n", strerror(errno));
425*77b80299SAndroid Build Coastguard Worker close(mDriverFD);
426*77b80299SAndroid Build Coastguard Worker mDriverFD = -1;
427*77b80299SAndroid Build Coastguard Worker }
428*77b80299SAndroid Build Coastguard Worker }
429*77b80299SAndroid Build Coastguard Worker
430*77b80299SAndroid Build Coastguard Worker #ifdef __ANDROID__
431*77b80299SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened. Terminating.");
432*77b80299SAndroid Build Coastguard Worker #endif
433*77b80299SAndroid Build Coastguard Worker }
434*77b80299SAndroid Build Coastguard Worker
~ProcessState()435*77b80299SAndroid Build Coastguard Worker ProcessState::~ProcessState()
436*77b80299SAndroid Build Coastguard Worker {
437*77b80299SAndroid Build Coastguard Worker if (mDriverFD >= 0) {
438*77b80299SAndroid Build Coastguard Worker if (mVMStart != MAP_FAILED) {
439*77b80299SAndroid Build Coastguard Worker munmap(mVMStart, mMmapSize);
440*77b80299SAndroid Build Coastguard Worker }
441*77b80299SAndroid Build Coastguard Worker close(mDriverFD);
442*77b80299SAndroid Build Coastguard Worker }
443*77b80299SAndroid Build Coastguard Worker mDriverFD = -1;
444*77b80299SAndroid Build Coastguard Worker }
445*77b80299SAndroid Build Coastguard Worker
446*77b80299SAndroid Build Coastguard Worker } // namespace hardware
447*77b80299SAndroid Build Coastguard Worker } // namespace android
448