diff options
author | Martijn Coenen <maco@google.com> | 2018-03-22 17:12:57 +0100 |
---|---|---|
committer | Martijn Coenen <maco@google.com> | 2018-03-23 10:21:53 +0000 |
commit | 2c32359fbee1e7a5d1d56c9c45140eac26b636f7 (patch) | |
tree | d28025d875a630f620b822fef16a680d1a3829bc | |
parent | 5dfc6ce3988e9045bac76370fbdaee23cf2a20ec (diff) | |
download | libhwbinder-2c32359fbee1e7a5d1d56c9c45140eac26b636f7.tar.gz |
Support initializing ProcessState with custom binder window size.
While the binder kernel driver allocates memory lazily, using
a 1MB binder window does mean 1MB of vmalloc address space is lost.
This can be a problem on 32-bit devices, where the address space
available for vmalloc is very limited.
This change allows initializing ProcessState with a custom mmap
size. Note that this API must be called as early as possible in
the process, before any other hwbinder (API) calls or HIDL calls
have been made.
Bug: 67668716
Test: verify kernel output after calling API
Change-Id: I62cdbcb4ffcad1a6d7b3eeae5560eb3e5e602515
-rw-r--r-- | ProcessState.cpp | 27 | ||||
-rw-r--r-- | include/hwbinder/ProcessState.h | 7 |
2 files changed, 27 insertions, 7 deletions
diff --git a/ProcessState.cpp b/ProcessState.cpp index e3a9b3c..0b32adf 100644 --- a/ProcessState.cpp +++ b/ProcessState.cpp @@ -39,7 +39,7 @@ #include <sys/stat.h> #include <sys/types.h> -#define BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2) +#define DEFAULT_BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2) #define DEFAULT_MAX_BINDER_THREADS 0 // ------------------------------------------------------------------------- @@ -71,7 +71,7 @@ sp<ProcessState> ProcessState::self() if (gProcess != NULL) { return gProcess; } - gProcess = new ProcessState; + gProcess = new ProcessState(DEFAULT_BINDER_VM_SIZE); return gProcess; } @@ -80,6 +80,18 @@ sp<ProcessState> ProcessState::selfOrNull() { return gProcess; } +sp<ProcessState> ProcessState::initWithMmapSize(size_t mmap_size) { + Mutex::Autolock _l(gProcessMutex); + if (gProcess != NULL) { + LOG_ALWAYS_FATAL_IF(mmap_size != gProcess->getMmapSize(), + "ProcessState already initialized with a different mmap size."); + return gProcess; + } + + gProcess = new ProcessState(mmap_size); + return gProcess; +} + void ProcessState::setContextObject(const sp<IBinder>& object) { setContextObject(object, String16("default")); @@ -196,6 +208,10 @@ ssize_t ProcessState::getKernelReferences(size_t buf_count, uintptr_t* buf) { return count; } +size_t ProcessState::getMmapSize() { + return mMmapSize; +} + ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle) { const size_t N=mHandleToObject.size(); @@ -356,7 +372,7 @@ static int open_driver() return fd; } -ProcessState::ProcessState() +ProcessState::ProcessState(size_t mmap_size) : mDriverFD(open_driver()) , mVMStart(MAP_FAILED) , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER) @@ -370,10 +386,11 @@ ProcessState::ProcessState() , mThreadPoolStarted(false) , mSpawnThreadOnStart(true) , mThreadPoolSeq(1) + , mMmapSize(mmap_size) { if (mDriverFD >= 0) { // mmap the binder, providing a chunk of virtual address space to receive transactions. - mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0); + mVMStart = mmap(0, mMmapSize, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0); if (mVMStart == MAP_FAILED) { // *sigh* ALOGE("Using /dev/hwbinder failed: unable to mmap transaction memory.\n"); @@ -390,7 +407,7 @@ ProcessState::~ProcessState() { if (mDriverFD >= 0) { if (mVMStart != MAP_FAILED) { - munmap(mVMStart, BINDER_VM_SIZE); + munmap(mVMStart, mMmapSize); } close(mDriverFD); } diff --git a/include/hwbinder/ProcessState.h b/include/hwbinder/ProcessState.h index 305ee11..2f72059 100644 --- a/include/hwbinder/ProcessState.h +++ b/include/hwbinder/ProcessState.h @@ -37,6 +37,8 @@ class ProcessState : public virtual RefBase public: static sp<ProcessState> self(); static sp<ProcessState> selfOrNull(); + // Note: don't call self() or selfOrNull() before initWithMmapSize() + static sp<ProcessState> initWithMmapSize(size_t mmapSize); // size in bytes void setContextObject(const sp<IBinder>& object); sp<IBinder> getContextObject(const sp<IBinder>& caller); @@ -68,11 +70,11 @@ public: void giveThreadPoolName(); ssize_t getKernelReferences(size_t count, uintptr_t* buf); - + size_t getMmapSize(); private: friend class IPCThreadState; - ProcessState(); + ProcessState(size_t mmap_size); ~ProcessState(); ProcessState(const ProcessState& o); @@ -115,6 +117,7 @@ private: bool mThreadPoolStarted; bool mSpawnThreadOnStart; volatile int32_t mThreadPoolSeq; + size_t mMmapSize; }; }; // namespace hardware |