diff options
author | Steven Moreland <smoreland@google.com> | 2018-05-25 12:09:51 -0700 |
---|---|---|
committer | Steven Moreland <smoreland@google.com> | 2018-05-25 14:40:51 -0700 |
commit | 9339952bfc64103c1a3c51d1150719d7289995b4 (patch) | |
tree | 62d473a601f19901f399b14d5c0eb718620684a3 | |
parent | c61c0c1193d493f97f3a8657b75c5256a70aea3a (diff) | |
download | native-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.cpp | 36 |
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, ¶m) != 0) { |