• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2005 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "hw-ProcessState"
18 
19 #include <hwbinder/ProcessState.h>
20 
21 #include <hwbinder/BpHwBinder.h>
22 #include <hwbinder/IPCThreadState.h>
23 #include <hwbinder/binder_kernel.h>
24 #include <utils/Atomic.h>
25 #include <utils/Log.h>
26 #include <utils/String8.h>
27 #include <utils/threads.h>
28 
29 #include <private/binder/binder_module.h>
30 #include <hwbinder/Static.h>
31 
32 #include <errno.h>
33 #include <fcntl.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <unistd.h>
37 #include <sys/ioctl.h>
38 #include <sys/mman.h>
39 #include <sys/stat.h>
40 #include <sys/types.h>
41 
42 #define BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2)
43 #define DEFAULT_MAX_BINDER_THREADS 0
44 
45 // -------------------------------------------------------------------------
46 
47 namespace android {
48 namespace hardware {
49 
50 class PoolThread : public Thread
51 {
52 public:
PoolThread(bool isMain)53     explicit PoolThread(bool isMain)
54         : mIsMain(isMain)
55     {
56     }
57 
58 protected:
threadLoop()59     virtual bool threadLoop()
60     {
61         IPCThreadState::self()->joinThreadPool(mIsMain);
62         return false;
63     }
64 
65     const bool mIsMain;
66 };
67 
self()68 sp<ProcessState> ProcessState::self()
69 {
70     Mutex::Autolock _l(gProcessMutex);
71     if (gProcess != NULL) {
72         return gProcess;
73     }
74     gProcess = new ProcessState;
75     return gProcess;
76 }
77 
selfOrNull()78 sp<ProcessState> ProcessState::selfOrNull() {
79     Mutex::Autolock _l(gProcessMutex);
80     return gProcess;
81 }
82 
setContextObject(const sp<IBinder> & object)83 void ProcessState::setContextObject(const sp<IBinder>& object)
84 {
85     setContextObject(object, String16("default"));
86 }
87 
getContextObject(const sp<IBinder> &)88 sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
89 {
90     return getStrongProxyForHandle(0);
91 }
92 
setContextObject(const sp<IBinder> & object,const String16 & name)93 void ProcessState::setContextObject(const sp<IBinder>& object, const String16& name)
94 {
95     AutoMutex _l(mLock);
96     mContexts.add(name, object);
97 }
98 
getContextObject(const String16 & name,const sp<IBinder> & caller)99 sp<IBinder> ProcessState::getContextObject(const String16& name, const sp<IBinder>& caller)
100 {
101     mLock.lock();
102     sp<IBinder> object(
103         mContexts.indexOfKey(name) >= 0 ? mContexts.valueFor(name) : NULL);
104     mLock.unlock();
105 
106     //printf("Getting context object %s for %p\n", String8(name).string(), caller.get());
107 
108     if (object != NULL) return object;
109 
110     // Don't attempt to retrieve contexts if we manage them
111     if (mManagesContexts) {
112         ALOGE("getContextObject(%s) failed, but we manage the contexts!\n",
113             String8(name).string());
114         return NULL;
115     }
116 
117     IPCThreadState* ipc = IPCThreadState::self();
118     {
119         Parcel data, reply;
120         // no interface token on this magic transaction
121         data.writeString16(name);
122         data.writeStrongBinder(caller);
123         status_t result = ipc->transact(0 /*magic*/, 0, data, &reply, 0);
124         if (result == NO_ERROR) {
125             object = reply.readStrongBinder();
126         }
127     }
128 
129     ipc->flushCommands();
130 
131     if (object != NULL) setContextObject(object, name);
132     return object;
133 }
134 
startThreadPool()135 void ProcessState::startThreadPool()
136 {
137     AutoMutex _l(mLock);
138     if (!mThreadPoolStarted) {
139         mThreadPoolStarted = true;
140         if (mSpawnThreadOnStart) {
141             spawnPooledThread(true);
142         }
143     }
144 }
145 
isContextManager(void) const146 bool ProcessState::isContextManager(void) const
147 {
148     return mManagesContexts;
149 }
150 
becomeContextManager(context_check_func checkFunc,void * userData)151 bool ProcessState::becomeContextManager(context_check_func checkFunc, void* userData)
152 {
153     if (!mManagesContexts) {
154         AutoMutex _l(mLock);
155         mBinderContextCheckFunc = checkFunc;
156         mBinderContextUserData = userData;
157 
158         flat_binder_object obj {
159             .flags = FLAT_BINDER_FLAG_TXN_SECURITY_CTX,
160         };
161 
162         status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR_EXT, &obj);
163 
164         // fallback to original method
165         if (result != 0) {
166             android_errorWriteLog(0x534e4554, "121035042");
167 
168             int dummy = 0;
169             result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &dummy);
170         }
171 
172         if (result == 0) {
173             mManagesContexts = true;
174         } else if (result == -1) {
175             mBinderContextCheckFunc = NULL;
176             mBinderContextUserData = NULL;
177             ALOGE("Binder ioctl to become context manager failed: %s\n", strerror(errno));
178         }
179     }
180     return mManagesContexts;
181 }
182 
183 // Get references to userspace objects held by the kernel binder driver
184 // Writes up to count elements into buf, and returns the total number
185 // of references the kernel has, which may be larger than count.
186 // buf may be NULL if count is 0.  The pointers returned by this method
187 // should only be used for debugging and not dereferenced, they may
188 // already be invalid.
getKernelReferences(size_t buf_count,uintptr_t * buf)189 ssize_t ProcessState::getKernelReferences(size_t buf_count, uintptr_t* buf) {
190     binder_node_debug_info info = {};
191 
192     uintptr_t* end = buf ? buf + buf_count : NULL;
193     size_t count = 0;
194 
195     do {
196         status_t result = ioctl(mDriverFD, BINDER_GET_NODE_DEBUG_INFO, &info);
197         if (result < 0) {
198             return -1;
199         }
200         if (info.ptr != 0) {
201             if (buf && buf < end) *buf++ = info.ptr;
202             count++;
203             if (buf && buf < end) *buf++ = info.cookie;
204             count++;
205         }
206     } while (info.ptr != 0);
207 
208     return count;
209 }
210 
lookupHandleLocked(int32_t handle)211 ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
212 {
213     const size_t N=mHandleToObject.size();
214     if (N <= (size_t)handle) {
215         handle_entry e;
216         e.binder = NULL;
217         e.refs = NULL;
218         status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
219         if (err < NO_ERROR) return NULL;
220     }
221     return &mHandleToObject.editItemAt(handle);
222 }
223 
getStrongProxyForHandle(int32_t handle)224 sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
225 {
226     sp<IBinder> result;
227 
228     AutoMutex _l(mLock);
229 
230     handle_entry* e = lookupHandleLocked(handle);
231 
232     if (e != NULL) {
233         // We need to create a new BpHwBinder if there isn't currently one, OR we
234         // are unable to acquire a weak reference on this current one.  See comment
235         // in getWeakProxyForHandle() for more info about this.
236         IBinder* b = e->binder;
237         if (b == NULL || !e->refs->attemptIncWeak(this)) {
238             b = new BpHwBinder(handle);
239             e->binder = b;
240             if (b) e->refs = b->getWeakRefs();
241             result = b;
242         } else {
243             // This little bit of nastyness is to allow us to add a primary
244             // reference to the remote proxy when this team doesn't have one
245             // but another team is sending the handle to us.
246             result.force_set(b);
247             e->refs->decWeak(this);
248         }
249     }
250 
251     return result;
252 }
253 
getWeakProxyForHandle(int32_t handle)254 wp<IBinder> ProcessState::getWeakProxyForHandle(int32_t handle)
255 {
256     wp<IBinder> result;
257 
258     AutoMutex _l(mLock);
259 
260     handle_entry* e = lookupHandleLocked(handle);
261 
262     if (e != NULL) {
263         // We need to create a new BpHwBinder if there isn't currently one, OR we
264         // are unable to acquire a weak reference on this current one.  The
265         // attemptIncWeak() is safe because we know the BpHwBinder destructor will always
266         // call expungeHandle(), which acquires the same lock we are holding now.
267         // We need to do this because there is a race condition between someone
268         // releasing a reference on this BpHwBinder, and a new reference on its handle
269         // arriving from the driver.
270         IBinder* b = e->binder;
271         if (b == NULL || !e->refs->attemptIncWeak(this)) {
272             b = new BpHwBinder(handle);
273             result = b;
274             e->binder = b;
275             if (b) e->refs = b->getWeakRefs();
276         } else {
277             result = b;
278             e->refs->decWeak(this);
279         }
280     }
281 
282     return result;
283 }
284 
expungeHandle(int32_t handle,IBinder * binder)285 void ProcessState::expungeHandle(int32_t handle, IBinder* binder)
286 {
287     AutoMutex _l(mLock);
288 
289     handle_entry* e = lookupHandleLocked(handle);
290 
291     // This handle may have already been replaced with a new BpHwBinder
292     // (if someone failed the AttemptIncWeak() above); we don't want
293     // to overwrite it.
294     if (e && e->binder == binder) e->binder = NULL;
295 }
296 
makeBinderThreadName()297 String8 ProcessState::makeBinderThreadName() {
298     int32_t s = android_atomic_add(1, &mThreadPoolSeq);
299     pid_t pid = getpid();
300     String8 name;
301     name.appendFormat("HwBinder:%d_%X", pid, s);
302     return name;
303 }
304 
spawnPooledThread(bool isMain)305 void ProcessState::spawnPooledThread(bool isMain)
306 {
307     if (mThreadPoolStarted) {
308         String8 name = makeBinderThreadName();
309         ALOGV("Spawning new pooled thread, name=%s\n", name.string());
310         sp<Thread> t = new PoolThread(isMain);
311         t->run(name.string());
312     }
313 }
314 
setThreadPoolConfiguration(size_t maxThreads,bool callerJoinsPool)315 status_t ProcessState::setThreadPoolConfiguration(size_t maxThreads, bool callerJoinsPool) {
316     LOG_ALWAYS_FATAL_IF(maxThreads < 1, "Binder threadpool must have a minimum of one thread.");
317     status_t result = NO_ERROR;
318     // the BINDER_SET_MAX_THREADS ioctl really tells the kernel how many threads
319     // it's allowed to spawn, *in addition* to any threads we may have already
320     // spawned locally. If 'callerJoinsPool' is true, it means that the caller
321     // will join the threadpool, and so the kernel needs to create one less thread.
322     // If 'callerJoinsPool' is false, we will still spawn a thread locally, and we should
323     // also tell the kernel to create one less thread than what was requested here.
324     size_t kernelMaxThreads = maxThreads - 1;
325     if (ioctl(mDriverFD, BINDER_SET_MAX_THREADS, &kernelMaxThreads) != -1) {
326         AutoMutex _l(mLock);
327         mMaxThreads = maxThreads;
328         mSpawnThreadOnStart = !callerJoinsPool;
329     } else {
330         result = -errno;
331         ALOGE("Binder ioctl to set max threads failed: %s", strerror(-result));
332     }
333     return result;
334 }
335 
giveThreadPoolName()336 void ProcessState::giveThreadPoolName() {
337     androidSetThreadName( makeBinderThreadName().string() );
338 }
339 
open_driver()340 static int open_driver()
341 {
342     int fd = open("/dev/hwbinder", O_RDWR | O_CLOEXEC);
343     if (fd >= 0) {
344         int vers = 0;
345         status_t result = ioctl(fd, BINDER_VERSION, &vers);
346         if (result == -1) {
347             ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
348             close(fd);
349             fd = -1;
350         }
351         if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
352           ALOGE("Binder driver protocol(%d) does not match user space protocol(%d)!", vers, BINDER_CURRENT_PROTOCOL_VERSION);
353             close(fd);
354             fd = -1;
355         }
356         size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
357         result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
358         if (result == -1) {
359             ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
360         }
361     } else {
362         ALOGW("Opening '/dev/hwbinder' failed: %s\n", strerror(errno));
363     }
364     return fd;
365 }
366 
ProcessState()367 ProcessState::ProcessState()
368     : mDriverFD(open_driver())
369     , mVMStart(MAP_FAILED)
370     , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
371     , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
372     , mExecutingThreadsCount(0)
373     , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
374     , mStarvationStartTimeMs(0)
375     , mManagesContexts(false)
376     , mBinderContextCheckFunc(NULL)
377     , mBinderContextUserData(NULL)
378     , mThreadPoolStarted(false)
379     , mSpawnThreadOnStart(true)
380     , mThreadPoolSeq(1)
381 {
382     if (mDriverFD >= 0) {
383         // mmap the binder, providing a chunk of virtual address space to receive transactions.
384         mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
385         if (mVMStart == MAP_FAILED) {
386             // *sigh*
387             ALOGE("Using /dev/hwbinder failed: unable to mmap transaction memory.\n");
388             close(mDriverFD);
389             mDriverFD = -1;
390         }
391     }
392     else {
393         ALOGE("Binder driver could not be opened.  Terminating.");
394     }
395 }
396 
~ProcessState()397 ProcessState::~ProcessState()
398 {
399     if (mDriverFD >= 0) {
400         if (mVMStart != MAP_FAILED) {
401             munmap(mVMStart, BINDER_VM_SIZE);
402         }
403         close(mDriverFD);
404     }
405     mDriverFD = -1;
406 }
407 
408 }; // namespace hardware
409 }; // namespace android
410