From e9ff4606449c075d464e667410392e23afab7a45 Mon Sep 17 00:00:00 2001 From: Jorim Jaggi Date: Wed, 14 Jun 2017 18:09:58 -0700 Subject: Actually do not hold WM lock while closing transaction Test: go/wm-smoke Test: Quick switch 100x, observe no delay Change-Id: I46022a23f749c52ba7f46e105679d728277970bd Fixes: 62444483 --- .../core/java/com/android/server/wm/WindowAnimator.java | 5 ++++- .../java/com/android/server/wm/WindowManagerService.java | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java index 03b5b827db74..07c29c05095a 100644 --- a/services/core/java/com/android/server/wm/WindowAnimator.java +++ b/services/core/java/com/android/server/wm/WindowAnimator.java @@ -227,7 +227,10 @@ public class WindowAnimator { Slog.wtf(TAG, "Unhandled exception in Window Manager", e); } finally { if (transactionOpen) { - mService.closeSurfaceTransaction(); + + // Do not hold window manager lock while closing the transaction, as this might be + // blocking until the next frame, which can lead to total lock starvation. + mService.closeSurfaceTransaction(false /* withLockHeld */); if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION animate"); } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 768b03a249b8..68818acb6a90 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -891,10 +891,26 @@ public class WindowManagerService extends IWindowManager.Stub } void closeSurfaceTransaction() { + closeSurfaceTransaction(true /* withLockHeld */); + } + + /** + * Closes a surface transaction. + * + * @param withLockHeld Whether to acquire the window manager while doing so. In some cases + * holding the lock my lead to starvation in WM in case closeTransaction + * blocks and we call it repeatedly, like we do for animations. + */ + void closeSurfaceTransaction(boolean withLockHeld) { synchronized (mWindowMap) { if (mRoot.mSurfaceTraceEnabled) { mRoot.mRemoteEventTrace.closeSurfaceTransaction(); } + if (withLockHeld) { + SurfaceControl.closeTransaction(); + } + } + if (!withLockHeld) { SurfaceControl.closeTransaction(); } } -- cgit v1.2.3-59-g8ed1b