Merge "msm: kgsl: Avoid a deadlock with the cmdbatch timer"
diff --git a/drivers/gpu/msm/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c
index 1cc9663..5f80fcf 100644
--- a/drivers/gpu/msm/adreno_dispatch.c
+++ b/drivers/gpu/msm/adreno_dispatch.c
@@ -180,14 +180,15 @@
 			 */
 			if (!timer_pending(&cmdbatch->timer))
 				mod_timer(&cmdbatch->timer, jiffies + (5 * HZ));
+			spin_unlock(&cmdbatch->lock);
 		} else {
 			/*
 			 * Otherwise, delete the timer to make sure it is good
 			 * and dead before queuing the buffer
 			 */
+			spin_unlock(&cmdbatch->lock);
 			del_timer_sync(&cmdbatch->timer);
 		}
-		spin_unlock(&cmdbatch->lock);
 
 		if (pending) {
 			cmdbatch = ERR_PTR(-EAGAIN);
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index d1241e0..543d6d7 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -1492,12 +1492,14 @@
 	if (cmdbatch == NULL || cmdbatch->context == NULL)
 		return;
 
+	spin_lock(&cmdbatch->lock);
+	if (list_empty(&cmdbatch->synclist))
+		goto done;
+
 	pr_err("kgsl: possible gpu syncpoint deadlock for context %d timestamp %d\n",
 		cmdbatch->context->id, cmdbatch->timestamp);
 	pr_err(" Active sync points:\n");
 
-	spin_lock(&cmdbatch->lock);
-
 	/* Print all the pending sync objects */
 	list_for_each_entry(event, &cmdbatch->synclist, node) {
 
@@ -1521,6 +1523,7 @@
 		}
 	}
 
+done:
 	spin_unlock(&cmdbatch->lock);
 }
 
@@ -1596,16 +1599,12 @@
 	}
 
 	sched = list_empty(&event->cmdbatch->synclist) ? 1 : 0;
+	spin_unlock(&event->cmdbatch->lock);
 
-	/*
-	 * If the list is empty delete the canary timer while
-	 * still holding the lock
-	 */
+	/* If the list is empty delete the canary timer */
 	if (sched)
 		del_timer_sync(&event->cmdbatch->timer);
 
-	spin_unlock(&event->cmdbatch->lock);
-
 	/*
 	 * if this is the last event in the list then tell
 	 * the GPU device that the cmdbatch can be submitted
@@ -1648,11 +1647,11 @@
 	struct kgsl_cmdbatch_sync_event *event, *tmp;
 	LIST_HEAD(cancel_synclist);
 
-	spin_lock(&cmdbatch->lock);
-
 	/* Zap the canary timer */
 	del_timer_sync(&cmdbatch->timer);
 
+	spin_lock(&cmdbatch->lock);
+
 	/* Empty the synclist before canceling events */
 	list_splice_init(&cmdbatch->synclist, &cancel_synclist);
 	spin_unlock(&cmdbatch->lock);