From d26d3de9d1bb7e94867744278c2800703a8ba8bb Mon Sep 17 00:00:00 2001 From: Martijn Coenen Date: Thu, 22 Mar 2018 17:12:57 +0100 Subject: 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. c/p from 32507d340df9c654ae3129ce666c6a2b5d708719 Bug: 129785390 Test: verify kernel output after calling API Change-Id: I62cdbcb4ffcad1a6d7b3eeae5560eb3e5e602515 --- libs/binder/ProcessState.cpp | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) (limited to 'libs/binder/ProcessState.cpp') diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp index 3798b61ab9..1bc28f2542 100644 --- a/libs/binder/ProcessState.cpp +++ b/libs/binder/ProcessState.cpp @@ -40,7 +40,7 @@ #include #include -#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 15 #ifdef __ANDROID_VNDK__ @@ -77,7 +77,13 @@ sp ProcessState::self() if (gProcess != nullptr) { return gProcess; } - gProcess = new ProcessState(kDefaultDriver); + gProcess = new ProcessState(kDefaultDriver, DEFAULT_BINDER_VM_SIZE); + return gProcess; +} + +sp ProcessState::selfOrNull() +{ + Mutex::Autolock _l(gProcessMutex); return gProcess; } @@ -98,13 +104,19 @@ sp ProcessState::initWithDriver(const char* driver) driver = "/dev/binder"; } - gProcess = new ProcessState(driver); + gProcess = new ProcessState(driver, DEFAULT_BINDER_VM_SIZE); return gProcess; } -sp ProcessState::selfOrNull() -{ +sp ProcessState::initWithMmapSize(size_t mmap_size) { Mutex::Autolock _l(gProcessMutex); + if (gProcess != nullptr) { + LOG_ALWAYS_FATAL_IF(mmap_size != gProcess->getMmapSize(), + "ProcessState already initialized with a different mmap size."); + return gProcess; + } + + gProcess = new ProcessState(kDefaultDriver, mmap_size); return gProcess; } @@ -234,6 +246,10 @@ ssize_t ProcessState::getKernelReferences(size_t buf_count, uintptr_t* buf) return count; } +size_t ProcessState::getMmapSize() { + return mMmapSize; +} + void ProcessState::setCallRestriction(CallRestriction restriction) { LOG_ALWAYS_FATAL_IF(IPCThreadState::selfOrNull(), "Call restrictions must be set before the threadpool is started."); @@ -418,7 +434,7 @@ static int open_driver(const char *driver) return fd; } -ProcessState::ProcessState(const char *driver) +ProcessState::ProcessState(const char *driver, size_t mmap_size) : mDriverName(String8(driver)) , mDriverFD(open_driver(driver)) , mVMStart(MAP_FAILED) @@ -432,11 +448,12 @@ ProcessState::ProcessState(const char *driver) , mBinderContextUserData(nullptr) , mThreadPoolStarted(false) , mThreadPoolSeq(1) + , mMmapSize(mmap_size) , mCallRestriction(CallRestriction::NONE) { if (mDriverFD >= 0) { // mmap the binder, providing a chunk of virtual address space to receive transactions. - mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0); + mVMStart = mmap(nullptr, mMmapSize, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0); if (mVMStart == MAP_FAILED) { // *sigh* ALOGE("Using %s failed: unable to mmap transaction memory.\n", mDriverName.c_str()); @@ -453,7 +470,7 @@ ProcessState::~ProcessState() { if (mDriverFD >= 0) { if (mVMStart != MAP_FAILED) { - munmap(mVMStart, BINDER_VM_SIZE); + munmap(mVMStart, mMmapSize); } close(mDriverFD); } -- cgit v1.2.3-59-g8ed1b