summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartijn Coenen <maco@google.com>2018-03-22 17:12:57 +0100
committerMartijn Coenen <maco@google.com>2018-03-23 10:21:53 +0000
commit2c32359fbee1e7a5d1d56c9c45140eac26b636f7 (patch)
treed28025d875a630f620b822fef16a680d1a3829bc
parent5dfc6ce3988e9045bac76370fbdaee23cf2a20ec (diff)
downloadlibhwbinder-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.cpp27
-rw-r--r--include/hwbinder/ProcessState.h7
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