storageproxyd: Start binder thread pool
The Trusty storage proxy requires that the suspend service is started to
acquire a wakelock for UFS RPMB operations. Without the binder thread
pool running, starting this service results in at least a 1s polling
delay. This change ensures that we start the thread pool before handling
any RPMB operations, so acquiring the wakelock will complete as soon as
the service is ready without needing to poll once per second.
Test: m storageproxyd
Test: Artificially delay suspend_service to check if we poll
Bug: 281951047
Change-Id: I1a4cdd48d57201b0cf9c24523d22e5bdbcea376a
diff --git a/trusty/storage/proxy/Android.bp b/trusty/storage/proxy/Android.bp
index 2e97ee0..e362b8b 100644
--- a/trusty/storage/proxy/Android.bp
+++ b/trusty/storage/proxy/Android.bp
@@ -33,6 +33,7 @@
shared_libs: [
"libbase",
+ "libbinder_ndk",
"libcutils",
"liblog",
"libhardware_legacy",
diff --git a/trusty/storage/proxy/proxy.c b/trusty/storage/proxy/proxy.c
index c89c5b6..3b744ec 100644
--- a/trusty/storage/proxy/proxy.c
+++ b/trusty/storage/proxy/proxy.c
@@ -24,6 +24,7 @@
#include <sys/stat.h>
#include <unistd.h>
+#include <android/binder_process.h>
#include <cutils/android_filesystem_config.h>
#include "checkpoint_handling.h"
@@ -238,6 +239,15 @@
/* parse arguments */
parse_args(argc, argv);
+ /*
+ * Start binder threadpool. At least one extra binder thread is needed to
+ * connect to the wakelock service without relying on polling. If we poll on
+ * the main thread we end up pausing for at least 1s even if the service
+ * starts faster.
+ */
+ ABinderProcess_setThreadPoolMaxThreadCount(1);
+ ABinderProcess_startThreadPool();
+
/* initialize secure storage directory */
rc = storage_init(ss_data_root);
if (rc < 0) return EXIT_FAILURE;
diff --git a/trusty/storage/proxy/rpmb.c b/trusty/storage/proxy/rpmb.c
index 22a85a7..1f5d107 100644
--- a/trusty/storage/proxy/rpmb.c
+++ b/trusty/storage/proxy/rpmb.c
@@ -399,6 +399,14 @@
bool is_request_write = req->reliable_write_size > 0;
+ /*
+ * Internally this call connects to the suspend service, which will cause
+ * this service to start if not already running. If the binder thread pool
+ * has not been started at this point, this call will block and poll for the
+ * service every 1s. We need to make sure the thread pool is started to
+ * receive an async notification that the service is started to avoid
+ * blocking (see main).
+ */
wl_rc = acquire_wake_lock(PARTIAL_WAKE_LOCK, UFS_WAKE_LOCK_NAME);
if (wl_rc < 0) {
ALOGE("%s: failed to acquire wakelock: %d, %s\n", __func__, wl_rc, strerror(errno));