summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Moreland <smoreland@google.com>2018-05-25 12:09:51 -0700
committerSteven Moreland <smoreland@google.com>2018-05-25 14:40:51 -0700
commit9339952bfc64103c1a3c51d1150719d7289995b4 (patch)
tree62d473a601f19901f399b14d5c0eb718620684a3
parentc61c0c1193d493f97f3a8657b75c5256a70aea3a (diff)
downloadnative-9339952bfc64103c1a3c51d1150719d7289995b4.tar.gz
surfaceflinger: fix race condition
surfaceflinger only has one thread. main thread is: a). startHidlServices b). do a getService c). getService receives notification on binder thread and returns d). binder ServiceManager register SF service Then, started by a). hwbinder thread is (DisplayService's, when it receives a transaction): e). binder ServiceManager get SF service ( (d) must happen first! ) Normally, (e) never happens because nothing calls into DisplayService until later. However, on a particular QCOM device (b/80061790), surfaceflinger restarts at just the right time that this sequence happens: (a) (b) (e) then (c) is blocked since (e) is on a binder thread). Test: QCOM device no longer enters this deadlock Test: boot up on Pixel device Test: (sanity) check to make sure surface flinger has one hwbinder thread Test: (sanity) make sure Pixel device surface flinger doesn't register an allocator when it isn't supposed to. As a follow-up, the return values from these various services will be checked. Bug: 80061790 Change-Id: I254d70951ee9508790c940240bcd1da5af746dd3
-rw-r--r--services/surfaceflinger/main_surfaceflinger.cpp36
1 files changed, 17 insertions, 19 deletions
diff --git a/services/surfaceflinger/main_surfaceflinger.cpp b/services/surfaceflinger/main_surfaceflinger.cpp
index 2a924ae1c7..8255b41596 100644
--- a/services/surfaceflinger/main_surfaceflinger.cpp
+++ b/services/surfaceflinger/main_surfaceflinger.cpp
@@ -35,6 +35,13 @@
using namespace android;
static status_t startGraphicsAllocatorService() {
+ using android::hardware::configstore::getBool;
+ using android::hardware::configstore::V1_0::ISurfaceFlingerConfigs;
+ if (!getBool<ISurfaceFlingerConfigs,
+ &ISurfaceFlingerConfigs::startGraphicsAllocatorService>(false)) {
+ return OK;
+ }
+
using android::hardware::graphics::allocator::V2_0::IAllocator;
status_t result =
@@ -47,27 +54,12 @@ static status_t startGraphicsAllocatorService() {
return OK;
}
-static status_t startHidlServices() {
+static status_t startDisplayService() {
using android::frameworks::displayservice::V1_0::implementation::DisplayService;
using android::frameworks::displayservice::V1_0::IDisplayService;
- using android::hardware::configstore::getBool;
- using android::hardware::configstore::getBool;
- using android::hardware::configstore::V1_0::ISurfaceFlingerConfigs;
- hardware::configureRpcThreadpool(1 /* maxThreads */,
- false /* callerWillJoin */);
-
- status_t err;
-
- if (getBool<ISurfaceFlingerConfigs,
- &ISurfaceFlingerConfigs::startGraphicsAllocatorService>(false)) {
- err = startGraphicsAllocatorService();
- if (err != OK) {
- return err;
- }
- }
sp<IDisplayService> displayservice = new DisplayService();
- err = displayservice->registerAsService();
+ status_t err = displayservice->registerAsService();
if (err != OK) {
ALOGE("Could not register IDisplayService service.");
@@ -77,9 +69,13 @@ static status_t startHidlServices() {
}
int main(int, char**) {
- startHidlServices();
-
signal(SIGPIPE, SIG_IGN);
+
+ hardware::configureRpcThreadpool(1 /* maxThreads */,
+ false /* callerWillJoin */);
+
+ startGraphicsAllocatorService();
+
// When SF is launched in its own process, limit the number of
// binder threads to 4.
ProcessState::self()->setThreadPoolMaxThreadCount(4);
@@ -112,6 +108,8 @@ int main(int, char**) {
sp<GpuService> gpuservice = new GpuService();
sm->addService(String16(GpuService::SERVICE_NAME), gpuservice, false);
+ startDisplayService(); // dependency on SF getting registered above
+
struct sched_param param = {0};
param.sched_priority = 2;
if (sched_setscheduler(0, SCHED_FIFO, &param) != 0) {