CHROMIUM: MALI: fix signaling of already signaled fences

Error code can be only set once, before fence is signaled.
So before setting error code, test if fence is signaled and do
not try to signal fence that has been already signaled.

BUG=chromium:760802
TEST=killall -9 surfaceflinger, no BUG_ON reboot

Change-Id: Ibc5f61381d51af3fa31903e3df43e715dc03e661
Signed-off-by: Dominik Behr <dbehr@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/644410
Commit-Ready: Douglas Anderson <dianders@chromium.org>
Tested-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
(cherry picked from commit 466855709f5ac0afdbe27a8079437974bd314ec8)
Reviewed-on: https://chromium-review.googlesource.com/655997
diff --git a/drivers/gpu/arm/midgard/mali_kbase_sync.c b/drivers/gpu/arm/midgard/mali_kbase_sync.c
index bf1b054..537777b 100644
--- a/drivers/gpu/arm/midgard/mali_kbase_sync.c
+++ b/drivers/gpu/arm/midgard/mali_kbase_sync.c
@@ -221,9 +221,16 @@
 
 void kbase_sync_signal_fence(struct dma_fence *fence, int result)
 {
-	if (result < 0)
-		dma_fence_set_error(fence, result);
-	dma_fence_signal(fence);
+	unsigned long flags;
+
+	spin_lock_irqsave(fence->lock, flags);
+
+	if (dma_fence_get_status_locked(fence) == 0) {
+		if (result < 0)
+			dma_fence_set_error(fence, result);
+		dma_fence_signal_locked(fence);
+	}
+	spin_unlock_irqrestore(fence->lock, flags);
 }
 
 #endif				/* CONFIG_SW_SYNC */