hwc: Acquire and Release mDrawlock properly to prevent deadlock
HDMI Online and offline event, UEvent thread acquires mDrawLock and
mStateLock sequentially. At the same time surfaceflinger draw thread
acquires mStateLock and mDrawLock in the reverse sequence which
results in deadlock condition. So release the mDrawLock immediately
after modifying the hwc context variables in UEvent thread.
Change-Id: I6a240294a28d8e9a9aca6f98522c7265b3cad4fa
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index 65e041b..6b2316b 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -107,10 +107,11 @@
break;
}
- Locker::Autolock _l(ctx->mDrawLock);
+ ctx->mDrawLock.lock();
destroyCompositionResources(ctx, dpy);
ctx->mHDMIDisplay->teardown();
resetDisplayInfo(ctx, dpy);
+ ctx->mDrawLock.unlock();
/* We need to send hotplug to SF only when we are disconnecting
* HDMI */
@@ -127,19 +128,19 @@
"for display: %d", __FUNCTION__, dpy);
break;
}
- {
- //Force composition to give up resources like pipes and
- //close fb. For example if assertive display is going on,
- //fb2 could be open, thus connecting Layer Mixer#0 to
- //WriteBack module. If HDMI attempts to open fb1, the driver
- //will try to attach Layer Mixer#0 to HDMI INT, which will
- //fail, since Layer Mixer#0 is still connected to WriteBack.
- //This block will force composition to close fb2 in above
- //example.
- Locker::Autolock _l(ctx->mDrawLock);
- ctx->dpyAttr[dpy].isConfiguring = true;
- ctx->proc->invalidate(ctx->proc);
- }
+ ctx->mDrawLock.lock();
+ //Force composition to give up resources like pipes and
+ //close fb. For example if assertive display is going on,
+ //fb2 could be open, thus connecting Layer Mixer#0 to
+ //WriteBack module. If HDMI attempts to open fb1, the driver
+ //will try to attach Layer Mixer#0 to HDMI INT, which will
+ //fail, since Layer Mixer#0 is still connected to WriteBack.
+ //This block will force composition to close fb2 in above
+ //example.
+ ctx->dpyAttr[dpy].isConfiguring = true;
+ ctx->mDrawLock.unlock();
+
+ ctx->proc->invalidate(ctx->proc);
//2 cycles for slower content
usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
* 2 / 1000);
@@ -166,12 +167,13 @@
ctx->mHDMIDisplay->configure();
ctx->mHDMIDisplay->activateDisplay();
- Locker::Autolock _l(ctx->mDrawLock);
+ ctx->mDrawLock.lock();
updateDisplayInfo(ctx, dpy);
initCompositionResources(ctx, dpy);
ctx->dpyAttr[dpy].isPause = false;
ctx->dpyAttr[dpy].connected = true;
ctx->dpyAttr[dpy].isConfiguring = true;
+ ctx->mDrawLock.unlock();
/* External display is HDMI */
ALOGE_IF(UEVENT_DEBUG, "%s: Sending EXTERNAL ONLINE"